Anthony PERARD
2011-Oct-27 15:12 UTC
[Xen-devel] [PATCH 0/5] hvmloader/DSDT change to handle PCI hotplug with QEMU upstream
This patch series introduces some change in the DSDT ACPI table generated to handle the PCI hotplug in qemu-xen. There is now options to ./mk_dsdt, instead of compiling it for each DSDT table we want. There is more to read in the 4th patch about want is not supported with the new QEMU. Anthony PERARD (5): hvmloader/acpi: Introduce --maxcpu option to mk_dsdt hvmloader/acpi/dsdt: Move IO port range reservation hvmloader: In mk_dsdt, Use __attribute__ format. hvmloader/acpi/dsdt: Fix PCI hotplug with the new qemu-xen. hvmloader: Load DSDT table from parametter .hgignore | 2 + tools/firmware/hvmloader/acpi/Makefile | 22 ++- tools/firmware/hvmloader/acpi/acpi2_0.h | 9 +- tools/firmware/hvmloader/acpi/build.c | 31 ++--- tools/firmware/hvmloader/acpi/dsdt.asl | 14 -- tools/firmware/hvmloader/acpi/mk_dsdt.c | 226 +++++++++++++++++++++++-------- tools/firmware/hvmloader/rombios.c | 12 ++- tools/firmware/hvmloader/seabios.c | 12 ++- 8 files changed, 228 insertions(+), 100 deletions(-) -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Anthony PERARD
2011-Oct-27 15:12 UTC
[Xen-devel] [PATCH 1/5] hvmloader/acpi: Introduce --maxcpu option to mk_dsdt
With this new option, there is no need to compile mk_dsdt for each DSDT table that we want. The Makefile is a bit reorganize to handle this new option and to prepare more change in a coming patch. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- .hgignore | 2 + tools/firmware/hvmloader/acpi/Makefile | 16 +++++++++----- tools/firmware/hvmloader/acpi/mk_dsdt.c | 34 +++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/.hgignore b/.hgignore index 9d4f864..9c286f4 100644 --- a/.hgignore +++ b/.hgignore @@ -140,7 +140,9 @@ ^tools/firmware/etherboot/ipxe\.git/.*$ ^tools/firmware/extboot/extboot.img$ ^tools/firmware/extboot/signrom$ +^tools/firmware/hvmloader/acpi/mk_dsdt$ ^tools/firmware/hvmloader/acpi/dsdt.*\.c$ +^tools/firmware/hvmloader/acpi/dsdt_.*\.asl$ ^tools/firmware/hvmloader/acpi/ssdt_.*\.h$ ^tools/firmware/hvmloader/hvmloader$ ^tools/firmware/hvmloader/roms\.inc$ diff --git a/tools/firmware/hvmloader/acpi/Makefile b/tools/firmware/hvmloader/acpi/Makefile index d32e055..7746a1c 100644 --- a/tools/firmware/hvmloader/acpi/Makefile +++ b/tools/firmware/hvmloader/acpi/Makefile @@ -31,15 +31,19 @@ ssdt_pm.h ssdt_tpm.h: %.h: %.asl iasl sed -e ''s/AmlCode/$*/g'' $*.hex >$@ rm -f $*.hex $*.aml +mk_dsdt: mk_dsdt.c + $(HOSTCC) $(HOSTCFLAGS) $(CFLAGS_xeninclude) -o $@ mk_dsdt.c + # NB. awk invocation is a portable alternative to ''head -n -1'' -dsdt_15cpu.c dsdt_anycpu.c: %.c: dsdt.asl mk_dsdt.c iasl - $(HOSTCC) $(HOSTCFLAGS) $(CFLAGS_xeninclude) -o mk_$* mk_dsdt.c - awk ''NR > 1 {print s} {s=$$0}'' $< >$*.asl - ./mk_$* >>$*.asl +dsdt_%cpu.asl: dsdt.asl mk_dsdt + awk ''NR > 1 {print s} {s=$$0}'' $< > $@ + ./mk_dsdt --maxcpu $* >> $@ + +$(filter dsdt_%.c,$(C_SRC)): %.c: iasl %.asl iasl -vs -p $* -tc $*.asl sed -e ''s/AmlCode/$*/g'' $*.hex >$@ echo "int $*_len=sizeof($*);" >>$@ - rm -f $*.hex $*.aml $*.asl mk_$* + rm -f $*.aml $*.hex iasl: @echo @@ -56,7 +60,7 @@ acpi.a: $(OBJS) clean: rm -rf *.a *.o $(IASL_VER) $(IASL_VER).tar.gz $(DEPS) - rm -rf ssdt_*.h dsdt*.c *~ *.aml *.hex mk_dsdt mk_dsdt15 dsdt_*cpu.asl + rm -rf ssdt_*.h dsdt*.c *~ *.aml *.hex mk_dsdt dsdt_*.asl install: all diff --git a/tools/firmware/hvmloader/acpi/mk_dsdt.c b/tools/firmware/hvmloader/acpi/mk_dsdt.c index f97da50..ab8a4fb 100644 --- a/tools/firmware/hvmloader/acpi/mk_dsdt.c +++ b/tools/firmware/hvmloader/acpi/mk_dsdt.c @@ -1,6 +1,9 @@ #include <stdio.h> #include <stdarg.h> #include <stdint.h> +#include <string.h> +#include <getopt.h> +#include <stdlib.h> #include <xen/hvm/hvm_info_table.h> static unsigned int indent_level; @@ -71,12 +74,39 @@ static void decision_tree( pop_block(); } +static struct option options[] = { + { "maxcpu", 1, 0, ''c'' }, + { 0, 0, 0, 0 } +}; + int main(int argc, char **argv) { unsigned int slot, dev, intx, link, cpu, max_cpus = HVM_MAX_VCPUS; - /* Extract optional maximum-cpu specification from invocation name. */ - sscanf(argv[0], "%*[^0-9]%u", &max_cpus); /* e.g., ./mk_dsdt15 */ + while (1) { + int opt = getopt_long(argc, argv, "", options, NULL); + if (opt == -1) + break; + + switch (opt) { + case ''c'': { + long i = 0; + char *endptr; + + i = strtol(optarg, &endptr, 10); + if (*optarg != ''\0'' && *endptr == ''\0'' && i >= 0) { + max_cpus = i; + } else if (!(strcmp(optarg, "any") == 0)){ + fprintf(stderr, "`%s'' is not a number or is bellow 0.\n", optarg); + return -1; + } + break; + } + default: + fprintf(stderr, "options not supported.\n"); + return -1; + } + } /**** DSDT DefinitionBlock start ****/ /* (we append to existing DSDT definition block) */ -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Anthony PERARD
2011-Oct-27 15:12 UTC
[Xen-devel] [PATCH 2/5] hvmloader/acpi/dsdt: Move IO port range reservation
This patch move the IO port range reservation from the dsdt.asl to mk_dsdt. This IO port range need to be generated by mk_dsdt, because qemu-xen use different port. The IO port for qemu-xen will be added in a later patch. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- tools/firmware/hvmloader/acpi/dsdt.asl | 14 -------------- tools/firmware/hvmloader/acpi/mk_dsdt.c | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tools/firmware/hvmloader/acpi/dsdt.asl b/tools/firmware/hvmloader/acpi/dsdt.asl index 1bcee86..0549d7b 100644 --- a/tools/firmware/hvmloader/acpi/dsdt.asl +++ b/tools/firmware/hvmloader/acpi/dsdt.asl @@ -100,20 +100,6 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0) Name (_ADR, 0x00) Name (_BBN, 0x00) - /* - * Reserve the IO port ranges [0x10c0, 0x1101] and [0xb044, 0xb047]. - * Or else, for a hotplugged-in device, the port IO BAR assigned - * by guest OS may conflict with the ranges here. - */ - Device(HP0) - { - Name(_HID, EISAID("PNP0C02")) - Name(_CRS, ResourceTemplate() { - IO (Decode16, 0x10c0, 0x10c0, 0x00, 0x82) - IO (Decode16, 0xb044, 0xb044, 0x00, 0x04) - }) - } - /* Make cirrues VGA S3 suspend/resume work in Windows XP/2003 */ Device (VGA) { diff --git a/tools/firmware/hvmloader/acpi/mk_dsdt.c b/tools/firmware/hvmloader/acpi/mk_dsdt.c index ab8a4fb..8cab7ba 100644 --- a/tools/firmware/hvmloader/acpi/mk_dsdt.c +++ b/tools/firmware/hvmloader/acpi/mk_dsdt.c @@ -210,6 +210,20 @@ int main(int argc, char **argv) /**** PCI0 start ****/ push_block("Scope", "\\_SB.PCI0"); + /* + * Reserve the IO port ranges [0x10c0, 0x1101] and [0xb044, 0xb047]. + * Or else, for a hotplugged-in device, the port IO BAR assigned + * by guest OS may conflict with the ranges here. + */ + push_block("Device", "HP0"); { + stmt("Name", "_HID, EISAID(\"PNP0C02\")"); + stmt("Name", "_CRS, ResourceTemplate() {" + " IO (Decode16, 0x10c0, 0x10c0, 0x00, 0x82)" + " IO (Decode16, 0xb044, 0xb044, 0x00, 0x04)" + "}"); + } pop_block(); + + /*** PCI-ISA link definitions ***/ /* BUFA: List of ISA IRQs available for linking to PCI INTx. */ stmt("Name", "BUFA, ResourceTemplate() { " -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Anthony PERARD
2011-Oct-27 15:12 UTC
[Xen-devel] [PATCH 3/5] hvmloader: In mk_dsdt, Use __attribute__ format.
Use __attribute__((format(printf,..))) for the function _stmt to prevent any mistake. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- tools/firmware/hvmloader/acpi/mk_dsdt.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/tools/firmware/hvmloader/acpi/mk_dsdt.c b/tools/firmware/hvmloader/acpi/mk_dsdt.c index 8cab7ba..c80a888 100644 --- a/tools/firmware/hvmloader/acpi/mk_dsdt.c +++ b/tools/firmware/hvmloader/acpi/mk_dsdt.c @@ -15,7 +15,8 @@ static void indent(void) printf(" "); } -static void _stmt(const char *name, const char *fmt, ...) +static __attribute__((format(printf, 2, 3))) +void _stmt(const char *name, const char *fmt, ...) { va_list args; -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Anthony PERARD
2011-Oct-27 15:12 UTC
[Xen-devel] [PATCH 4/5] hvmloader/acpi/dsdt: Fix PCI hotplug with the new qemu-xen.
The ACPI PIIX4 device in QEMU upstream as not the same behavior to handle PCI hotplug. This patch introduce the necessary change to the DSDT ACPI table to behave as expceted by the new QEMU. To switch to this new DSDT table version, there is a new option --dm-version to mk_dsdt. Change are inspired by SeaBIOS DSDT source code. There is few things missing with the new QEMU: - QEMU provide the plugged/unplugged status only per slot (and not per func like qemu-xen-traditionnal. - I did not include the _STA ACPI method that give the status of a device (present, functionning properly) because qemu-xen does not handle it. - I did not include the _RMV method that say if the device can be removed, because the IO port of QEMU that give this status always return true. In SeaBIOS table, they have a specific _RMV method for VGA, ISA that return false. But I''m not sure that we can do the same in Xen. So, the only way to remove a device is from outside of the guest (like with xl pci-detatch), and can not be initiated from inside. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- tools/firmware/hvmloader/acpi/Makefile | 6 +- tools/firmware/hvmloader/acpi/mk_dsdt.c | 183 +++++++++++++++++++++---------- 2 files changed, 128 insertions(+), 61 deletions(-) diff --git a/tools/firmware/hvmloader/acpi/Makefile b/tools/firmware/hvmloader/acpi/Makefile index 7746a1c..c602b56 100644 --- a/tools/firmware/hvmloader/acpi/Makefile +++ b/tools/firmware/hvmloader/acpi/Makefile @@ -18,7 +18,7 @@ XEN_ROOT = $(CURDIR)/../../../.. include $(XEN_ROOT)/tools/firmware/Rules.mk -C_SRC = build.c dsdt_anycpu.c dsdt_15cpu.c static_tables.c +C_SRC = build.c dsdt_anycpu.c dsdt_15cpu.c static_tables.c dsdt_anycpu_qemu_xen.c OBJS = $(patsubst %.c,%.o,$(C_SRC)) CFLAGS += $(CFLAGS_xeninclude) @@ -34,6 +34,10 @@ ssdt_pm.h ssdt_tpm.h: %.h: %.asl iasl mk_dsdt: mk_dsdt.c $(HOSTCC) $(HOSTCFLAGS) $(CFLAGS_xeninclude) -o $@ mk_dsdt.c +dsdt_anycpu_qemu_xen.asl: dsdt.asl mk_dsdt + awk ''NR > 1 {print s} {s=$$0}'' $< > $@ + ./mk_dsdt --dm-version qemu-xen >> $@ + # NB. awk invocation is a portable alternative to ''head -n -1'' dsdt_%cpu.asl: dsdt.asl mk_dsdt awk ''NR > 1 {print s} {s=$$0}'' $< > $@ diff --git a/tools/firmware/hvmloader/acpi/mk_dsdt.c b/tools/firmware/hvmloader/acpi/mk_dsdt.c index c80a888..48011c3 100644 --- a/tools/firmware/hvmloader/acpi/mk_dsdt.c +++ b/tools/firmware/hvmloader/acpi/mk_dsdt.c @@ -8,6 +8,11 @@ static unsigned int indent_level; +typedef enum dm_version { + QEMU_XEN_TRADITIONAL, + QEMU_XEN, +} dm_version; + static void indent(void) { unsigned int i; @@ -77,12 +82,14 @@ static void decision_tree( static struct option options[] = { { "maxcpu", 1, 0, ''c'' }, + { "dm-version", 1, 0, ''q'' }, { 0, 0, 0, 0 } }; int main(int argc, char **argv) { unsigned int slot, dev, intx, link, cpu, max_cpus = HVM_MAX_VCPUS; + dm_version dm_version = QEMU_XEN_TRADITIONAL; while (1) { int opt = getopt_long(argc, argv, "", options, NULL); @@ -103,8 +110,17 @@ int main(int argc, char **argv) } break; } + case ''q'': + if (strcmp(optarg, "qemu-xen") == 0) { + dm_version = QEMU_XEN; + } else if (strcmp(optarg, "qemu-xen-traditional") == 0) { + dm_version = QEMU_XEN_TRADITIONAL; + } else { + fprintf(stderr, "Unknown device model version `%s''.\n", optarg); + return -1; + } + break; default: - fprintf(stderr, "options not supported.\n"); return -1; } } @@ -218,10 +234,17 @@ int main(int argc, char **argv) */ push_block("Device", "HP0"); { stmt("Name", "_HID, EISAID(\"PNP0C02\")"); - stmt("Name", "_CRS, ResourceTemplate() {" - " IO (Decode16, 0x10c0, 0x10c0, 0x00, 0x82)" - " IO (Decode16, 0xb044, 0xb044, 0x00, 0x04)" - "}"); + if (dm_version == QEMU_XEN_TRADITIONAL) { + stmt("Name", "_CRS, ResourceTemplate() {" + " IO (Decode16, 0x10c0, 0x10c0, 0x00, 0x82)" + " IO (Decode16, 0xb044, 0xb044, 0x00, 0x04)" + "}"); + } else { + stmt("Name", "_CRS, ResourceTemplate() {" + " IO (Decode16, 0xae00, 0xae00, 0x00, 0x10)" + " IO (Decode16, 0xb044, 0xb044, 0x00, 0x04)" + "}"); + } } pop_block(); @@ -309,37 +332,56 @@ int main(int argc, char **argv) * QEMU provides a simple hotplug controller with some I/O to handle * the hotplug action and status, which is beyond the ACPI scope. */ - for ( slot = 0; slot < 0x100; slot++ ) - { - push_block("Device", "S%02X", slot); - /* _ADR == dev:fn (16:16) */ - stmt("Name", "_ADR, 0x%08x", ((slot & ~7) << 13) | (slot & 7)); - /* _SUN == dev */ - stmt("Name", "_SUN, 0x%08x", slot >> 3); - push_block("Method", "_PS0, 0"); - stmt("Store", "0x%02x, \\_GPE.DPT1", slot); - stmt("Store", "0x80, \\_GPE.DPT2"); - pop_block(); - push_block("Method", "_PS3, 0"); - stmt("Store", "0x%02x, \\_GPE.DPT1", slot); - stmt("Store", "0x83, \\_GPE.DPT2"); - pop_block(); - push_block("Method", "_EJ0, 1"); - stmt("Store", "0x%02x, \\_GPE.DPT1", slot); - stmt("Store", "0x88, \\_GPE.DPT2"); - stmt("Store", "0x%02x, \\_GPE.PH%02X", /* eject */ - (slot & 1) ? 0x10 : 0x01, slot & ~1); - pop_block(); - push_block("Method", "_STA, 0"); - stmt("Store", "0x%02x, \\_GPE.DPT1", slot); - stmt("Store", "0x89, \\_GPE.DPT2"); - if ( slot & 1 ) - stmt("ShiftRight", "0x4, \\_GPE.PH%02X, Local1", slot & ~1); - else - stmt("And", "\\_GPE.PH%02X, 0x0f, Local1", slot & ~1); - stmt("Return", "Local1"); /* IN status as the _STA */ - pop_block(); + if (dm_version == QEMU_XEN_TRADITIONAL) { + for ( slot = 0; slot < 0x100; slot++ ) + { + push_block("Device", "S%02X", slot); + /* _ADR == dev:fn (16:16) */ + stmt("Name", "_ADR, 0x%08x", ((slot & ~7) << 13) | (slot & 7)); + /* _SUN == dev */ + stmt("Name", "_SUN, 0x%08x", slot >> 3); + push_block("Method", "_PS0, 0"); + stmt("Store", "0x%02x, \\_GPE.DPT1", slot); + stmt("Store", "0x80, \\_GPE.DPT2"); + pop_block(); + push_block("Method", "_PS3, 0"); + stmt("Store", "0x%02x, \\_GPE.DPT1", slot); + stmt("Store", "0x83, \\_GPE.DPT2"); + pop_block(); + push_block("Method", "_EJ0, 1"); + stmt("Store", "0x%02x, \\_GPE.DPT1", slot); + stmt("Store", "0x88, \\_GPE.DPT2"); + stmt("Store", "0x%02x, \\_GPE.PH%02X", /* eject */ + (slot & 1) ? 0x10 : 0x01, slot & ~1); + pop_block(); + push_block("Method", "_STA, 0"); + stmt("Store", "0x%02x, \\_GPE.DPT1", slot); + stmt("Store", "0x89, \\_GPE.DPT2"); + if ( slot & 1 ) + stmt("ShiftRight", "0x4, \\_GPE.PH%02X, Local1", slot & ~1); + else + stmt("And", "\\_GPE.PH%02X, 0x0f, Local1", slot & ~1); + stmt("Return", "Local1"); /* IN status as the _STA */ + pop_block(); + pop_block(); + } + } else { + stmt("OperationRegion", "SEJ, SystemIO, 0xae08, 0x04"); + push_block("Field", "SEJ, DWordAcc, NoLock, WriteAsZeros"); + indent(); printf("B0EJ, 32,\n"); pop_block(); + + /* hotplug_slot */ + for (slot = 1; slot <= 31; slot++) { + push_block("Device", "S%i", slot); { + stmt("Name", "_ADR, %#06x0000", slot); + push_block("Method", "_EJ0,1"); { + stmt("Store", "ShiftLeft(1, %#06x), B0EJ", slot); + stmt("Return", "0x0"); + } pop_block(); + stmt("Name", "_SUN, %i", slot); + } pop_block(); + } } pop_block(); @@ -349,18 +391,26 @@ int main(int argc, char **argv) /**** GPE start ****/ push_block("Scope", "\\_GPE"); - stmt("OperationRegion", "PHP, SystemIO, 0x10c0, 0x82"); - - push_block("Field", "PHP, ByteAcc, NoLock, Preserve"); - indent(); printf("PSTA, 8,\n"); /* hotplug controller event reg */ - indent(); printf("PSTB, 8,\n"); /* hotplug controller slot reg */ - for ( slot = 0; slot < 0x100; slot += 2 ) - { - indent(); - /* Each hotplug control register manages a pair of pci functions. */ - printf("PH%02X, 8,\n", slot); + if (dm_version == QEMU_XEN_TRADITIONAL) { + stmt("OperationRegion", "PHP, SystemIO, 0x10c0, 0x82"); + + push_block("Field", "PHP, ByteAcc, NoLock, Preserve"); + indent(); printf("PSTA, 8,\n"); /* hotplug controller event reg */ + indent(); printf("PSTB, 8,\n"); /* hotplug controller slot reg */ + for ( slot = 0; slot < 0x100; slot += 2 ) + { + indent(); + /* Each hotplug control register manages a pair of pci functions. */ + printf("PH%02X, 8,\n", slot); + } + pop_block(); + } else { + stmt("OperationRegion", "PCST, SystemIO, 0xae00, 0x08"); + push_block("Field", "PCST, DWordAcc, NoLock, WriteAsZeros"); + indent(); printf("PCIU, 32,\n"); + indent(); printf("PCID, 32,\n"); + pop_block(); } - pop_block(); stmt("OperationRegion", "DG1, SystemIO, 0xb044, 0x04"); @@ -368,20 +418,33 @@ int main(int argc, char **argv) indent(); printf("DPT1, 8, DPT2, 8\n"); pop_block(); - push_block("Method", "_L03, 0, Serialized"); - /* Detect slot and event (remove/add). */ - stmt("Name", "SLT, 0x0"); - stmt("Name", "EVT, 0x0"); - stmt("Store", "PSTA, Local1"); - stmt("And", "Local1, 0xf, EVT"); - stmt("Store", "PSTB, Local1"); /* XXX: Store (PSTB, SLT) ? */ - stmt("And", "Local1, 0xff, SLT"); - /* Debug */ - stmt("Store", "SLT, DPT1"); - stmt("Store", "EVT, DPT2"); - /* Decision tree */ - decision_tree(0x00, 0x100, "SLT", pci_hotplug_notify); - pop_block(); + if (dm_version == QEMU_XEN_TRADITIONAL) { + push_block("Method", "_L03, 0, Serialized"); + /* Detect slot and event (remove/add). */ + stmt("Name", "SLT, 0x0"); + stmt("Name", "EVT, 0x0"); + stmt("Store", "PSTA, Local1"); + stmt("And", "Local1, 0xf, EVT"); + stmt("Store", "PSTB, Local1"); /* XXX: Store (PSTB, SLT) ? */ + stmt("And", "Local1, 0xff, SLT"); + /* Debug */ + stmt("Store", "SLT, DPT1"); + stmt("Store", "EVT, DPT2"); + /* Decision tree */ + decision_tree(0x00, 0x100, "SLT", pci_hotplug_notify); + pop_block(); + } else { + push_block("Method", "_L01"); + for (slot = 1; slot <= 31; slot++) { + push_block("If", "And(PCIU, ShiftLeft(1, %i))", slot); + stmt("Notify", "\\_SB.PCI0.S%i, 1", slot); + pop_block(); + push_block("If", "And(PCID, ShiftLeft(1, %i))", slot); + stmt("Notify", "\\_SB.PCI0.S%i, 3", slot); + pop_block(); + } + pop_block(); + } pop_block(); /**** GPE end ****/ -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Anthony PERARD
2011-Oct-27 15:12 UTC
[Xen-devel] [PATCH 5/5] hvmloader: Load DSDT table from parametter
In order to have two different DSDT tables for rombios and SeaBIOS, this patch introduce a new parameter to acpi_build_tables() which contain the DSDT table to load. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- tools/firmware/hvmloader/acpi/acpi2_0.h | 9 ++++++++- tools/firmware/hvmloader/acpi/build.c | 31 ++++++++++++++----------------- tools/firmware/hvmloader/rombios.c | 12 +++++++++++- tools/firmware/hvmloader/seabios.c | 12 +++++++++++- 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/tools/firmware/hvmloader/acpi/acpi2_0.h b/tools/firmware/hvmloader/acpi/acpi2_0.h index 7fa8f5b..b281ec0 100644 --- a/tools/firmware/hvmloader/acpi/acpi2_0.h +++ b/tools/firmware/hvmloader/acpi/acpi2_0.h @@ -391,7 +391,14 @@ struct acpi_20_madt_intsrcovr { #pragma pack () -void acpi_build_tables(unsigned int physical); +struct acpi_config { + unsigned char *dsdt_anycpu; + int dsdt_anycpu_len; + unsigned char *dsdt_15cpu; + int dsdt_15cpu_len; +}; + +void acpi_build_tables(struct acpi_config *config, unsigned int physical); #endif /* _ACPI_2_0_H_ */ diff --git a/tools/firmware/hvmloader/acpi/build.c b/tools/firmware/hvmloader/acpi/build.c index d8222b1..c902885 100644 --- a/tools/firmware/hvmloader/acpi/build.c +++ b/tools/firmware/hvmloader/acpi/build.c @@ -47,17 +47,6 @@ struct acpi_info { uint32_t madt_lapic0_addr; /* 16 - Address of first MADT LAPIC struct */ }; -/* - * Alternative DSDTs we get linked against. A cover-all DSDT for up to the - * implementation-defined maximum number of VCPUs, and an alternative for use - * when a guest can only have up to 15 VCPUs. - * - * The latter is required for Windows 2000, which experiences a BSOD of - * KMODE_EXCEPTION_NOT_HANDLED if it sees more than 15 processor objects. - */ -extern unsigned char dsdt_anycpu[], dsdt_15cpu; -extern int dsdt_anycpu_len, dsdt_15cpu_len; - /* Number of processor objects in the chosen DSDT. */ static unsigned int nr_processor_objects; @@ -285,7 +274,7 @@ static int construct_secondary_tables(unsigned long *table_ptrs, return nr_tables; } -void acpi_build_tables(unsigned int physical) +void acpi_build_tables(struct acpi_config *config, unsigned int physical) { struct acpi_info *acpi_info = (struct acpi_info *)ACPI_INFO_PHYSICAL_ADDRESS; struct acpi_20_rsdp *rsdp; @@ -308,18 +297,26 @@ void acpi_build_tables(unsigned int physical) if (!facs) goto oom; memcpy(facs, &Facs, sizeof(struct acpi_20_facs)); - if ( hvm_info->nr_vcpus <= 15 ) + /* + * Alternative DSDTs we get linked against. A cover-all DSDT for up to the + * implementation-defined maximum number of VCPUs, and an alternative for use + * when a guest can only have up to 15 VCPUs. + * + * The latter is required for Windows 2000, which experiences a BSOD of + * KMODE_EXCEPTION_NOT_HANDLED if it sees more than 15 processor objects. + */ + if ( hvm_info->nr_vcpus <= 15 && config->dsdt_15cpu) { - dsdt = mem_alloc(dsdt_15cpu_len, 16); + dsdt = mem_alloc(config->dsdt_15cpu_len, 16); if (!dsdt) goto oom; - memcpy(dsdt, &dsdt_15cpu, dsdt_15cpu_len); + memcpy(dsdt, config->dsdt_15cpu, config->dsdt_15cpu_len); nr_processor_objects = 15; } else { - dsdt = mem_alloc(dsdt_anycpu_len, 16); + dsdt = mem_alloc(config->dsdt_anycpu_len, 16); if (!dsdt) goto oom; - memcpy(dsdt, &dsdt_anycpu, dsdt_anycpu_len); + memcpy(dsdt, config->dsdt_anycpu, config->dsdt_anycpu_len); nr_processor_objects = HVM_MAX_VCPUS; } diff --git a/tools/firmware/hvmloader/rombios.c b/tools/firmware/hvmloader/rombios.c index 017bd4c..fa38014 100644 --- a/tools/firmware/hvmloader/rombios.c +++ b/tools/firmware/hvmloader/rombios.c @@ -40,6 +40,9 @@ #define ROMBIOS_MAXOFFSET 0x0000FFFF #define ROMBIOS_END (ROMBIOS_BEGIN + ROMBIOS_SIZE) +extern unsigned char dsdt_anycpu[], dsdt_15cpu[]; +extern int dsdt_anycpu_len, dsdt_15cpu_len; + static void rombios_setup_e820(void) { /* @@ -112,7 +115,14 @@ static void reset_bios_checksum(void) static void rombios_acpi_build_tables(void) { - acpi_build_tables(ACPI_PHYSICAL_ADDRESS); + struct acpi_config config = { + .dsdt_anycpu = dsdt_anycpu, + .dsdt_anycpu_len = dsdt_anycpu_len, + .dsdt_15cpu = dsdt_15cpu, + .dsdt_15cpu_len = dsdt_15cpu_len, + }; + + acpi_build_tables(&config, ACPI_PHYSICAL_ADDRESS); } static void rombios_create_mp_tables(void) diff --git a/tools/firmware/hvmloader/seabios.c b/tools/firmware/hvmloader/seabios.c index 8f4c0a4..3045157 100644 --- a/tools/firmware/hvmloader/seabios.c +++ b/tools/firmware/hvmloader/seabios.c @@ -31,6 +31,9 @@ #define ROM_INCLUDE_SEABIOS #include "roms.inc" +extern unsigned char dsdt_anycpu_qemu_xen[]; +extern int dsdt_anycpu_qemu_xen_len; + struct seabios_info { char signature[14]; /* XenHVMSeaBIOS\0 */ uint8_t length; /* Length of this struct */ @@ -91,7 +94,14 @@ static void add_table(uint32_t t) static void seabios_acpi_build_tables(void) { uint32_t rsdp = (uint32_t)scratch_alloc(sizeof(struct acpi_20_rsdp), 0); - acpi_build_tables(rsdp); + struct acpi_config config = { + .dsdt_anycpu = dsdt_anycpu_qemu_xen, + .dsdt_anycpu_len = dsdt_anycpu_qemu_xen_len, + .dsdt_15cpu = NULL, + .dsdt_15cpu_len = 0, + }; + + acpi_build_tables(&config, rsdp); add_table(rsdp); } -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel