summary refs log tree commit diff stats
path: root/hw/acpi/memory_hotplug_acpi_table.c
diff options
context:
space:
mode:
authorIgor Mammedov <imammedo@redhat.com>2015-12-28 18:02:17 +0100
committerMichael S. Tsirkin <mst@redhat.com>2016-01-09 23:20:17 +0200
commitc943764596fe9d507b926e64381cb0ba3d3aec20 (patch)
tree02f745c2d145760e9d88e064bc8517641cd4d94f /hw/acpi/memory_hotplug_acpi_table.c
parente328e316608d696519d8248319ec323868db5dee (diff)
downloadfocaccia-qemu-c943764596fe9d507b926e64381cb0ba3d3aec20.tar.gz
focaccia-qemu-c943764596fe9d507b926e64381cb0ba3d3aec20.zip
pc: acpi: memhp: move MHPD.MCRS method into SSDT
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/acpi/memory_hotplug_acpi_table.c')
-rw-r--r--hw/acpi/memory_hotplug_acpi_table.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/hw/acpi/memory_hotplug_acpi_table.c b/hw/acpi/memory_hotplug_acpi_table.c
index c2bfcd6b8a..c76a7d82a0 100644
--- a/hw/acpi/memory_hotplug_acpi_table.c
+++ b/hw/acpi/memory_hotplug_acpi_table.c
@@ -124,6 +124,98 @@ void build_memory_hotplug_aml(Aml *ctx, uint32_t nr_mem,
         }
         aml_append(mem_ctrl_dev, method);
 
+        method = aml_method(stringify(MEMORY_SLOT_CRS_METHOD), 1,
+                            AML_SERIALIZED);
+        {
+            Aml *mr64 = aml_name("MR64");
+            Aml *mr32 = aml_name("MR32");
+            Aml *crs_tmpl = aml_resource_template();
+            Aml *minl = aml_name("MINL");
+            Aml *minh = aml_name("MINH");
+            Aml *maxl =  aml_name("MAXL");
+            Aml *maxh =  aml_name("MAXH");
+            Aml *lenl = aml_name("LENL");
+            Aml *lenh = aml_name("LENH");
+
+            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
+            aml_append(method, aml_store(aml_to_integer(slot_arg0),
+                                         slot_selector));
+
+            aml_append(crs_tmpl,
+                aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
+                                 AML_CACHEABLE, AML_READ_WRITE,
+                                 0, 0x0, 0xFFFFFFFFFFFFFFFEULL, 0,
+                                 0xFFFFFFFFFFFFFFFFULL));
+            aml_append(method, aml_name_decl("MR64", crs_tmpl));
+            aml_append(method,
+                aml_create_dword_field(mr64, aml_int(14), "MINL"));
+            aml_append(method,
+                aml_create_dword_field(mr64, aml_int(18), "MINH"));
+            aml_append(method,
+                aml_create_dword_field(mr64, aml_int(38), "LENL"));
+            aml_append(method,
+                aml_create_dword_field(mr64, aml_int(42), "LENH"));
+            aml_append(method,
+                aml_create_dword_field(mr64, aml_int(22), "MAXL"));
+            aml_append(method,
+                aml_create_dword_field(mr64, aml_int(26), "MAXH"));
+
+            aml_append(method,
+                aml_store(aml_name(stringify(MEMORY_SLOT_ADDR_HIGH)), minh));
+            aml_append(method,
+                aml_store(aml_name(stringify(MEMORY_SLOT_ADDR_LOW)), minl));
+            aml_append(method,
+                aml_store(aml_name(stringify(MEMORY_SLOT_SIZE_HIGH)), lenh));
+            aml_append(method,
+                aml_store(aml_name(stringify(MEMORY_SLOT_SIZE_LOW)), lenl));
+
+            /* 64-bit math: MAX = MIN + LEN - 1 */
+            aml_append(method, aml_add(minl, lenl, maxl));
+            aml_append(method, aml_add(minh, lenh, maxh));
+            ifctx = aml_if(aml_lless(maxl, minl));
+            {
+                aml_append(ifctx, aml_add(maxh, one, maxh));
+            }
+            aml_append(method, ifctx);
+            ifctx = aml_if(aml_lless(maxl, one));
+            {
+                aml_append(ifctx, aml_subtract(maxh, one, maxh));
+            }
+            aml_append(method, ifctx);
+            aml_append(method, aml_subtract(maxl, one, maxl));
+
+            /* return 32-bit _CRS if addr/size is in low mem */
+            /* TODO: remove it since all hotplugged DIMMs are in high mem */
+            ifctx = aml_if(aml_equal(maxh, zero));
+            {
+                crs_tmpl = aml_resource_template();
+                aml_append(crs_tmpl,
+                    aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED,
+                                     AML_MAX_FIXED, AML_CACHEABLE,
+                                     AML_READ_WRITE,
+                                     0, 0x0, 0xFFFFFFFE, 0,
+                                     0xFFFFFFFF));
+                aml_append(ifctx, aml_name_decl("MR32", crs_tmpl));
+                aml_append(ifctx,
+                    aml_create_dword_field(mr32, aml_int(10), "MIN"));
+                aml_append(ifctx,
+                    aml_create_dword_field(mr32, aml_int(14), "MAX"));
+                aml_append(ifctx,
+                    aml_create_dword_field(mr32, aml_int(22), "LEN"));
+                aml_append(ifctx, aml_store(minl, aml_name("MIN")));
+                aml_append(ifctx, aml_store(maxl, aml_name("MAX")));
+                aml_append(ifctx, aml_store(lenl, aml_name("LEN")));
+
+                aml_append(ifctx, aml_release(ctrl_lock));
+                aml_append(ifctx, aml_return(mr32));
+            }
+            aml_append(method, ifctx);
+
+            aml_append(method, aml_release(ctrl_lock));
+            aml_append(method, aml_return(mr64));
+        }
+        aml_append(mem_ctrl_dev, method);
+
         method = aml_method(stringify(MEMORY_SLOT_PROXIMITY_METHOD), 1,
                             AML_NOTSERIALIZED);
         {