[PATCH 3/4] acpi: EJ0 method name patching

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Modify ACPI to only supply _EJ0 methods for PCI
slots that support hotplug.

This is done by runtime patching:
- Rename _EJ0 methods for PCI slots in DSDT to EJ0_:
  note that this has the same checksum, but
  is ignored by OSPM.
- At compile time, look for these methods in ASL source,
  find the matching AML,  and store the offsets of these methods
  in a table named aml_ej0_data.
  Note that we are looking for EJ0_ in source code,
  so we'll be able to write EJ0 if we want to and the script
  will not match it.
- At run time, go over aml_ej0_data, check which slots
  support hotplug and patch the ACPI table, replacing EJ0_ with _EJ0.

Note: the method used is robust in that we don't need
to change any offsets manually in case of ASL code changes.
As all parsing is done at compile time, any unexpected input causes
build failure, not a runtime failure.

Signed-off-by: Michael S. Tsirkin <mst@xxxxxxxxxx>
---
 Makefile          |    3 ++-
 src/acpi-dsdt.dsl |    9 +++++++--
 src/acpi.c        |   11 +++++++++++
 3 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 5c011bb..dee93d6 100644
--- a/Makefile
+++ b/Makefile
@@ -197,7 +197,8 @@ src/%.hex: src/%.dsl src/splitdsl.pl src/find_ej0.pl
 	$(Q)cpp -P $< > $(OUT)$*.dsl.i.orig
 	$(Q)./src/splitdsl.pl $(OUT)$*.dsl.i.orig > $(OUT)$*.dsl.i
 	$(Q)iasl -l -tc -p $(OUT)$* $(OUT)$*.dsl.i
-	$(Q)cp $(OUT)$*.hex $@
+	$(Q)./src/find_ej0.pl $(OUT)$*.lst > $(OUT)$*.off
+	$(Q)cat $(OUT)$*.hex $(OUT)$*.off > $@
 
 $(OUT)ccode32flat.o: src/acpi-dsdt.hex
 
diff --git a/src/acpi-dsdt.dsl b/src/acpi-dsdt.dsl
index 08412e2..3d43e4b 100644
--- a/src/acpi-dsdt.dsl
+++ b/src/acpi-dsdt.dsl
@@ -127,11 +127,16 @@ DefinitionBlock (
             {
                 PCRM, 32,
             }
-
+            // Method EJ0_ will be patched by BIOS to _EJ0
+            // at runtime, if the slot is detected to support hotplug.
+            // Must be immediately preceded by _ADR for this to work.
+            // EJ0_ is not allowed anywhere else in this file,
+            // if you really want to use it, write EJ0 which
+            // creates the same AML but isn't patched.
 #define hotplug_slot(name, nr) \
             Device (S##name) {                    \
                Name (_ADR, nr##0000)              \
-               Method (_EJ0,1) {                  \
+               Method (EJ0_,1) {                  \
                     Store(ShiftLeft(1, nr), B0EJ) \
                     Return (0x0)                  \
                }                                  \
diff --git a/src/acpi.c b/src/acpi.c
index 6bb6ff6..cbb5143 100644
--- a/src/acpi.c
+++ b/src/acpi.c
@@ -198,6 +198,8 @@ struct srat_memory_affinity
     u32    reserved3[2];
 } PACKED;
 
+#define PCI_RMV_BASE 0xae0c
+
 #include "acpi-dsdt.hex"
 
 static void
@@ -243,6 +245,8 @@ build_fadt(struct pci_device *pci)
     struct fadt_descriptor_rev1 *fadt = malloc_high(sizeof(*fadt));
     struct facs_descriptor_rev1 *facs = memalign_high(64, sizeof(*facs));
     void *dsdt = malloc_high(sizeof(AmlCode));
+    u32 rmvc_pcrm;
+    int i;
 
     if (!fadt || !facs || !dsdt) {
         warn_noalloc();
@@ -255,7 +259,13 @@ build_fadt(struct pci_device *pci)
     facs->length = cpu_to_le32(sizeof(*facs));
 
     /* DSDT */
     memcpy(dsdt, AmlCode, sizeof(AmlCode));
+    rmvc_pcrm = inl(PCI_RMV_BASE);
+    for (i = 0; i < sizeof(aml_ej0_data) / sizeof(*aml_ej0_data); ++i) {
+        if (rmvc_pcrm & aml_ej0_data[i].slot_mask) {
+            memcpy(dsdt + aml_ej0_data[i].offset, "_EJ0", 4);
+        }
+    }
 
     /* FADT */
     memset(fadt, 0, sizeof(*fadt));
-- 
1.7.5.53.gc233e

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux