mirror of https://gitee.com/openkylin/qemu.git
pc: acpi-build: create memory hotplug IO region dynamically
it replaces a static complied in DSDT MMIO region for memory hotplug with one created at runtime leaving only truly static memory hotplug related ASL bits in DSDT. And replaces template patching of MEMORY_SLOTS_NUMBER value with ASL API created named value. Later it also would make easier to reuse current ACPI memory hotplug on other targets. Also later it would be possible to move remaining memory hotplug ASL methods into build_ssdt() and add all memory hotplug related AML into SSDT only when memory hotplug is enabled, further reducing ACPI tables blob if memory hotplug isn't used. 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>
This commit is contained in:
parent
8698c0c0ed
commit
2c6b94d84e
|
@ -103,6 +103,8 @@ typedef struct AcpiPmInfo {
|
|||
uint32_t io_base;
|
||||
uint16_t cpu_hp_io_base;
|
||||
uint16_t cpu_hp_io_len;
|
||||
uint16_t mem_hp_io_base;
|
||||
uint16_t mem_hp_io_len;
|
||||
} AcpiPmInfo;
|
||||
|
||||
typedef struct AcpiMiscInfo {
|
||||
|
@ -187,6 +189,9 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
|
|||
assert(obj);
|
||||
|
||||
pm->cpu_hp_io_len = ACPI_GPE_PROC_LEN;
|
||||
pm->mem_hp_io_base = ACPI_MEMORY_HOTPLUG_BASE;
|
||||
pm->mem_hp_io_len = ACPI_MEMORY_HOTPLUG_IO_LEN;
|
||||
|
||||
/* Fill in optional s3/s4 related properties */
|
||||
o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL);
|
||||
if (o) {
|
||||
|
@ -887,9 +892,6 @@ build_ssdt(GArray *table_data, GArray *linker,
|
|||
|
||||
patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml));
|
||||
|
||||
ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml),
|
||||
ssdt_mctrl_nr_slots[0], 32, nr_mem);
|
||||
|
||||
/* create S3_ / S4_ / S5_ packages if necessary */
|
||||
scope = aml_scope("\\");
|
||||
if (!pm->s3_disabled) {
|
||||
|
@ -1027,6 +1029,55 @@ build_ssdt(GArray *table_data, GArray *linker,
|
|||
|
||||
/* build memory devices */
|
||||
assert(nr_mem <= ACPI_MAX_RAM_SLOTS);
|
||||
scope = aml_scope("\\_SB.PCI0." stringify(MEMORY_HOTPLUG_DEVICE));
|
||||
aml_append(scope,
|
||||
aml_name_decl(stringify(MEMORY_SLOTS_NUMBER), aml_int(nr_mem))
|
||||
);
|
||||
|
||||
crs = aml_resource_template();
|
||||
aml_append(crs,
|
||||
aml_io(aml_decode16, pm->mem_hp_io_base, pm->mem_hp_io_base, 0,
|
||||
pm->mem_hp_io_len)
|
||||
);
|
||||
aml_append(scope, aml_name_decl("_CRS", crs));
|
||||
|
||||
aml_append(scope, aml_operation_region(
|
||||
stringify(MEMORY_HOTPLUG_IO_REGION), aml_system_io,
|
||||
pm->mem_hp_io_base, pm->mem_hp_io_len)
|
||||
);
|
||||
|
||||
field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), aml_dword_acc);
|
||||
aml_append(field, /* read only */
|
||||
aml_named_field(stringify(MEMORY_SLOT_ADDR_LOW), 32));
|
||||
aml_append(field, /* read only */
|
||||
aml_named_field(stringify(MEMORY_SLOT_ADDR_HIGH), 32));
|
||||
aml_append(field, /* read only */
|
||||
aml_named_field(stringify(MEMORY_SLOT_SIZE_LOW), 32));
|
||||
aml_append(field, /* read only */
|
||||
aml_named_field(stringify(MEMORY_SLOT_SIZE_HIGH), 32));
|
||||
aml_append(field, /* read only */
|
||||
aml_named_field(stringify(MEMORY_SLOT_PROXIMITY), 32));
|
||||
aml_append(scope, field);
|
||||
|
||||
field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), aml_byte_acc);
|
||||
aml_append(field, aml_reserved_field(160 /* bits, Offset(20) */));
|
||||
aml_append(field, /* 1 if enabled, read only */
|
||||
aml_named_field(stringify(MEMORY_SLOT_ENABLED), 1));
|
||||
aml_append(field,
|
||||
/*(read) 1 if has a insert event. (write) 1 to clear event */
|
||||
aml_named_field(stringify(MEMORY_SLOT_INSERT_EVENT), 1));
|
||||
aml_append(scope, field);
|
||||
|
||||
field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), aml_dword_acc);
|
||||
aml_append(field, /* DIMM selector, write only */
|
||||
aml_named_field(stringify(MEMORY_SLOT_SLECTOR), 32));
|
||||
aml_append(field, /* _OST event code, write only */
|
||||
aml_named_field(stringify(MEMORY_SLOT_OST_EVENT), 32));
|
||||
aml_append(field, /* _OST status code, write only */
|
||||
aml_named_field(stringify(MEMORY_SLOT_OST_STATUS), 32));
|
||||
aml_append(scope, field);
|
||||
|
||||
aml_append(sb_scope, scope);
|
||||
|
||||
for (i = 0; i < nr_mem; i++) {
|
||||
#define BASEPATH "\\_SB.PCI0." stringify(MEMORY_HOTPLUG_DEVICE) "."
|
||||
|
|
|
@ -22,14 +22,16 @@
|
|||
External(MEMORY_SLOTS_NUMBER, IntObj)
|
||||
|
||||
/* Memory hotplug IO registers */
|
||||
OperationRegion(MEMORY_HOTPLUG_IO_REGION, SystemIO,
|
||||
ACPI_MEMORY_HOTPLUG_BASE,
|
||||
ACPI_MEMORY_HOTPLUG_IO_LEN)
|
||||
|
||||
Name(_CRS, ResourceTemplate() {
|
||||
IO(Decode16, ACPI_MEMORY_HOTPLUG_BASE, ACPI_MEMORY_HOTPLUG_BASE,
|
||||
0, ACPI_MEMORY_HOTPLUG_IO_LEN, IO)
|
||||
})
|
||||
External(MEMORY_SLOT_ADDR_LOW, FieldUnitObj) // read only
|
||||
External(MEMORY_SLOT_ADDR_HIGH, FieldUnitObj) // read only
|
||||
External(MEMORY_SLOT_SIZE_LOW, FieldUnitObj) // read only
|
||||
External(MEMORY_SLOT_SIZE_HIGH, FieldUnitObj) // read only
|
||||
External(MEMORY_SLOT_PROXIMITY, FieldUnitObj) // read only
|
||||
External(MEMORY_SLOT_ENABLED, FieldUnitObj) // 1 if enabled, read only
|
||||
External(MEMORY_SLOT_INSERT_EVENT, FieldUnitObj) // (read) 1 if has a insert event. (write) 1 to clear event
|
||||
External(MEMORY_SLOT_SLECTOR, FieldUnitObj) // DIMM selector, write only
|
||||
External(MEMORY_SLOT_OST_EVENT, FieldUnitObj) // _OST event code, write only
|
||||
External(MEMORY_SLOT_OST_STATUS, FieldUnitObj) // _OST status code, write only
|
||||
|
||||
Method(_STA, 0) {
|
||||
If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
|
||||
|
@ -39,25 +41,7 @@
|
|||
Return(0xB)
|
||||
}
|
||||
|
||||
Field(MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
|
||||
MEMORY_SLOT_ADDR_LOW, 32, // read only
|
||||
MEMORY_SLOT_ADDR_HIGH, 32, // read only
|
||||
MEMORY_SLOT_SIZE_LOW, 32, // read only
|
||||
MEMORY_SLOT_SIZE_HIGH, 32, // read only
|
||||
MEMORY_SLOT_PROXIMITY, 32, // read only
|
||||
}
|
||||
Field(MEMORY_HOTPLUG_IO_REGION, ByteAcc, NoLock, Preserve) {
|
||||
Offset(20),
|
||||
MEMORY_SLOT_ENABLED, 1, // 1 if enabled, read only
|
||||
MEMORY_SLOT_INSERT_EVENT, 1, // (read) 1 if has a insert event. (write) 1 to clear event
|
||||
}
|
||||
|
||||
Mutex (MEMORY_SLOT_LOCK, 0)
|
||||
Field (MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
|
||||
MEMORY_SLOT_SLECTOR, 32, // DIMM selector, write only
|
||||
MEMORY_SLOT_OST_EVENT, 32, // _OST event code, write only
|
||||
MEMORY_SLOT_OST_STATUS, 32, // _OST status code, write only
|
||||
}
|
||||
|
||||
Method(MEMORY_SLOT_SCAN_METHOD, 0) {
|
||||
If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
|
||||
|
|
|
@ -36,7 +36,5 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
|
|||
Name(P1E, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
|
||||
ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_length
|
||||
Name(P1L, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
|
||||
ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
|
||||
Name(MEMORY_SLOTS_NUMBER, 0x12345678)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue