From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LzBbW-0000in-0u for qemu-devel@nongnu.org; Wed, 29 Apr 2009 11:21:46 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LzBbR-0000iR-8U for qemu-devel@nongnu.org; Wed, 29 Apr 2009 11:21:45 -0400 Received: from [199.232.76.173] (port=34594 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LzBbR-0000iO-20 for qemu-devel@nongnu.org; Wed, 29 Apr 2009 11:21:41 -0400 Received: from e5.ny.us.ibm.com ([32.97.182.145]:46280) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LzBbQ-0000Wd-OJ for qemu-devel@nongnu.org; Wed, 29 Apr 2009 11:21:40 -0400 Received: from d01relay04.pok.ibm.com (d01relay04.pok.ibm.com [9.56.227.236]) by e5.ny.us.ibm.com (8.13.1/8.13.1) with ESMTP id n3TFGlnq017988 for ; Wed, 29 Apr 2009 11:16:47 -0400 Received: from d01av01.pok.ibm.com (d01av01.pok.ibm.com [9.56.224.215]) by d01relay04.pok.ibm.com (8.13.8/8.13.8/NCO v9.2) with ESMTP id n3TFLVSw118902 for ; Wed, 29 Apr 2009 11:21:31 -0400 Received: from d01av01.pok.ibm.com (loopback [127.0.0.1]) by d01av01.pok.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id n3TFLUBL031164 for ; Wed, 29 Apr 2009 11:21:30 -0400 From: Beth Kon Date: Wed, 29 Apr 2009 11:21:40 -0400 Message-Id: <1241018500-29372-1-git-send-email-eak@us.ibm.com> Subject: [Qemu-devel] [RFC][PATCH] Fix ACPI Table Collision List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Beth Kon A potential collision exists in the current rombios32.c between 2 ACPI table entries: rsdt->table_offset_entry[i+4] = cpu_to_le32(addr); (when i == 0) and rsdt->table_offset_entry[4] = cpu_to_le32(srat_addr); This patch corrects the problem. I have built this and very primitively tested that -numa doesn't make anything explode, but have not tested additional acpi tables. I'm hope others who have been playing with this stuff would be more readily able to confirm that nothing breaks. One thing I don't understand is why the line acpi_additional_tables(); /* resets cfg to required entry */ is needed. So maybe I'm missing some subtlety here. If someone could explain I'd appreciate it. Signed-off-by: Beth Kon diff --git a/bios/rombios32.c b/bios/rombios32.c index d8f6d4e..72f5e4c 100644 --- a/bios/rombios32.c +++ b/bios/rombios32.c @@ -47,6 +47,12 @@ typedef unsigned long long uint64_t; #define wbinvd() asm volatile("wbinvd") +#ifdef BX_QEMU +#define BASE_ACPI_TABLES 4 +#else +#define BASE_ACPI_TABLES 3 +#endif + #define CPUID_MSR (1 << 5) #define CPUID_APIC (1 << 9) #define CPUID_MTRR (1 << 12) @@ -1294,12 +1300,9 @@ struct rsdp_descriptor /* Root System Descriptor Pointer */ struct rsdt_descriptor_rev1 { ACPI_TABLE_HEADER_DEF /* ACPI common table header */ -#ifdef BX_QEMU - uint32_t table_offset_entry [5]; /* Array of pointers to other */ -#else - uint32_t table_offset_entry [3]; /* Array of pointers to other */ -#endif - /* ACPI tables */ + uint32_t table_offset_entry [BASE_ACPI_TABLES]; /* Array of pointers + * to other ACPI + * tables*/ } __attribute__((__packed__)); /* @@ -1666,8 +1669,14 @@ void acpi_bios_init(void) #ifdef BX_QEMU external_tables = acpi_additional_tables(); + qemu_cfg_select(QEMU_CFG_NUMA); + nb_numa_nodes = qemu_cfg_get64(); + if (nb_numa_nodes > 0) { + external_tables++; + } #else external_tables = 0; + nb_numa_nodes = 0; #endif addr = base_addr = ram_size - ACPI_DATA_SIZE; @@ -1693,12 +1702,6 @@ void acpi_bios_init(void) ssdt_addr = addr; ssdt = (void *)(addr); addr += acpi_build_processor_ssdt(ssdt); -#ifdef BX_QEMU - qemu_cfg_select(QEMU_CFG_NUMA); - nb_numa_nodes = qemu_cfg_get64(); -#else - nb_numa_nodes = 0; -#endif if (nb_numa_nodes > 0) { addr = (addr + 7) & ~7; srat_addr = addr; @@ -1897,9 +1900,13 @@ void acpi_bios_init(void) acpi_additional_tables(); /* resets cfg to required entry */ for(i = 0; i < external_tables; i++) { uint16_t len; + if (i == 0 && nb_numa_nodes > 0) { + rsdt->table_offset_entry[BASE_ACPI_TABLES] = cpu_to_le32(srat_addr); + continue; + } if(acpi_load_table(i, addr, &len) < 0) BX_PANIC("Failed to load ACPI table from QEMU\n"); - rsdt->table_offset_entry[i+4] = cpu_to_le32(addr); + rsdt->table_offset_entry[i + BASE_ACPI_TABLES] = cpu_to_le32(addr); addr += len; if(addr >= ram_size) BX_PANIC("ACPI table overflow\n"); @@ -1912,11 +1919,9 @@ void acpi_bios_init(void) rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr); #ifdef BX_QEMU rsdt->table_offset_entry[3] = cpu_to_le32(hpet_addr); - if (nb_numa_nodes > 0) - rsdt->table_offset_entry[4] = cpu_to_le32(srat_addr); #endif acpi_build_table_header((struct acpi_table_header *)rsdt, "RSDT", - rsdt_size - (nb_numa_nodes > 0? 0: sizeof(uint32_t)), 1); + rsdt_size, 1); acpi_tables_size = addr - base_addr;