From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Michael S. Tsirkin" Subject: [PATCH 3/4] acpi: EJ0 method name patching Date: Wed, 21 Sep 2011 15:44:37 +0300 Message-ID: <2a33cd639ef190a0eaa924c03332433e3f0aa493.1316608551.git.mst@redhat.com> References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: "Kevin O'Connor" , seabios@seabios.org, Gleb Natapov , kvm@vger.kernel.org, jasowang@redhat.com, alex williamson , Marcelo Tosatti To: Amos Kong Return-path: Received: from mx1.redhat.com ([209.132.183.28]:1025 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753742Ab1IUMnk (ORCPT ); Wed, 21 Sep 2011 08:43:40 -0400 Content-Disposition: inline In-Reply-To: Sender: kvm-owner@vger.kernel.org List-ID: 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 --- 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