We already build the CPU notification method in src/acpi.c, and we can reuse most of the code for PCI hotplug.
Signed-off-by: Paolo Bonzini pbonzini@redhat.com --- src/acpi.c | 68 +++++++++++++++++++++++++++++++++++----------------- src/ssdt-pcihp.dsl | 37 ---------------------------- 2 files changed, 46 insertions(+), 59 deletions(-)
diff --git a/src/acpi.c b/src/acpi.c index 7d22d22..38b72fb 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -406,11 +406,43 @@ encodeLen(u8 *ssdt_ptr, int length, int bytes) #define PROC_SIZEOF (*ssdt_proc_end - *ssdt_proc_start) #define PROC_AML (ssdp_proc_aml + *ssdt_proc_start)
+#define PCI_SLOTS 32 + #define SSDT_SIGNATURE 0x54445353 // SSDT #define SSDT_HEADER_LENGTH 36
#include "ssdt-susp.hex"
+static u8* +build_notify(u8 *ssdt_ptr, const char *name, int skip, int count, + const char *target, int ofs) +{ + count -= skip; + + *(ssdt_ptr++) = 0x14; // MethodOp + ssdt_ptr = encodeLen(ssdt_ptr, 2+5+(12*count), 2); + memcpy(ssdt_ptr, name, 4); + ssdt_ptr += 4; + *(ssdt_ptr++) = 0x02; // MethodOp + + int i; + for (i = skip; count-- > 0; i++) { + *(ssdt_ptr++) = 0xA0; // IfOp + ssdt_ptr = encodeLen(ssdt_ptr, 11, 1); + *(ssdt_ptr++) = 0x93; // LEqualOp + *(ssdt_ptr++) = 0x68; // Arg0Op + *(ssdt_ptr++) = 0x0A; // BytePrefix + *(ssdt_ptr++) = i; + *(ssdt_ptr++) = 0x86; // NotifyOp + memcpy(ssdt_ptr, target, 4); + ssdt_ptr[ofs] = getHex(i >> 4); + ssdt_ptr[ofs + 1] = getHex(i); + ssdt_ptr += 4; + *(ssdt_ptr++) = 0x69; // Arg1Op + } + return ssdt_ptr; +} + static void* build_ssdt(void) { @@ -420,7 +452,9 @@ build_ssdt(void) + (acpi_cpus * PROC_SIZEOF) // procs + (1+2+5+(12*acpi_cpus)) // NTFY + (6+2+1+(1*acpi_cpus)) // CPON - + 17); // BDAT + + 17 // BDAT + + (1+3+4) // Scope(PCI0) + + (1+2+5+(12*(PCI_SLOTS - 1)))); // PCNT u8 *ssdt = malloc_high(length); if (! ssdt) { warn_noalloc(); @@ -464,27 +498,7 @@ build_ssdt(void)
// build "Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}" // Arg0 = Processor ID = APIC ID - *(ssdt_ptr++) = 0x14; // MethodOp - ssdt_ptr = encodeLen(ssdt_ptr, 2+5+(12*acpi_cpus), 2); - *(ssdt_ptr++) = 'N'; - *(ssdt_ptr++) = 'T'; - *(ssdt_ptr++) = 'F'; - *(ssdt_ptr++) = 'Y'; - *(ssdt_ptr++) = 0x02; - for (i=0; i<acpi_cpus; i++) { - *(ssdt_ptr++) = 0xA0; // IfOp - ssdt_ptr = encodeLen(ssdt_ptr, 11, 1); - *(ssdt_ptr++) = 0x93; // LEqualOp - *(ssdt_ptr++) = 0x68; // Arg0Op - *(ssdt_ptr++) = 0x0A; // BytePrefix - *(ssdt_ptr++) = i; - *(ssdt_ptr++) = 0x86; // NotifyOp - *(ssdt_ptr++) = 'C'; - *(ssdt_ptr++) = 'P'; - *(ssdt_ptr++) = getHex(i >> 4); - *(ssdt_ptr++) = getHex(i); - *(ssdt_ptr++) = 0x69; // Arg1Op - } + ssdt_ptr = build_notify(ssdt_ptr, "NTFY", 0, acpi_cpus, "CP00", 2);
// build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" *(ssdt_ptr++) = 0x08; // NameOp @@ -523,6 +537,16 @@ build_ssdt(void) *(u32*)ssdt_ptr = sizeof(struct bfld); ssdt_ptr += 4;
+ // build Scope(PCI0) opcode + *(ssdt_ptr++) = 0x10; // ScopeOp + ssdt_ptr = encodeLen(ssdt_ptr, length - (ssdt_ptr - ssdt), 3); + *(ssdt_ptr++) = 'P'; + *(ssdt_ptr++) = 'C'; + *(ssdt_ptr++) = 'I'; + *(ssdt_ptr++) = '0'; + + ssdt_ptr = build_notify(ssdt_ptr, "PCNT", 1, PCI_SLOTS, "S00_", 1); + build_header((void*)ssdt, SSDT_SIGNATURE, ssdt_ptr - ssdt, 1);
//hexdump(ssdt, ssdt_ptr - ssdt); diff --git a/src/ssdt-pcihp.dsl b/src/ssdt-pcihp.dsl index 4b435b8..fd9c0bb 100644 --- a/src/ssdt-pcihp.dsl +++ b/src/ssdt-pcihp.dsl @@ -57,42 +57,5 @@ DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", "BXSSDTPCIHP", 0x1) hotplug_slot(1d) hotplug_slot(1e) hotplug_slot(1f) - -#define gen_pci_hotplug(slot) \ - If (LEqual(Arg0, 0x##slot)) { Notify(S##slot, Arg1) } - - Method(PCNT, 2) { - gen_pci_hotplug(01) - gen_pci_hotplug(02) - gen_pci_hotplug(03) - gen_pci_hotplug(04) - gen_pci_hotplug(05) - gen_pci_hotplug(06) - gen_pci_hotplug(07) - gen_pci_hotplug(08) - gen_pci_hotplug(09) - gen_pci_hotplug(0a) - gen_pci_hotplug(0b) - gen_pci_hotplug(0c) - gen_pci_hotplug(0d) - gen_pci_hotplug(0e) - gen_pci_hotplug(0f) - gen_pci_hotplug(10) - gen_pci_hotplug(11) - gen_pci_hotplug(12) - gen_pci_hotplug(13) - gen_pci_hotplug(14) - gen_pci_hotplug(15) - gen_pci_hotplug(16) - gen_pci_hotplug(17) - gen_pci_hotplug(18) - gen_pci_hotplug(19) - gen_pci_hotplug(1a) - gen_pci_hotplug(1b) - gen_pci_hotplug(1c) - gen_pci_hotplug(1d) - gen_pci_hotplug(1e) - gen_pci_hotplug(1f) - } } }