debuggers.hg

changeset 20979:a259e779467c

hvmloader: Build a compatibility DSDT with only 15 processor objects.

Deploy this smaller DSDT where possible: this is required to boot
Windows 2000, which only supports up to 15 processors and will blue
screen if it sees more processor objects than that (even inactive
ones).

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Feb 11 22:42:18 2010 +0000 (2010-02-11)
parents 363bbf511573
children 29797e6d5809
files .hgignore tools/firmware/hvmloader/acpi/Makefile tools/firmware/hvmloader/acpi/build.c tools/firmware/hvmloader/acpi/mk_dsdt.c
line diff
     1.1 --- a/.hgignore	Thu Feb 11 21:49:47 2010 +0000
     1.2 +++ b/.hgignore	Thu Feb 11 22:42:18 2010 +0000
     1.3 @@ -137,7 +137,7 @@
     1.4  ^tools/firmware/etherboot/gpxe/.*$
     1.5  ^tools/firmware/extboot/extboot.img$
     1.6  ^tools/firmware/extboot/signrom$
     1.7 -^tools/firmware/hvmloader/acpi/dsdt\.c$
     1.8 +^tools/firmware/hvmloader/acpi/dsdt.*\.c$
     1.9  ^tools/firmware/hvmloader/acpi/ssdt_.*\.h$
    1.10  ^tools/firmware/hvmloader/hvmloader$
    1.11  ^tools/firmware/hvmloader/roms\.h$
     2.1 --- a/tools/firmware/hvmloader/acpi/Makefile	Thu Feb 11 21:49:47 2010 +0000
     2.2 +++ b/tools/firmware/hvmloader/acpi/Makefile	Thu Feb 11 22:42:18 2010 +0000
     2.3 @@ -18,7 +18,7 @@
     2.4  XEN_ROOT = ../../../..
     2.5  include $(XEN_ROOT)/tools/firmware/Rules.mk
     2.6  
     2.7 -C_SRC = build.c dsdt.c static_tables.c
     2.8 +C_SRC = build.c dsdt.c dsdt15.c static_tables.c
     2.9  OBJS  = $(patsubst %.c,%.o,$(C_SRC))
    2.10  
    2.11  CFLAGS += -I. -I.. $(CFLAGS_include)
    2.12 @@ -32,15 +32,15 @@ ssdt_pm.h ssdt_tpm.h: %.h: %.asl
    2.13  	sed -e 's/AmlCode/$*/g' $*.hex >$@
    2.14  	rm -f *.aml $*.hex
    2.15  
    2.16 -dsdt.c: dsdt.asl mk_dsdt.c
    2.17 +dsdt.c dsdt15.c: %.c: dsdt.asl mk_dsdt.c
    2.18  	$(MAKE) iasl
    2.19 -	$(HOSTCC) $(HOSTCFLAGS) $(CFLAGS_include) -o mk_dsdt mk_dsdt.c
    2.20 -	head -n -1 $< >_dsdt.asl
    2.21 -	./mk_dsdt >>_dsdt.asl
    2.22 -	iasl -tc _dsdt.asl
    2.23 -	sed -e 's/AmlCode/Dsdt/g' _dsdt.hex >dsdt.c
    2.24 -	echo "int DsdtLen=sizeof(Dsdt);" >> dsdt.c
    2.25 -	rm -f *.aml _dsdt.asl mk_dsdt _dsdt.hex
    2.26 +	$(HOSTCC) $(HOSTCFLAGS) $(CFLAGS_include) -o mk_$* mk_dsdt.c
    2.27 +	head -n -1 $< >_$*.asl
    2.28 +	./mk_$* >>_$*.asl
    2.29 +	iasl -tc _$*.asl
    2.30 +	sed -e 's/AmlCode/_$*/g' _$*.hex >$@
    2.31 +	echo "int _$*_len=sizeof(_$*);" >>$@
    2.32 +	rm -f *.aml _dsdt* mk_$*
    2.33  
    2.34  iasl:
    2.35  	@echo
     3.1 --- a/tools/firmware/hvmloader/acpi/build.c	Thu Feb 11 21:49:47 2010 +0000
     3.2 +++ b/tools/firmware/hvmloader/acpi/build.c	Thu Feb 11 22:42:18 2010 +0000
     3.3 @@ -33,8 +33,20 @@ extern struct acpi_20_rsdt Rsdt;
     3.4  extern struct acpi_20_xsdt Xsdt;
     3.5  extern struct acpi_20_fadt Fadt;
     3.6  extern struct acpi_20_facs Facs;
     3.7 -extern unsigned char Dsdt[];
     3.8 -extern int DsdtLen;
     3.9 +
    3.10 +/*
    3.11 + * Alternative DSDTs we get linked against. A cover-all DSDT for up to the
    3.12 + * implementation-defined maximum number of VCPUs, and an alternative for use
    3.13 + * when a guest can only have up to 15 VCPUs.
    3.14 + * 
    3.15 + * The latter is required for Windows 2000, which experiences a BSOD of
    3.16 + * KMODE_EXCEPTION_NOT_HANDLED if it sees more than 15 processor objects.
    3.17 + */
    3.18 +extern unsigned char _dsdt[], _dsdt15;
    3.19 +extern int _dsdt_len, _dsdt15_len;
    3.20 +
    3.21 +/* Number of processor objects in the chosen DSDT. */
    3.22 +static unsigned int nr_processor_objects;
    3.23  
    3.24  static void set_checksum(
    3.25      void *table, uint32_t checksum_offset, uint32_t length)
    3.26 @@ -115,7 +127,7 @@ static int construct_madt(struct acpi_20
    3.27  
    3.28      lapic = (struct acpi_20_madt_lapic *)(io_apic + 1);
    3.29      madt_lapic0_addr = (uint32_t)lapic;
    3.30 -    for ( i = 0; i < HVM_MAX_VCPUS; i++ )
    3.31 +    for ( i = 0; i < nr_processor_objects; i++ )
    3.32      {
    3.33          memset(lapic, 0, sizeof(*lapic));
    3.34          lapic->type    = ACPI_PROCESSOR_LOCAL_APIC;
    3.35 @@ -251,8 +263,18 @@ static void __acpi_build_tables(uint8_t 
    3.36      offset += align16(sizeof(struct acpi_20_facs));
    3.37  
    3.38      dsdt = (unsigned char *)&buf[offset];
    3.39 -    memcpy(dsdt, &Dsdt, DsdtLen);
    3.40 -    offset += align16(DsdtLen);
    3.41 +    if ( hvm_info->nr_vcpus <= 15 )
    3.42 +    {
    3.43 +        memcpy(dsdt, &_dsdt15, _dsdt15_len);
    3.44 +        offset += align16(_dsdt15_len);
    3.45 +        nr_processor_objects = 15;
    3.46 +    }
    3.47 +    else
    3.48 +    {
    3.49 +        memcpy(dsdt, &_dsdt, _dsdt_len);
    3.50 +        offset += align16(_dsdt_len);
    3.51 +        nr_processor_objects = HVM_MAX_VCPUS;
    3.52 +    }
    3.53  
    3.54      /*
    3.55       * N.B. ACPI 1.0 operating systems may not handle FADT with revision 2
     4.1 --- a/tools/firmware/hvmloader/acpi/mk_dsdt.c	Thu Feb 11 21:49:47 2010 +0000
     4.2 +++ b/tools/firmware/hvmloader/acpi/mk_dsdt.c	Thu Feb 11 22:42:18 2010 +0000
     4.3 @@ -71,9 +71,12 @@ static void decision_tree(
     4.4      pop_block();
     4.5  }
     4.6  
     4.7 -int main(void)
     4.8 +int main(int argc, char **argv)
     4.9  {
    4.10 -    unsigned int slot, dev, intx, link, cpu;
    4.11 +    unsigned int slot, dev, intx, link, cpu, max_cpus = HVM_MAX_VCPUS;
    4.12 +
    4.13 +    /* Extract optional maximum-cpu specification from invocation name. */
    4.14 +    sscanf(argv[0], "%*[^0-9]%u", &max_cpus); /* e.g., ./mk_dsdt15 */
    4.15  
    4.16      /**** DSDT DefinitionBlock start ****/
    4.17      /* (we append to existing DSDT definition block) */
    4.18 @@ -89,7 +92,7 @@ int main(void)
    4.19      pop_block();
    4.20  
    4.21      /* Define processor objects and control methods. */
    4.22 -    for ( cpu = 0; cpu < HVM_MAX_VCPUS; cpu++)
    4.23 +    for ( cpu = 0; cpu < max_cpus; cpu++)
    4.24      {
    4.25          push_block("Processor", "PR%02X, %d, 0x0000b010, 0x06", cpu, cpu);
    4.26  
    4.27 @@ -131,13 +134,13 @@ int main(void)
    4.28      /* Operation Region 'PRST': bitmask of online CPUs. */
    4.29      stmt("OperationRegion", "PRST, SystemIO, 0xaf00, 32");
    4.30      push_block("Field", "PRST, ByteAcc, NoLock, Preserve");
    4.31 -    indent(); printf("PRS, %u\n", HVM_MAX_VCPUS);
    4.32 +    indent(); printf("PRS, %u\n", max_cpus);
    4.33      pop_block();
    4.34  
    4.35      /* Control method 'PRSC': CPU hotplug GPE handler. */
    4.36      push_block("Method", "PRSC, 0");
    4.37      stmt("Store", "PRS, Local0");
    4.38 -    for ( cpu = 0; cpu < HVM_MAX_VCPUS; cpu++ )
    4.39 +    for ( cpu = 0; cpu < max_cpus; cpu++ )
    4.40      {
    4.41          /* Read a byte at a time from the PRST online-CPU bitmask. */
    4.42          if ( (cpu & 7) == 0 )