diff options
-rw-r--r-- | hw/acpi/cpu_hotplug_acpi_table.c | 64 | ||||
-rw-r--r-- | hw/i386/acpi-build.c | 2 | ||||
-rw-r--r-- | hw/i386/acpi-dsdt-cpu-hotplug.dsl | 39 | ||||
-rw-r--r-- | hw/i386/acpi-dsdt.dsl | 2 | ||||
-rw-r--r-- | hw/i386/q35-acpi-dsdt.dsl | 2 | ||||
-rw-r--r-- | include/hw/acpi/aml-build.h | 2 | ||||
-rw-r--r-- | include/hw/acpi/cpu_hotplug.h | 1 | ||||
-rw-r--r-- | include/hw/acpi/pc-hotplug.h | 1 |
8 files changed, 71 insertions, 42 deletions
diff --git a/hw/acpi/cpu_hotplug_acpi_table.c b/hw/acpi/cpu_hotplug_acpi_table.c index 90c4043f4d..8dda4f423f 100644 --- a/hw/acpi/cpu_hotplug_acpi_table.c +++ b/hw/acpi/cpu_hotplug_acpi_table.c @@ -26,6 +26,8 @@ void build_cpu_hotplug_aml(Aml *ctx) Aml *cpu_on = aml_local(0); Aml *madt = aml_local(1); Aml *cpus_map = aml_name(CPU_ON_BITMAP); + Aml *zero = aml_int(0); + Aml *one = aml_int(1); /* * _MAT method - creates an madt apic buffer @@ -60,7 +62,7 @@ void build_cpu_hotplug_aml(Aml *ctx) aml_append(method, if_ctx); else_ctx = aml_else(); { - aml_append(else_ctx, aml_return(aml_int(0x0))); + aml_append(else_ctx, aml_return(zero)); } aml_append(method, else_ctx); aml_append(sb_scope, method); @@ -69,5 +71,65 @@ void build_cpu_hotplug_aml(Aml *ctx) aml_append(method, aml_sleep(200)); aml_append(sb_scope, method); + method = aml_method(stringify(CPU_SCAN_METHOD), 0, AML_NOTSERIALIZED); + { + Aml *while_ctx, *if_ctx2, *else_ctx2; + Aml *bus_check_evt = aml_int(1); + Aml *remove_evt = aml_int(3); + Aml *status_map = aml_local(5); /* Local5 = active cpu bitmap */ + Aml *byte = aml_local(2); /* Local2 = last read byte from bitmap */ + Aml *idx = aml_local(0); /* Processor ID / APIC ID iterator */ + Aml *is_cpu_on = aml_local(1); /* Local1 = CPON flag for cpu */ + Aml *status = aml_local(3); /* Local3 = active state for cpu */ + + aml_append(method, aml_store(aml_name(CPU_STATUS_MAP), status_map)); + aml_append(method, aml_store(zero, byte)); + aml_append(method, aml_store(zero, idx)); + + /* While (idx < SizeOf(CPON)) */ + while_ctx = aml_while(aml_lless(idx, aml_sizeof(cpus_map))); + aml_append(while_ctx, + aml_store(aml_derefof(aml_index(cpus_map, idx)), is_cpu_on)); + + if_ctx = aml_if(aml_and(idx, aml_int(0x07), NULL)); + { + /* Shift down previously read bitmap byte */ + aml_append(if_ctx, aml_shiftright(byte, one, byte)); + } + aml_append(while_ctx, if_ctx); + + else_ctx = aml_else(); + { + /* Read next byte from cpu bitmap */ + aml_append(else_ctx, aml_store(aml_derefof(aml_index(status_map, + aml_shiftright(idx, aml_int(3), NULL))), byte)); + } + aml_append(while_ctx, else_ctx); + + aml_append(while_ctx, aml_store(aml_and(byte, one, NULL), status)); + if_ctx = aml_if(aml_lnot(aml_equal(is_cpu_on, status))); + { + /* State change - update CPON with new state */ + aml_append(if_ctx, aml_store(status, aml_index(cpus_map, idx))); + if_ctx2 = aml_if(aml_equal(status, one)); + { + aml_append(if_ctx2, + aml_call2(AML_NOTIFY_METHOD, idx, bus_check_evt)); + } + aml_append(if_ctx, if_ctx2); + else_ctx2 = aml_else(); + { + aml_append(else_ctx2, + aml_call2(AML_NOTIFY_METHOD, idx, remove_evt)); + } + } + aml_append(if_ctx, else_ctx2); + aml_append(while_ctx, if_ctx); + + aml_append(while_ctx, aml_increment(idx)); /* go to next cpu */ + aml_append(method, while_ctx); + } + aml_append(sb_scope, method); + aml_append(ctx, sb_scope); } diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 69b7160189..6c5d09a26d 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1340,7 +1340,7 @@ build_ssdt(GArray *table_data, GArray *linker, * Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...} */ /* Arg0 = Processor ID = APIC ID */ - method = aml_method("NTFY", 2, AML_NOTSERIALIZED); + method = aml_method(AML_NOTIFY_METHOD, 2, AML_NOTSERIALIZED); for (i = 0; i < acpi_cpus; i++) { ifctx = aml_if(aml_equal(aml_arg(0), aml_int(i))); aml_append(ifctx, diff --git a/hw/i386/acpi-dsdt-cpu-hotplug.dsl b/hw/i386/acpi-dsdt-cpu-hotplug.dsl index fb75edaefe..88c472b8ce 100644 --- a/hw/i386/acpi-dsdt-cpu-hotplug.dsl +++ b/hw/i386/acpi-dsdt-cpu-hotplug.dsl @@ -19,42 +19,5 @@ Scope(\_SB) { /* Objects filled in by run-time generated SSDT */ - External(NTFY, MethodObj) - External(CPON, PkgObj) - External(PRS, FieldUnitObj) - - /* Methods called by run-time generated SSDT Processor objects */ - Method(PRSC, 0) { - // Local5 = active cpu bitmap - Store(PRS, Local5) - // Local2 = last read byte from bitmap - Store(Zero, Local2) - // Local0 = Processor ID / APIC ID iterator - Store(Zero, Local0) - While (LLess(Local0, SizeOf(CPON))) { - // Local1 = CPON flag for this cpu - Store(DerefOf(Index(CPON, Local0)), Local1) - If (And(Local0, 0x07)) { - // Shift down previously read bitmap byte - ShiftRight(Local2, 1, Local2) - } Else { - // Read next byte from cpu bitmap - Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), Local2) - } - // Local3 = active state for this cpu - Store(And(Local2, 1), Local3) - - If (LNotEqual(Local1, Local3)) { - // State change - update CPON with new state - Store(Local3, Index(CPON, Local0)) - // Do CPU notify - If (LEqual(Local3, 1)) { - NTFY(Local0, 1) - } Else { - NTFY(Local0, 3) - } - } - Increment(Local0) - } - } + External(CPU_SCAN_METHOD, MethodObj) } diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl index 9cf1b88528..6a0c656b1d 100644 --- a/hw/i386/acpi-dsdt.dsl +++ b/hw/i386/acpi-dsdt.dsl @@ -268,7 +268,7 @@ DefinitionBlock ( } Method(_E02) { // CPU hotplug event - \_SB.PRSC() + \_SB.CPU_SCAN_METHOD() } Method(_L04) { } diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl index f950f39f2d..7211665a50 100644 --- a/hw/i386/q35-acpi-dsdt.dsl +++ b/hw/i386/q35-acpi-dsdt.dsl @@ -401,7 +401,7 @@ DefinitionBlock ( } Method(_E02) { // CPU hotplug event - \_SB.PRSC() + \_SB.CPU_SCAN_METHOD() } Method(_L04) { } diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index ef44d02285..83c0102f84 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -16,6 +16,8 @@ #define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp" #define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log" +#define AML_NOTIFY_METHOD "NTFY" + typedef enum { AML_NO_OPCODE = 0,/* has only data */ AML_OPCODE, /* has opcode optionally followed by data */ diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h index 0755dd3347..255e70c2b7 100644 --- a/include/hw/acpi/cpu_hotplug.h +++ b/include/hw/acpi/cpu_hotplug.h @@ -31,6 +31,7 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner, #define CPU_MAT_METHOD "CPMA" #define CPU_ON_BITMAP "CPON" #define CPU_STATUS_METHOD "CPST" +#define CPU_STATUS_MAP "PRS" void build_cpu_hotplug_aml(Aml *ctx); #endif diff --git a/include/hw/acpi/pc-hotplug.h b/include/hw/acpi/pc-hotplug.h index 6a8d268f84..6522745c22 100644 --- a/include/hw/acpi/pc-hotplug.h +++ b/include/hw/acpi/pc-hotplug.h @@ -28,6 +28,7 @@ #define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8 #define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00 #define CPU_HOTPLUG_RESOURCE_DEVICE PRES +#define CPU_SCAN_METHOD PRSC #define ACPI_MEMORY_HOTPLUG_IO_LEN 24 #define ACPI_MEMORY_HOTPLUG_BASE 0x0a00 |