提交 c34ebfdc 编写于 作者: A Anthony Liguori

Bring pcbios, seabios, and vgabios into the tree as git submodules. Right now,

they aren't integrated into the build but we can do that incrementally.
Signed-off-by: NAnthony Liguori <aliguori@us.ibm.com>
上级 ae027ad3
[submodule "roms/vgabios"]
path = roms/vgabios
url = ../vgabios.git
[submodule "roms/seabios"]
path = roms/seabios
url = ../seabios.git
[submodule "roms/pcbios"]
path = roms/pcbios
url = ../pcbios.git
...@@ -2405,10 +2405,12 @@ done # for target in $targets ...@@ -2405,10 +2405,12 @@ done # for target in $targets
# build tree in object directory if source path is different from current one # build tree in object directory if source path is different from current one
if test "$source_path_used" = "yes" ; then if test "$source_path_used" = "yes" ; then
DIRS="tests tests/cris slirp audio block pc-bios/optionrom" DIRS="tests tests/cris slirp audio block pc-bios/optionrom"
DIRS="$DIRS roms/pcbios roms/seabios roms/vgabios"
FILES="Makefile tests/Makefile" FILES="Makefile tests/Makefile"
FILES="$FILES tests/cris/Makefile tests/cris/.gdbinit" FILES="$FILES tests/cris/Makefile tests/cris/.gdbinit"
FILES="$FILES tests/test-mmap.c" FILES="$FILES tests/test-mmap.c"
FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps pc-bios/video.x" FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps pc-bios/video.x"
FILES="$FILES roms/pcbios/Makefile roms/seabios/Makefile roms/vgabios/Makefile"
for bios_file in $source_path/pc-bios/*.bin $source_path/pc-bios/*.dtb $source_path/pc-bios/openbios-*; do for bios_file in $source_path/pc-bios/*.bin $source_path/pc-bios/*.dtb $source_path/pc-bios/openbios-*; do
FILES="$FILES pc-bios/`basename $bios_file`" FILES="$FILES pc-bios/`basename $bios_file`"
done done
...@@ -2422,6 +2424,20 @@ if test "$source_path_used" = "yes" ; then ...@@ -2422,6 +2424,20 @@ if test "$source_path_used" = "yes" ; then
done done
fi fi
# temporary config to build submodules
for rom in seabios vgabios pcbios; do
config_mak=roms/$rom/config.mak
echo "# Automatically generated by configure - do not modify" >> $config_mak
echo "SRC_PATH=$source_path/roms/$rom" >> $config_mak
echo "CC=$cc" >> $config_mak
echo "BCC=bcc" >> $config_mak
echo "CPP=${cross_prefix}cpp" >> $config_mak
echo "OBJCOPY=objcopy" >> $config_mak
echo "IASL=iasl" >> $config_mak
echo "HOST_CC=$host_cc" >> $config_mak
echo "LD=$ld" >> $config_mak
done
for hwlib in 32 64; do for hwlib in 32 64; do
d=libhw$hwlib d=libhw$hwlib
mkdir -p $d mkdir -p $d
......
- The PC BIOS comes from the Bochs project (http://bochs.sourceforge.net/). - The PC BIOS comes from the Bochs project (http://bochs.sourceforge.net/).
The patches in bios-pq have been applied. The binary is based on the revision
in bios-pq/HEAD with the patches in bios-pq/series applied. The git repo
that HEAD refers to is located at
git://git.kernel.org/pub/scm/virt/bochs/bochs.git
To build these use the following instructions:
using guilt:
$ export QEMUSRC=/path/to/qemu/svn
$ git clone git://git.kernel.org/pub/scm/virt/bochs/bochs.git
$ cd bochs
$ git checkout -b qemu-bios $(cat $QEMUSRC/pc-bios/bios-pq/HEAD)
$ mkdir -p .git/patches
$ ln -s $QEMUSRC/pc-bios/bios-pq .git/patches/qemu-bios
$ touch .git/patches/qemu-bios/status
$ guilt push -a
$ ./configure
$ cd bios
$ make
$ cp BIOS-bochs-latest $QEMUSRC/pc-bios/bios.bin
or alternatively (after the git checkout):
$ for p in $(cat $QEMUSRC/pc-bios/bios-pq/series); do git am $p; done
$ ./configure
$ make bios
- The VGA BIOS and the Cirrus VGA BIOS come from the LGPL VGA bios - The VGA BIOS and the Cirrus VGA BIOS come from the LGPL VGA bios
project (http://www.nongnu.org/vgabios/). The binary is based on the revision project (http://www.nongnu.org/vgabios/).
in vgabios-pq/HEAD with the patches in vgabios-pq/series applied. The git
repo that HEAD refers to is located at
git://git.kernel.org/pub/scm/virt/vgabios/vgabios.git
- The PowerPC Open Hack'Ware Open Firmware Compatible BIOS is - The PowerPC Open Hack'Ware Open Firmware Compatible BIOS is
available at http://perso.magic.fr/l_indien/OpenHackWare/index.htm. available at http://perso.magic.fr/l_indien/OpenHackWare/index.htm.
......
--- bochs-2.3.7.orig/bios/rombios.h
+++ bochs-2.3.7/bios/rombios.h
@@ -19,7 +19,7 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/* define it to include QEMU specific code */
-//#define BX_QEMU
+#define BX_QEMU
#ifndef LEGACY
# define BX_ROMBIOS32 1
update SMBIOS table to report memory above 4G (Alex Williamson)
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Index: bochs/bios/rombios32.c
===================================================================
diff --git a/bios/rombios32.c b/bios/rombios32.c
index 3269be5..9587288 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -429,6 +429,7 @@ uint32_t cpuid_signature;
uint32_t cpuid_features;
uint32_t cpuid_ext_features;
unsigned long ram_size;
+uint64_t ram_end;
uint8_t bios_uuid[16];
#ifdef BX_USE_EBDA_TABLES
unsigned long ebda_cur_addr;
@@ -571,6 +572,13 @@ void ram_probe(void)
ram_size = (cmos_readb(0x30) | (cmos_readb(0x31) << 8)) * 1024 +
1 * 1024 * 1024;
BX_INFO("ram_size=0x%08lx\n", ram_size);
+ if (cmos_readb(0x5b) | cmos_readb(0x5c) | cmos_readb(0x5d))
+ ram_end = (((uint64_t)cmos_readb(0x5b) << 16) |
+ ((uint64_t)cmos_readb(0x5c) << 24) |
+ ((uint64_t)cmos_readb(0x5d) << 32)) + (1ull << 32);
+ else
+ ram_end = ram_size;
+ BX_INFO("end of ram=%ldMB\n", ram_end >> 20);
#ifdef BX_USE_EBDA_TABLES
ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380;
BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr);
@@ -2174,7 +2182,8 @@ void smbios_init(void)
{
unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
char *start, *p, *q;
- int memsize = ram_size / (1024 * 1024);
+ int memsize = (ram_end == ram_size) ? ram_size / (1024 * 1024) :
+ (ram_end - (1ull << 32) + ram_size) / (1024 * 1024);
#ifdef BX_USE_EBDA_TABLES
ebda_cur_addr = align(ebda_cur_addr, 16);
@@ -2201,8 +2210,8 @@ void smbios_init(void)
add_struct(smbios_type_4_init(p, cpu_num));
add_struct(smbios_type_16_init(p, memsize));
add_struct(smbios_type_17_init(p, memsize));
- add_struct(smbios_type_19_init(p, memsize));
- add_struct(smbios_type_20_init(p, memsize));
+ add_struct(smbios_type_19_init(p, ram_end / (1024 * 1024)));
+ add_struct(smbios_type_20_init(p, ram_end / (1024 * 1024)));
add_struct(smbios_type_32_init(p));
add_struct(smbios_type_127_init(p));
generate mptable unconditionally (Avi Kivity)
VMware ESX requires an mptable even for uniprocessor guests.
Signed-off-by: Avi Kivity <avi@qumranet.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Index: bochs/bios/rombios32.c
===================================================================
--- bochs.orig/bios/rombios32.c
+++ bochs/bios/rombios32.c
@@ -970,11 +970,6 @@ static void mptable_init(void)
int ioapic_id, i, len;
int mp_config_table_size;
-#ifdef BX_QEMU
- if (smp_cpus <= 1)
- return;
-#endif
-
#ifdef BX_USE_EBDA_TABLES
mp_config_table = (uint8_t *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE);
#else
resolve memory device roll over reporting issues with >32G guests (Bill Rieske)
The field within the Memory Device type 17 is only a word with the MSB being
used to report MB/KB. Thereby, a guest with 32G and greater would report
incorrect memory device information rolling over to 0.
This presents more than one memory device and associated memory structures
if the memory is larger than 16G
Signed-off-by: Bill Rieske <brieske@novell.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Index: bochs/bios/rombios32.c
===================================================================
--- bochs.orig/bios/rombios32.c
+++ bochs/bios/rombios32.c
@@ -381,6 +381,17 @@ int vsnprintf(char *buf, int buflen, con
return buf - buf0;
}
+int snprintf(char * buf, size_t size, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i=vsnprintf(buf,size,fmt,args);
+ va_end(args);
+ return i;
+}
+
void bios_printf(int flags, const char *fmt, ...)
{
va_list ap;
@@ -2039,7 +2050,7 @@ smbios_type_4_init(void *start, unsigned
/* Type 16 -- Physical Memory Array */
static void *
-smbios_type_16_init(void *start, uint32_t memsize)
+smbios_type_16_init(void *start, uint32_t memsize, int nr_mem_devs)
{
struct smbios_type_16 *p = (struct smbios_type_16*)start;
@@ -2052,7 +2063,7 @@ smbios_type_16_init(void *start, uint32_
p->error_correction = 0x01; /* other */
p->maximum_capacity = memsize * 1024;
p->memory_error_information_handle = 0xfffe; /* none provided */
- p->number_of_memory_devices = 1;
+ p->number_of_memory_devices = nr_mem_devs;
start += sizeof(struct smbios_type_16);
*((uint16_t *)start) = 0;
@@ -2062,20 +2073,19 @@ smbios_type_16_init(void *start, uint32_
/* Type 17 -- Memory Device */
static void *
-smbios_type_17_init(void *start, uint32_t memory_size_mb)
+smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance)
{
struct smbios_type_17 *p = (struct smbios_type_17 *)start;
p->header.type = 17;
p->header.length = sizeof(struct smbios_type_17);
- p->header.handle = 0x1100;
+ p->header.handle = 0x1100 + instance;
p->physical_memory_array_handle = 0x1000;
p->total_width = 64;
p->data_width = 64;
- /* truncate memory_size_mb to 16 bits and clear most significant
- bit [indicates size in MB] */
- p->size = (uint16_t) memory_size_mb & 0x7fff;
+/* TODO: should assert in case something is wrong ASSERT((memory_size_mb & ~0x7fff) == 0); */
+ p->size = memory_size_mb;
p->form_factor = 0x09; /* DIMM */
p->device_set = 0;
p->device_locator_str = 1;
@@ -2084,8 +2094,8 @@ smbios_type_17_init(void *start, uint32_
p->type_detail = 0;
start += sizeof(struct smbios_type_17);
- memcpy((char *)start, "DIMM 1", 7);
- start += 7;
+ snprintf(start, 8, "DIMM %d", instance);
+ start += strlen(start) + 1;
*((uint8_t *)start) = 0;
return start+1;
@@ -2093,16 +2103,16 @@ smbios_type_17_init(void *start, uint32_
/* Type 19 -- Memory Array Mapped Address */
static void *
-smbios_type_19_init(void *start, uint32_t memory_size_mb)
+smbios_type_19_init(void *start, uint32_t memory_size_mb, int instance)
{
struct smbios_type_19 *p = (struct smbios_type_19 *)start;
p->header.type = 19;
p->header.length = sizeof(struct smbios_type_19);
- p->header.handle = 0x1300;
+ p->header.handle = 0x1300 + instance;
- p->starting_address = 0;
- p->ending_address = (memory_size_mb * 1024) - 1;
+ p->starting_address = instance << 24;
+ p->ending_address = p->starting_address + (memory_size_mb << 10) - 1;
p->memory_array_handle = 0x1000;
p->partition_width = 1;
@@ -2114,18 +2124,18 @@ smbios_type_19_init(void *start, uint32_
/* Type 20 -- Memory Device Mapped Address */
static void *
-smbios_type_20_init(void *start, uint32_t memory_size_mb)
+smbios_type_20_init(void *start, uint32_t memory_size_mb, int instance)
{
struct smbios_type_20 *p = (struct smbios_type_20 *)start;
p->header.type = 20;
p->header.length = sizeof(struct smbios_type_20);
- p->header.handle = 0x1400;
+ p->header.handle = 0x1400 + instance;
- p->starting_address = 0;
- p->ending_address = (memory_size_mb * 1024) - 1;
- p->memory_device_handle = 0x1100;
- p->memory_array_mapped_address_handle = 0x1300;
+ p->starting_address = instance << 24;
+ p->ending_address = p->starting_address + (memory_size_mb << 10) - 1;
+ p->memory_device_handle = 0x1100 + instance;
+ p->memory_array_mapped_address_handle = 0x1300 + instance;
p->partition_row_position = 1;
p->interleave_position = 0;
p->interleaved_data_depth = 0;
@@ -2176,6 +2186,7 @@ void smbios_init(void)
char *start, *p, *q;
int memsize = (ram_end == ram_size) ? ram_size / (1024 * 1024) :
(ram_end - (1ull << 32) + ram_size) / (1024 * 1024);
+ int i, nr_mem_devs;
#ifdef BX_USE_EBDA_TABLES
ebda_cur_addr = align(ebda_cur_addr, 16);
@@ -2187,23 +2198,32 @@ void smbios_init(void)
p = (char *)start + sizeof(struct smbios_entry_point);
-#define add_struct(fn) { \
+#define add_struct(fn) do{ \
q = (fn); \
nr_structs++; \
if ((q - p) > max_struct_size) \
max_struct_size = q - p; \
p = q; \
-}
+}while (0)
add_struct(smbios_type_0_init(p));
add_struct(smbios_type_1_init(p));
add_struct(smbios_type_3_init(p));
for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
add_struct(smbios_type_4_init(p, cpu_num));
- add_struct(smbios_type_16_init(p, memsize));
- add_struct(smbios_type_17_init(p, memsize));
- add_struct(smbios_type_19_init(p, ram_end / (1024 * 1024)));
- add_struct(smbios_type_20_init(p, ram_end / (1024 * 1024)));
+
+ /* Each 'memory device' covers up to 16GB of address space. */
+ nr_mem_devs = (memsize + 0x3fff) >> 14;
+ add_struct(smbios_type_16_init(p, memsize, nr_mem_devs));
+ for ( i = 0; i < nr_mem_devs; i++ )
+ {
+ uint32_t dev_memsize = ((i == (nr_mem_devs - 1))
+ ? (memsize & 0x3fff) : 0x4000);
+ add_struct(smbios_type_17_init(p, dev_memsize, i));
+ add_struct(smbios_type_19_init(p, dev_memsize, i));
+ add_struct(smbios_type_20_init(p, dev_memsize, i));
+ }
+
add_struct(smbios_type_32_init(p));
add_struct(smbios_type_127_init(p));
fix smbios memory device length boundary condition (Bill Rieske)
dev_memsize ends up 0 when it shouldn't be on 16G boundary conditions.
Signed-off-by: Bill Rieske <brieske@novell.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Index: bochs/bios/rombios32.c
===================================================================
--- bochs.orig/bios/rombios32.c
+++ bochs/bios/rombios32.c
@@ -2218,7 +2218,7 @@ void smbios_init(void)
for ( i = 0; i < nr_mem_devs; i++ )
{
uint32_t dev_memsize = ((i == (nr_mem_devs - 1))
- ? (memsize & 0x3fff) : 0x4000);
+ ? (((memsize-1) & 0x3fff)+1) : 0x4000);
add_struct(smbios_type_17_init(p, dev_memsize, i));
add_struct(smbios_type_19_init(p, dev_memsize, i));
add_struct(smbios_type_20_init(p, dev_memsize, i));
qemu: bios: use preprocessor for pci link routing (Avi Kivity)
Signed-off-by: Avi Kivity <avi@qumranet.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Index: bochs/bios/acpi-dsdt.dsl
===================================================================
--- bochs.orig/bios/acpi-dsdt.dsl
+++ bochs/bios/acpi-dsdt.dsl
@@ -47,42 +47,22 @@ DefinitionBlock (
section 6.2.8.1 */
/* Note: we provide the same info as the PCI routing
table of the Bochs BIOS */
-
- // PCI Slot 0
- Package() {0x0000ffff, 0, LNKD, 0},
- Package() {0x0000ffff, 1, LNKA, 0},
- Package() {0x0000ffff, 2, LNKB, 0},
- Package() {0x0000ffff, 3, LNKC, 0},
-
- // PCI Slot 1
- Package() {0x0001ffff, 0, LNKA, 0},
- Package() {0x0001ffff, 1, LNKB, 0},
- Package() {0x0001ffff, 2, LNKC, 0},
- Package() {0x0001ffff, 3, LNKD, 0},
-
- // PCI Slot 2
- Package() {0x0002ffff, 0, LNKB, 0},
- Package() {0x0002ffff, 1, LNKC, 0},
- Package() {0x0002ffff, 2, LNKD, 0},
- Package() {0x0002ffff, 3, LNKA, 0},
-
- // PCI Slot 3
- Package() {0x0003ffff, 0, LNKC, 0},
- Package() {0x0003ffff, 1, LNKD, 0},
- Package() {0x0003ffff, 2, LNKA, 0},
- Package() {0x0003ffff, 3, LNKB, 0},
-
- // PCI Slot 4
- Package() {0x0004ffff, 0, LNKD, 0},
- Package() {0x0004ffff, 1, LNKA, 0},
- Package() {0x0004ffff, 2, LNKB, 0},
- Package() {0x0004ffff, 3, LNKC, 0},
-
- // PCI Slot 5
- Package() {0x0005ffff, 0, LNKA, 0},
- Package() {0x0005ffff, 1, LNKB, 0},
- Package() {0x0005ffff, 2, LNKC, 0},
- Package() {0x0005ffff, 3, LNKD, 0},
+#define prt_slot(nr, lnk0, lnk1, lnk2, lnk3) \
+ Package() { nr##ffff, 0, lnk0, 0 }, \
+ Package() { nr##ffff, 1, lnk1, 0 }, \
+ Package() { nr##ffff, 2, lnk2, 0 }, \
+ Package() { nr##ffff, 3, lnk3, 0 }
+
+#define prt_slot0(nr) prt_slot(nr, LNKD, LNKA, LNKB, LNKC)
+#define prt_slot1(nr) prt_slot(nr, LNKA, LNKB, LNKC, LNKD)
+#define prt_slot2(nr) prt_slot(nr, LNKB, LNKC, LNKD, LNKA)
+#define prt_slot3(nr) prt_slot(nr, LNKC, LNKD, LNKA, LNKB)
+ prt_slot0(0x0000),
+ prt_slot1(0x0001),
+ prt_slot2(0x0002),
+ prt_slot3(0x0003),
+ prt_slot0(0x0004),
+ prt_slot1(0x0005),
})
Name (_CRS, ResourceTemplate ()
--
bios: add 26 pci slots, bringing the total to 32 (Avi Kivity)
lack of pci slots causes Windows to complain when installing too many devices.
Signed-off-by: Avi Kivity <avi@qumranet.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Index: bochs/bios/acpi-dsdt.dsl
===================================================================
--- bochs.orig/bios/acpi-dsdt.dsl
+++ bochs/bios/acpi-dsdt.dsl
@@ -63,6 +63,32 @@ DefinitionBlock (
prt_slot3(0x0003),
prt_slot0(0x0004),
prt_slot1(0x0005),
+ prt_slot2(0x0006),
+ prt_slot3(0x0007),
+ prt_slot0(0x0008),
+ prt_slot1(0x0009),
+ prt_slot2(0x000a),
+ prt_slot3(0x000b),
+ prt_slot0(0x000c),
+ prt_slot1(0x000d),
+ prt_slot2(0x000e),
+ prt_slot3(0x000f),
+ prt_slot0(0x0010),
+ prt_slot1(0x0011),
+ prt_slot2(0x0012),
+ prt_slot3(0x0013),
+ prt_slot0(0x0014),
+ prt_slot1(0x0015),
+ prt_slot2(0x0016),
+ prt_slot3(0x0017),
+ prt_slot0(0x0018),
+ prt_slot1(0x0019),
+ prt_slot2(0x001a),
+ prt_slot3(0x001b),
+ prt_slot0(0x001c),
+ prt_slot1(0x001d),
+ prt_slot2(0x001e),
+ prt_slot3(0x001f),
})
Name (_CRS, ResourceTemplate ()
--
qemu: bios: provide gpe _L0x methods (Glauber Costa)
provide methods for gpe blk 0, even though they do nothing atm
Signed-off-by: Glauber Costa <gcosta@redhat.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Index: bochs/bios/acpi-dsdt.dsl
===================================================================
--- bochs.orig/bios/acpi-dsdt.dsl
+++ bochs/bios/acpi-dsdt.dsl
@@ -597,4 +597,59 @@ DefinitionBlock (
Zero, /* reserved */
Zero /* reserved */
})
+
+ Scope (\_GPE)
+ {
+ Name(_HID, "ACPI0006")
+
+ Method(_L00) {
+ Return(0x01)
+ }
+ Method(_L01) {
+ Return(0x01)
+ }
+ Method(_L02) {
+ Return(0x01)
+ }
+ Method(_L03) {
+ Return(0x01)
+ }
+ Method(_L04) {
+ Return(0x01)
+ }
+ Method(_L05) {
+ Return(0x01)
+ }
+ Method(_L06) {
+ Return(0x01)
+ }
+ Method(_L07) {
+ Return(0x01)
+ }
+ Method(_L08) {
+ Return(0x01)
+ }
+ Method(_L09) {
+ Return(0x01)
+ }
+ Method(_L0A) {
+ Return(0x01)
+ }
+ Method(_L0B) {
+ Return(0x01)
+ }
+ Method(_L0C) {
+ Return(0x01)
+ }
+ Method(_L0D) {
+ Return(0x01)
+ }
+ Method(_L0E) {
+ Return(0x01)
+ }
+ Method(_L0F) {
+ Return(0x01)
+ }
+ }
+
}
Index: bochs/bios/rombios32.c
===================================================================
--- bochs.orig/bios/rombios32.c
+++ bochs/bios/rombios32.c
@@ -1647,6 +1647,8 @@ void acpi_bios_init(void)
fadt->pm_tmr_len = 4;
fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported
fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported
+ fadt->gpe0_blk = cpu_to_le32(0xafe0);
+ fadt->gpe0_blk_len = 4;
/* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */
fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6));
acpi_build_table_header((struct acpi_table_header *)fadt, "FACP",
--
qemu: bios: pci hotplug support (Marcelo Tosatti)
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Index: bochs/bios/acpi-dsdt.dsl
===================================================================
--- bochs.orig/bios/acpi-dsdt.dsl
+++ bochs/bios/acpi-dsdt.dsl
@@ -91,6 +91,61 @@ DefinitionBlock (
prt_slot3(0x001f),
})
+ OperationRegion(PCST, SystemIO, 0xae00, 0x08)
+ Field (PCST, DWordAcc, NoLock, WriteAsZeros)
+ {
+ PCIU, 32,
+ PCID, 32,
+ }
+
+ OperationRegion(SEJ, SystemIO, 0xae08, 0x04)
+ Field (SEJ, DWordAcc, NoLock, WriteAsZeros)
+ {
+ B0EJ, 32,
+ }
+
+#define hotplug_slot(name, nr) \
+ Device (S##name) { \
+ Name (_ADR, nr##0000) \
+ Method (_EJ0,1) { \
+ Store(ShiftLeft(1, nr), B0EJ) \
+ Return (0x0) \
+ } \
+ Name (_SUN, name) \
+ }
+
+ hotplug_slot(1, 0x0001)
+ hotplug_slot(2, 0x0002)
+ hotplug_slot(3, 0x0003)
+ hotplug_slot(4, 0x0004)
+ hotplug_slot(5, 0x0005)
+ hotplug_slot(6, 0x0006)
+ hotplug_slot(7, 0x0007)
+ hotplug_slot(8, 0x0008)
+ hotplug_slot(9, 0x0009)
+ hotplug_slot(10, 0x000a)
+ hotplug_slot(11, 0x000b)
+ hotplug_slot(12, 0x000c)
+ hotplug_slot(13, 0x000d)
+ hotplug_slot(14, 0x000e)
+ hotplug_slot(15, 0x000f)
+ hotplug_slot(16, 0x0010)
+ hotplug_slot(17, 0x0011)
+ hotplug_slot(18, 0x0012)
+ hotplug_slot(19, 0x0013)
+ hotplug_slot(20, 0x0014)
+ hotplug_slot(21, 0x0015)
+ hotplug_slot(22, 0x0016)
+ hotplug_slot(23, 0x0017)
+ hotplug_slot(24, 0x0018)
+ hotplug_slot(25, 0x0019)
+ hotplug_slot(26, 0x001a)
+ hotplug_slot(27, 0x001b)
+ hotplug_slot(28, 0x001c)
+ hotplug_slot(29, 0x001d)
+ hotplug_slot(30, 0x001e)
+ hotplug_slot(31, 0x001f)
+
Name (_CRS, ResourceTemplate ()
{
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
@@ -605,8 +660,50 @@ DefinitionBlock (
Method(_L00) {
Return(0x01)
}
+
+#define gen_pci_hotplug(nr) \
+ If (And(\_SB.PCI0.PCIU, ShiftLeft(1, nr))) { \
+ Notify(\_SB.PCI0.S##nr, 1) \
+ } \
+ If (And(\_SB.PCI0.PCID, ShiftLeft(1, nr))) { \
+ Notify(\_SB.PCI0.S##nr, 3) \
+ }
+
Method(_L01) {
- Return(0x01)
+ gen_pci_hotplug(1)
+ gen_pci_hotplug(2)
+ gen_pci_hotplug(3)
+ gen_pci_hotplug(4)
+ gen_pci_hotplug(5)
+ gen_pci_hotplug(6)
+ gen_pci_hotplug(7)
+ gen_pci_hotplug(8)
+ gen_pci_hotplug(9)
+ gen_pci_hotplug(10)
+ gen_pci_hotplug(11)
+ gen_pci_hotplug(12)
+ gen_pci_hotplug(13)
+ gen_pci_hotplug(14)
+ gen_pci_hotplug(15)
+ gen_pci_hotplug(16)
+ gen_pci_hotplug(17)
+ gen_pci_hotplug(18)
+ gen_pci_hotplug(19)
+ gen_pci_hotplug(20)
+ gen_pci_hotplug(21)
+ gen_pci_hotplug(22)
+ gen_pci_hotplug(23)
+ gen_pci_hotplug(24)
+ gen_pci_hotplug(25)
+ gen_pci_hotplug(26)
+ gen_pci_hotplug(27)
+ gen_pci_hotplug(28)
+ gen_pci_hotplug(29)
+ gen_pci_hotplug(30)
+ gen_pci_hotplug(31)
+
+ Return (0x01)
+
}
Method(_L02) {
Return(0x01)
--
bios: mark the acpi sci interrupt as connected to irq 9 (Avi Kivity)
Due to a chipset bug, the sci interrupt is hardwired to irq 9. Set the
pci interrupt line register accordingly.
Signed-off-by: Avi Kivity <avi@qumranet.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Index: bochs/bios/rombios32.c
===================================================================
--- bochs.orig/bios/rombios32.c
+++ bochs/bios/rombios32.c
@@ -981,6 +981,8 @@ static void pci_bios_init_device(PCIDevi
/* PIIX4 Power Management device (for ACPI) */
pm_io_base = PM_IO_BASE;
smb_io_base = SMB_IO_BASE;
+ // acpi sci is hardwired to 9
+ pci_config_writeb(d, PCI_INTERRUPT_LINE, 9);
pm_sci_int = pci_config_readb(d, PCI_INTERRUPT_LINE);
piix4_pm_enable(d);
acpi_enabled = 1;
--
Read additional ACPI tables from a VM (Gleb Natapov)
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
diff --git a/bios/rombios32.c b/bios/rombios32.c
index 27c5952..7be4216 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -469,6 +469,8 @@ void wrmsr_smp(uint32_t index, uint64_t val)
#define QEMU_CFG_SIGNATURE 0x00
#define QEMU_CFG_ID 0x01
#define QEMU_CFG_UUID 0x02
+#define QEMU_CFG_ARCH_LOCAL 0x8000
+#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0)
int qemu_cfg_port;
@@ -496,6 +498,27 @@ void qemu_cfg_read(uint8_t *buf, int len)
while (len--)
*(buf++) = inb(QEMU_CFG_DATA_PORT);
}
+
+static uint16_t acpi_additional_tables(void)
+{
+ uint16_t cnt;
+
+ qemu_cfg_select(QEMU_CFG_ACPI_TABLES);
+ qemu_cfg_read((uint8_t*)&cnt, sizeof(cnt));
+
+ return cnt;
+}
+
+static int acpi_load_table(int i, uint32_t addr, uint16_t *len)
+{
+ qemu_cfg_read((uint8_t*)len, sizeof(*len));
+
+ if (!*len)
+ return -1;
+
+ qemu_cfg_read((uint8_t*)addr, *len);
+ return 0;
+}
#endif
void uuid_probe(void)
@@ -1550,8 +1573,8 @@ void acpi_bios_init(void)
uint32_t hpet_addr;
#endif
uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr, ssdt_addr;
- uint32_t acpi_tables_size, madt_addr, madt_size;
- int i;
+ uint32_t acpi_tables_size, madt_addr, madt_size, rsdt_size;
+ uint16_t i, external_tables;
/* reserve memory space for tables */
#ifdef BX_USE_EBDA_TABLES
@@ -1564,10 +1587,17 @@ void acpi_bios_init(void)
bios_table_cur_addr += sizeof(*rsdp);
#endif
+#ifdef BX_QEMU
+ external_tables = acpi_additional_tables();
+#else
+ external_tables = 0;
+#endif
+
addr = base_addr = ram_size - ACPI_DATA_SIZE;
rsdt_addr = addr;
rsdt = (void *)(addr);
- addr += sizeof(*rsdt);
+ rsdt_size = sizeof(*rsdt) + external_tables * 4;
+ addr += rsdt_size;
fadt_addr = addr;
fadt = (void *)(addr);
@@ -1606,12 +1636,6 @@ void acpi_bios_init(void)
addr += sizeof(*hpet);
#endif
- acpi_tables_size = addr - base_addr;
-
- BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n",
- (unsigned long)rsdp,
- (unsigned long)rsdt, acpi_tables_size);
-
/* RSDP */
memset(rsdp, 0, sizeof(*rsdp));
memcpy(rsdp->signature, "RSD PTR ", 8);
@@ -1623,17 +1647,6 @@ void acpi_bios_init(void)
rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr);
rsdp->checksum = acpi_checksum((void *)rsdp, 20);
- /* RSDT */
- memset(rsdt, 0, sizeof(*rsdt));
- rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);
- rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);
- rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr);
-#ifdef BX_QEMU
- rsdt->table_offset_entry[3] = cpu_to_le32(hpet_addr);
-#endif
- acpi_build_table_header((struct acpi_table_header *)rsdt,
- "RSDT", sizeof(*rsdt), 1);
-
/* FADT */
memset(fadt, 0, sizeof(*fadt));
fadt->firmware_ctrl = cpu_to_le32(facs_addr);
@@ -1710,6 +1723,7 @@ void acpi_bios_init(void)
"APIC", madt_size, 1);
}
+ memset(rsdt, 0, rsdt_size);
#ifdef BX_QEMU
/* HPET */
memset(hpet, 0, sizeof(*hpet));
@@ -1720,7 +1734,34 @@ void acpi_bios_init(void)
hpet->addr.address = cpu_to_le32(ACPI_HPET_ADDRESS);
acpi_build_table_header((struct acpi_table_header *)hpet,
"HPET", sizeof(*hpet), 1);
+
+ acpi_additional_tables(); /* resets cfg to required entry */
+ for(i = 0; i < external_tables; i++) {
+ uint16_t len;
+ 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);
+ addr += len;
+ if(addr >= ram_size)
+ BX_PANIC("ACPI table overflow\n");
+ }
+#endif
+
+ /* RSDT */
+ rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);
+ rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);
+ rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr);
+#ifdef BX_QEMU
+ rsdt->table_offset_entry[3] = cpu_to_le32(hpet_addr);
#endif
+ acpi_build_table_header((struct acpi_table_header *)rsdt,
+ "RSDT", rsdt_size, 1);
+
+ acpi_tables_size = addr - base_addr;
+
+ BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n",
+ (unsigned long)rsdp,
+ (unsigned long)rsdt, acpi_tables_size);
}
qemu:bios: Load SMBIOS entries and files from qemu (Alex Williamson)
Allow SMBIOS fields to be overridden and entries replaced by those
read from qemu.
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
diff --git a/bios/rombios32.c b/bios/rombios32.c
index 7be4216..1a1ed64 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -441,7 +441,6 @@ uint32_t cpuid_features;
uint32_t cpuid_ext_features;
unsigned long ram_size;
uint64_t ram_end;
-uint8_t bios_uuid[16];
#ifdef BX_USE_EBDA_TABLES
unsigned long ebda_cur_addr;
#endif
@@ -471,6 +470,7 @@ void wrmsr_smp(uint32_t index, uint64_t val)
#define QEMU_CFG_UUID 0x02
#define QEMU_CFG_ARCH_LOCAL 0x8000
#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0)
+#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1)
int qemu_cfg_port;
@@ -519,19 +519,17 @@ static int acpi_load_table(int i, uint32_t addr, uint16_t *len)
qemu_cfg_read((uint8_t*)addr, *len);
return 0;
}
-#endif
-void uuid_probe(void)
+static uint16_t smbios_entries(void)
{
-#ifdef BX_QEMU
- if(qemu_cfg_port) {
- qemu_cfg_select(QEMU_CFG_UUID);
- qemu_cfg_read(bios_uuid, 16);
- return;
- }
-#endif
- memset(bios_uuid, 0, 16);
+ uint16_t cnt;
+
+ qemu_cfg_select(QEMU_CFG_SMBIOS_ENTRIES);
+ qemu_cfg_read((uint8_t*)&cnt, sizeof(cnt));
+
+ return cnt;
}
+#endif
void cpu_probe(void)
{
@@ -1963,21 +1961,105 @@ smbios_entry_point_init(void *start,
ep->intermediate_checksum = -sum;
}
+struct smbios_header {
+ uint16_t length;
+ uint8_t type;
+} __attribute__((__packed__));
+
+struct smbios_field {
+ struct smbios_header header;
+ uint8_t type;
+ uint16_t offset;
+ uint8_t data[];
+} __attribute__((__packed__));
+
+struct smbios_table {
+ struct smbios_header header;
+ uint8_t data[];
+} __attribute__((__packed__));
+
+#define SMBIOS_FIELD_ENTRY 0
+#define SMBIOS_TABLE_ENTRY 1
+
+static size_t
+smbios_load_field(int type, size_t offset, void *addr)
+{
+#ifdef BX_QEMU
+ int i;
+
+ for (i = smbios_entries(); i > 0; i--) {
+ struct smbios_field field;
+
+ qemu_cfg_read((uint8_t *)&field, sizeof(struct smbios_header));
+ field.header.length -= sizeof(struct smbios_header);
+
+ if (field.header.type != SMBIOS_FIELD_ENTRY) {
+ while (field.header.length--)
+ inb(QEMU_CFG_DATA_PORT);
+ continue;
+ }
+
+ qemu_cfg_read((uint8_t *)&field.type,
+ sizeof(field) - sizeof(struct smbios_header));
+ field.header.length -= sizeof(field) - sizeof(struct smbios_header);
+
+ if (field.type != type || field.offset != offset) {
+ while (field.header.length--)
+ inb(QEMU_CFG_DATA_PORT);
+ continue;
+ }
+
+ qemu_cfg_read(addr, field.header.length);
+ return (size_t)field.header.length;
+ }
+#endif
+ return 0;
+}
+
+#define load_str_field_with_default(type, field, def) do { \
+ size = smbios_load_field(type, offsetof(struct smbios_type_##type, \
+ field), end); \
+ if (size > 0) { \
+ end += size; \
+ } else { \
+ memcpy(end, def, sizeof(def)); \
+ end += sizeof(def); \
+ } \
+ p->field = ++str_index; \
+} while (0)
+
+#define load_str_field_or_skip(type, field) do { \
+ size = smbios_load_field(type, offsetof(struct smbios_type_##type, \
+ field), end); \
+ if (size > 0) { \
+ end += size; \
+ p->field = ++str_index; \
+ } else { \
+ p->field = 0; \
+ } \
+} while (0)
+
/* Type 0 -- BIOS Information */
#define RELEASE_DATE_STR "01/01/2007"
static void *
-smbios_type_0_init(void *start)
+smbios_init_type_0(void *start)
{
struct smbios_type_0 *p = (struct smbios_type_0 *)start;
+ char *end = (char *)start + sizeof(struct smbios_type_0);
+ size_t size;
+ int str_index = 0;
p->header.type = 0;
p->header.length = sizeof(struct smbios_type_0);
p->header.handle = 0;
- p->vendor_str = 1;
- p->bios_version_str = 1;
+ load_str_field_with_default(0, vendor_str, BX_APPNAME);
+ load_str_field_with_default(0, bios_version_str, BX_APPNAME);
+
p->bios_starting_address_segment = 0xe800;
- p->bios_release_date_str = 2;
+
+ load_str_field_with_default(0, bios_release_date_str, RELEASE_DATE_STR);
+
p->bios_rom_size = 0; /* FIXME */
memset(p->bios_characteristics, 0, 8);
@@ -1985,50 +2067,66 @@ smbios_type_0_init(void *start)
p->bios_characteristics_extension_bytes[0] = 0;
p->bios_characteristics_extension_bytes[1] = 0;
- p->system_bios_major_release = 1;
- p->system_bios_minor_release = 0;
+ if (!smbios_load_field(0, offsetof(struct smbios_type_0,
+ system_bios_major_release),
+ &p->system_bios_major_release))
+ p->system_bios_major_release = 1;
+
+ if (!smbios_load_field(0, offsetof(struct smbios_type_0,
+ system_bios_minor_release),
+ &p->system_bios_minor_release))
+ p->system_bios_minor_release = 0;
+
p->embedded_controller_major_release = 0xff;
p->embedded_controller_minor_release = 0xff;
- start += sizeof(struct smbios_type_0);
- memcpy((char *)start, BX_APPNAME, sizeof(BX_APPNAME));
- start += sizeof(BX_APPNAME);
- memcpy((char *)start, RELEASE_DATE_STR, sizeof(RELEASE_DATE_STR));
- start += sizeof(RELEASE_DATE_STR);
- *((uint8_t *)start) = 0;
+ *end = 0;
+ end++;
- return start+1;
+ return end;
}
/* Type 1 -- System Information */
static void *
-smbios_type_1_init(void *start)
+smbios_init_type_1(void *start)
{
struct smbios_type_1 *p = (struct smbios_type_1 *)start;
+ char *end = (char *)start + sizeof(struct smbios_type_1);
+ size_t size;
+ int str_index = 0;
+
p->header.type = 1;
p->header.length = sizeof(struct smbios_type_1);
p->header.handle = 0x100;
- p->manufacturer_str = 0;
- p->product_name_str = 0;
- p->version_str = 0;
- p->serial_number_str = 0;
+ load_str_field_or_skip(1, manufacturer_str);
+ load_str_field_or_skip(1, product_name_str);
+ load_str_field_or_skip(1, version_str);
+ load_str_field_or_skip(1, serial_number_str);
- memcpy(p->uuid, bios_uuid, 16);
+ size = smbios_load_field(1, offsetof(struct smbios_type_1,
+ uuid), &p->uuid);
+ if (size == 0)
+ memset(p->uuid, 0, 16);
p->wake_up_type = 0x06; /* power switch */
- p->sku_number_str = 0;
- p->family_str = 0;
- start += sizeof(struct smbios_type_1);
- *((uint16_t *)start) = 0;
+ load_str_field_or_skip(1, sku_number_str);
+ load_str_field_or_skip(1, family_str);
- return start+2;
+ *end = 0;
+ end++;
+ if (!str_index) {
+ *end = 0;
+ end++;
+ }
+
+ return end;
}
/* Type 3 -- System Enclosure */
static void *
-smbios_type_3_init(void *start)
+smbios_init_type_3(void *start)
{
struct smbios_type_3 *p = (struct smbios_type_3 *)start;
@@ -2058,7 +2156,7 @@ smbios_type_3_init(void *start)
/* Type 4 -- Processor Information */
static void *
-smbios_type_4_init(void *start, unsigned int cpu_number)
+smbios_init_type_4(void *start, unsigned int cpu_number)
{
struct smbios_type_4 *p = (struct smbios_type_4 *)start;
@@ -2098,7 +2196,7 @@ smbios_type_4_init(void *start, unsigned int cpu_number)
/* Type 16 -- Physical Memory Array */
static void *
-smbios_type_16_init(void *start, uint32_t memsize, int nr_mem_devs)
+smbios_init_type_16(void *start, uint32_t memsize, int nr_mem_devs)
{
struct smbios_type_16 *p = (struct smbios_type_16*)start;
@@ -2121,7 +2219,7 @@ smbios_type_16_init(void *start, uint32_t memsize, int nr_mem_devs)
/* Type 17 -- Memory Device */
static void *
-smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance)
+smbios_init_type_17(void *start, uint32_t memory_size_mb, int instance)
{
struct smbios_type_17 *p = (struct smbios_type_17 *)start;
@@ -2151,7 +2249,7 @@ smbios_type_17_init(void *start, uint32_t memory_size_mb, int instance)
/* Type 19 -- Memory Array Mapped Address */
static void *
-smbios_type_19_init(void *start, uint32_t memory_size_mb, int instance)
+smbios_init_type_19(void *start, uint32_t memory_size_mb, int instance)
{
struct smbios_type_19 *p = (struct smbios_type_19 *)start;
@@ -2172,7 +2270,7 @@ smbios_type_19_init(void *start, uint32_t memory_size_mb, int instance)
/* Type 20 -- Memory Device Mapped Address */
static void *
-smbios_type_20_init(void *start, uint32_t memory_size_mb, int instance)
+smbios_init_type_20(void *start, uint32_t memory_size_mb, int instance)
{
struct smbios_type_20 *p = (struct smbios_type_20 *)start;
@@ -2196,7 +2294,7 @@ smbios_type_20_init(void *start, uint32_t memory_size_mb, int instance)
/* Type 32 -- System Boot Information */
static void *
-smbios_type_32_init(void *start)
+smbios_init_type_32(void *start)
{
struct smbios_type_32 *p = (struct smbios_type_32 *)start;
@@ -2214,7 +2312,7 @@ smbios_type_32_init(void *start)
/* Type 127 -- End of Table */
static void *
-smbios_type_127_init(void *start)
+smbios_init_type_127(void *start)
{
struct smbios_type_127 *p = (struct smbios_type_127 *)start;
@@ -2228,6 +2326,78 @@ smbios_type_127_init(void *start)
return start + 2;
}
+static int
+smbios_load_external(int type, char **p, unsigned *nr_structs,
+ unsigned *max_struct_size)
+{
+#ifdef BX_QEMU
+ static uint64_t used_bitmap[4] = { 0 };
+ char *start = *p;
+ int i;
+
+ /* Check if we've already reported these tables */
+ if (used_bitmap[(type >> 6) & 0x3] & (1ULL << (type & 0x3f)))
+ return 1;
+
+ /* Don't introduce spurious end markers */
+ if (type == 127)
+ return 0;
+
+ for (i = smbios_entries(); i > 0; i--) {
+ struct smbios_table table;
+ struct smbios_structure_header *header = (void *)*p;
+ int string;
+
+ qemu_cfg_read((uint8_t *)&table, sizeof(struct smbios_header));
+ table.header.length -= sizeof(struct smbios_header);
+
+ if (table.header.type != SMBIOS_TABLE_ENTRY) {
+ while (table.header.length--)
+ inb(QEMU_CFG_DATA_PORT);
+ continue;
+ }
+
+ qemu_cfg_read((uint8_t *)*p, sizeof(struct smbios_structure_header));
+ table.header.length -= sizeof(struct smbios_structure_header);
+
+ if (header->type != type) {
+ while (table.header.length--)
+ inb(QEMU_CFG_DATA_PORT);
+ continue;
+ }
+
+ *p += sizeof(struct smbios_structure_header);
+
+ /* Entries end with a double NULL char, if there's a string at
+ * the end (length is greater than formatted length), the string
+ * terminator provides the first NULL. */
+ string = header->length < table.header.length +
+ sizeof(struct smbios_structure_header);
+
+ /* Read the rest and terminate the entry */
+ qemu_cfg_read((uint8_t *)*p, table.header.length);
+ *p += table.header.length;
+ *((uint8_t*)*p) = 0;
+ (*p)++;
+ if (!string) {
+ *((uint8_t*)*p) = 0;
+ (*p)++;
+ }
+
+ (*nr_structs)++;
+ if (*p - (char *)header > *max_struct_size)
+ *max_struct_size = *p - (char *)header;
+ }
+
+ /* Mark that we've reported on this type */
+ used_bitmap[(type >> 6) & 0x3] |= (1ULL << (type & 0x3f));
+
+ return (start != *p);
+#else /* !BX_QEMU */
+ return 0;
+#endif
+}
+
void smbios_init(void)
{
unsigned cpu_num, nr_structs = 0, max_struct_size = 0;
@@ -2246,34 +2416,39 @@ void smbios_init(void)
p = (char *)start + sizeof(struct smbios_entry_point);
-#define add_struct(fn) do{ \
- q = (fn); \
- nr_structs++; \
- if ((q - p) > max_struct_size) \
- max_struct_size = q - p; \
- p = q; \
-}while (0)
-
- add_struct(smbios_type_0_init(p));
- add_struct(smbios_type_1_init(p));
- add_struct(smbios_type_3_init(p));
+#define add_struct(type, args...) do { \
+ if (!smbios_load_external(type, &p, &nr_structs, &max_struct_size)) { \
+ q = smbios_init_type_##type(args); \
+ nr_structs++; \
+ if ((q - p) > max_struct_size) \
+ max_struct_size = q - p; \
+ p = q; \
+ } \
+} while (0)
+
+ add_struct(0, p);
+ add_struct(1, p);
+ add_struct(3, p);
for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
- add_struct(smbios_type_4_init(p, cpu_num));
+ add_struct(4, p, cpu_num);
/* Each 'memory device' covers up to 16GB of address space. */
nr_mem_devs = (memsize + 0x3fff) >> 14;
- add_struct(smbios_type_16_init(p, memsize, nr_mem_devs));
+ add_struct(16, p, memsize, nr_mem_devs);
for ( i = 0; i < nr_mem_devs; i++ )
{
uint32_t dev_memsize = ((i == (nr_mem_devs - 1))
? (((memsize-1) & 0x3fff)+1) : 0x4000);
- add_struct(smbios_type_17_init(p, dev_memsize, i));
- add_struct(smbios_type_19_init(p, dev_memsize, i));
- add_struct(smbios_type_20_init(p, dev_memsize, i));
+ add_struct(17, p, dev_memsize, i);
+ add_struct(19, p, dev_memsize, i);
+ add_struct(20, p, dev_memsize, i);
}
- add_struct(smbios_type_32_init(p));
- add_struct(smbios_type_127_init(p));
+ add_struct(32, p);
+ /* Add any remaining provided entries before the end marker */
+ for (i = 0; i < 256; i++)
+ smbios_load_external(i, &p, &nr_structs, &max_struct_size);
+ add_struct(127, p);
#undef add_struct
@@ -2380,8 +2555,6 @@ void rombios32_init(uint32_t *s3_resume_vector, uint8_t *shutdown_flag)
mptable_init();
- uuid_probe();
-
smbios_init();
if (acpi_enabled)
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From c09142004a409bf27070939f470c5e0b37595a5a Mon Sep 17 00:00:00 2001
From: Beth Kon <eak@us.ibm.com>
Date: Fri, 19 Jun 2009 14:22:00 -0400
Subject: [PATCH] Fix non-ACPI Timer Interrupt Routing - v3
Replicate ACPI irq0->inti2 override in mp table for non-acpi case.
v1 -> v2 adds comment suggested by Ryan.
v2 -> v3 clarifies comment and corrects entry count
Signed-off-by: Beth Kon <eak@us.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
bios/rombios32.c | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/bios/rombios32.c b/bios/rombios32.c
index 1a1ed64..d789e20 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -1124,7 +1124,11 @@ static void mptable_init(void)
putstr(&q, "0.1 "); /* vendor id */
putle32(&q, 0); /* OEM table ptr */
putle16(&q, 0); /* OEM table size */
+#ifdef BX_QEMU
+ putle16(&q, smp_cpus + 17); /* entry count */
+#else
putle16(&q, smp_cpus + 18); /* entry count */
+#endif
putle32(&q, 0xfee00000); /* local APIC addr */
putle16(&q, 0); /* ext table length */
putb(&q, 0); /* ext table checksum */
@@ -1166,6 +1170,12 @@ static void mptable_init(void)
/* irqs */
for(i = 0; i < 16; i++) {
+#ifdef BX_QEMU
+ /* One entry per ioapic interrupt destination. Destination 2 is covered
+ by irq0->inti2 override (i == 0). Source IRQ 2 is unused */
+ if (i == 2)
+ continue;
+#endif
putb(&q, 3); /* entry type = I/O interrupt */
putb(&q, 0); /* interrupt type = vectored interrupt */
putb(&q, 0); /* flags: po=0, el=0 */
@@ -1173,7 +1183,11 @@ static void mptable_init(void)
putb(&q, 0); /* source bus ID = ISA */
putb(&q, i); /* source bus IRQ */
putb(&q, ioapic_id); /* dest I/O APIC ID */
+#ifdef BX_QEMU
+ putb(&q, i == 0 ? 2 : i); /* dest I/O APIC interrupt in */
+#else
putb(&q, i); /* dest I/O APIC interrupt in */
+#endif
}
/* patch length */
len = q - mp_config_table;
--
1.6.2.5
add SRAT ACPI table support (Andre Przywara)
Take NUMA topology info from the QEMU firmware configuration interface
(number of nodes, node for each (V)CPU and amount of memory) and build
a SRAT table describing this topology for the guest OS. Handles more than
4 GB of RAM by including a hole for 32bit PCI memory mapping.
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
diff --git a/bios/rombios32.c b/bios/rombios32.c
index 49dfd62..d8f6d4e 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -450,6 +450,11 @@ int pm_sci_int;
unsigned long bios_table_cur_addr;
unsigned long bios_table_end_addr;
+static inline uint64_t le64_to_cpu(uint64_t x)
+{
+ return x;
+}
+
void wrmsr_smp(uint32_t index, uint64_t val)
{
static struct { uint32_t ecx, eax, edx; } *p = (void *)SMP_MSR_ADDR;
@@ -468,6 +473,7 @@ void wrmsr_smp(uint32_t index, uint64_t val)
#define QEMU_CFG_SIGNATURE 0x00
#define QEMU_CFG_ID 0x01
#define QEMU_CFG_UUID 0x02
+#define QEMU_CFG_NUMA 0x0D
#define QEMU_CFG_ARCH_LOCAL 0x8000
#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0)
#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1)
@@ -529,6 +535,14 @@ static uint16_t smbios_entries(void)
return cnt;
}
+
+uint64_t qemu_cfg_get64 (void)
+{
+ uint64_t ret;
+
+ qemu_cfg_read((uint8_t*)&ret, 8);
+ return le64_to_cpu(ret);
+}
#endif
void cpu_probe(void)
@@ -1281,7 +1295,7 @@ struct rsdt_descriptor_rev1
{
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
#ifdef BX_QEMU
- uint32_t table_offset_entry [4]; /* Array of pointers to other */
+ uint32_t table_offset_entry [5]; /* Array of pointers to other */
#else
uint32_t table_offset_entry [3]; /* Array of pointers to other */
#endif
@@ -1389,7 +1403,7 @@ struct multiple_apic_table
} __attribute__((__packed__));
-/* Values for Type in APIC_HEADER_DEF */
+/* Values for Type in APIC sub-headers */
#define APIC_PROCESSOR 0
#define APIC_IO 1
@@ -1402,18 +1416,18 @@ struct multiple_apic_table
#define APIC_XRUPT_SOURCE 8
#define APIC_RESERVED 9 /* 9 and greater are reserved */
-/*
- * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
- */
-#define APIC_HEADER_DEF /* Common APIC sub-structure header */\
+#define ACPI_SUB_HEADER_DEF /* Common ACPI sub-structure header */\
uint8_t type; \
uint8_t length;
+/*
+ * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
+ */
/* Sub-structures for MADT */
struct madt_processor_apic
{
- APIC_HEADER_DEF
+ ACPI_SUB_HEADER_DEF
uint8_t processor_id; /* ACPI processor id */
uint8_t local_apic_id; /* Processor's local APIC id */
#if 0
@@ -1424,6 +1438,43 @@ struct madt_processor_apic
#endif
} __attribute__((__packed__));
+/*
+ * SRAT (NUMA topology description) table
+ */
+
+#define SRAT_PROCESSOR 0
+#define SRAT_MEMORY 1
+
+struct system_resource_affinity_table
+{
+ ACPI_TABLE_HEADER_DEF
+ uint32_t reserved1;
+ uint32_t reserved2[2];
+};
+
+struct srat_processor_affinity
+{
+ ACPI_SUB_HEADER_DEF
+ uint8_t proximity_lo;
+ uint8_t local_apic_id;
+ uint32_t flags;
+ uint8_t local_sapic_eid;
+ uint8_t proximity_hi[3];
+ uint32_t reserved;
+};
+
+struct srat_memory_affinity
+{
+ ACPI_SUB_HEADER_DEF
+ uint8_t proximity[4];
+ uint16_t reserved1;
+ uint32_t base_addr_low,base_addr_high;
+ uint32_t length_low,length_high;
+ uint32_t reserved2;
+ uint32_t flags;
+ uint32_t reserved3[2];
+};
+
#ifdef BX_QEMU
/*
* * ACPI 2.0 Generic Address Space definition.
@@ -1452,7 +1503,7 @@ struct acpi_20_hpet {
struct madt_io_apic
{
- APIC_HEADER_DEF
+ ACPI_SUB_HEADER_DEF
uint8_t io_apic_id; /* I/O APIC ID */
uint8_t reserved; /* Reserved - must be zero */
uint32_t address; /* APIC physical address */
@@ -1463,7 +1514,7 @@ struct madt_io_apic
#ifdef BX_QEMU
struct madt_int_override
{
- APIC_HEADER_DEF
+ ACPI_SUB_HEADER_DEF
uint8_t bus; /* Identifies ISA Bus */
uint8_t source; /* Bus-relative interrupt source */
uint32_t gsi; /* GSI that source will signal */
@@ -1567,6 +1618,21 @@ int acpi_build_processor_ssdt(uint8_t *ssdt)
return ssdt_ptr - ssdt;
}
+static void acpi_build_srat_memory(struct srat_memory_affinity *numamem,
+ uint64_t base, uint64_t len, int node, int enabled)
+{
+ numamem->type = SRAT_MEMORY;
+ numamem->length = sizeof(*numamem);
+ memset (numamem->proximity, 0 ,4);
+ numamem->proximity[0] = node;
+ numamem->flags = cpu_to_le32(!!enabled);
+ numamem->base_addr_low = base & 0xFFFFFFFF;
+ numamem->base_addr_high = base >> 32;
+ numamem->length_low = len & 0xFFFFFFFF;
+ numamem->length_high = len >> 32;
+ return;
+}
+
/* base_addr must be a multiple of 4KB */
void acpi_bios_init(void)
{
@@ -1577,12 +1643,15 @@ void acpi_bios_init(void)
struct multiple_apic_table *madt;
uint8_t *dsdt, *ssdt;
#ifdef BX_QEMU
+ struct system_resource_affinity_table *srat;
struct acpi_20_hpet *hpet;
uint32_t hpet_addr;
#endif
uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr, ssdt_addr;
uint32_t acpi_tables_size, madt_addr, madt_size, rsdt_size;
+ uint32_t srat_addr,srat_size;
uint16_t i, external_tables;
+ int nb_numa_nodes;
/* reserve memory space for tables */
#ifdef BX_USE_EBDA_TABLES
@@ -1624,6 +1693,25 @@ 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;
+ srat_size = sizeof(*srat) +
+ sizeof(struct srat_processor_affinity) * smp_cpus +
+ sizeof(struct srat_memory_affinity) * (nb_numa_nodes + 2);
+ srat = (void *)(addr);
+ addr += srat_size;
+ } else {
+ srat_addr = addr;
+ srat = (void*)(addr);
+ srat_size = 0;
+ }
addr = (addr + 7) & ~7;
madt_addr = addr;
@@ -1733,6 +1821,69 @@ void acpi_bios_init(void)
memset(rsdt, 0, rsdt_size);
#ifdef BX_QEMU
+ /* SRAT */
+ if (nb_numa_nodes > 0) {
+ struct srat_processor_affinity *core;
+ struct srat_memory_affinity *numamem;
+ int slots;
+ uint64_t mem_len, mem_base, next_base = 0, curnode;
+
+ qemu_cfg_select(QEMU_CFG_NUMA);
+ qemu_cfg_get64();
+ memset (srat, 0 , srat_size);
+ srat->reserved1=1;
+
+ core = (void*)(srat + 1);
+ for (i = 0; i < smp_cpus; ++i) {
+ core->type = SRAT_PROCESSOR;
+ core->length = sizeof(*core);
+ core->local_apic_id = i;
+ curnode = qemu_cfg_get64();
+ core->proximity_lo = curnode;
+ memset (core->proximity_hi, 0, 3);
+ core->local_sapic_eid = 0;
+ if (i < smp_cpus)
+ core->flags = cpu_to_le32(1);
+ else
+ core->flags = 0;
+ core++;
+ }
+
+ /* the memory map is a bit tricky, it contains at least one hole
+ * from 640k-1M and possibly another one from 3.5G-4G.
+ */
+ numamem = (void*)core; slots = 0;
+ acpi_build_srat_memory(numamem, 0, 640*1024, 0, 1);
+ next_base = 1024 * 1024; numamem++;slots++;
+ for (i = 1; i < nb_numa_nodes + 1; ++i) {
+ mem_base = next_base;
+ mem_len = qemu_cfg_get64();
+ if (i == 1) mem_len -= 1024 * 1024;
+ next_base = mem_base + mem_len;
+
+ /* Cut out the PCI hole */
+ if (mem_base <= ram_size && next_base > ram_size) {
+ mem_len -= next_base - ram_size;
+ if (mem_len > 0) {
+ acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
+ numamem++; slots++;
+ }
+ mem_base = 1ULL << 32;
+ mem_len = next_base - ram_size;
+ next_base += (1ULL << 32) - ram_size;
+ }
+ acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
+ numamem++; slots++;
+ }
+ for (; slots < nb_numa_nodes + 2; slots++) {
+ acpi_build_srat_memory(numamem, 0, 0, 0, 0);
+ numamem++;
+ }
+
+ acpi_build_table_header((struct acpi_table_header *)srat,
+ "SRAT", srat_size, 1);
+ }
+
/* HPET */
memset(hpet, 0, sizeof(*hpet));
/* Note timer_block_id value must be kept in sync with value advertised by
@@ -1761,9 +1912,11 @@ 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, 1);
+ acpi_build_table_header((struct acpi_table_header *)rsdt, "RSDT",
+ rsdt_size - (nb_numa_nodes > 0? 0: sizeof(uint32_t)), 1);
acpi_tables_size = addr - base_addr;
--
1.6.1.3
Enable power button event generation.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
diff --git a/bios/rombios32.c b/bios/rombios32.c
index 81e3bad..9986531 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -1767,8 +1767,8 @@ void acpi_bios_init(void)
fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported
fadt->gpe0_blk = cpu_to_le32(0xafe0);
fadt->gpe0_blk_len = 4;
- /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */
- fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6));
+ /* WBINVD + PROC_C1 + SLP_BUTTON + FIX_RTC */
+ fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 6));
acpi_build_table_header((struct acpi_table_header *)fadt, "FACP",
sizeof(*fadt), 1);
Subject: [PATCH] bios: Use the correct mask to size the PCI option ROM BAR
From: Alex Williamson <alex.williamson@hp.com>
Bit 0 is the enable bit, which we not only don't want to set, but
it will stick and make us think it's an I/O port resource.
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
diff --git a/bios/rombios32.c b/bios/rombios32.c
index d7e18e9..f861f81 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -985,11 +985,13 @@ static void pci_bios_init_device(PCIDevice *d)
int ofs;
uint32_t val, size ;
- if (i == PCI_ROM_SLOT)
+ if (i == PCI_ROM_SLOT) {
ofs = 0x30;
- else
+ pci_config_writel(d, ofs, 0xfffffffe);
+ } else {
ofs = 0x10 + i * 4;
- pci_config_writel(d, ofs, 0xffffffff);
+ pci_config_writel(d, ofs, 0xffffffff);
+ }
val = pci_config_readl(d, ofs);
if (val != 0) {
size = (~(val & ~0xf)) + 1;
From f371c480cb93f3516f34af5e3a4524ee6ba43c24 Mon Sep 17 00:00:00 2001
From: Jan Kiszka <jan.kiszka@web.de>
Date: Thu, 2 Jul 2009 00:11:38 +0200
Subject: [PATCH 1/2] bochs-bios: Move QEMU_CFG constants to rombios.h
We will need them outside of rombios32.c.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
bios/rombios.h | 10 ++++++++++
bios/rombios32.c | 10 ----------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/bios/rombios.h b/bios/rombios.h
index 6f9cbb1..59ce19d 100644
--- a/bios/rombios.h
+++ b/bios/rombios.h
@@ -58,6 +58,16 @@
#define SMB_IO_BASE 0xb100
#define SMP_MSR_ADDR 0x0510
+#define QEMU_CFG_CTL_PORT 0x510
+#define QEMU_CFG_DATA_PORT 0x511
+#define QEMU_CFG_SIGNATURE 0x00
+#define QEMU_CFG_ID 0x01
+#define QEMU_CFG_UUID 0x02
+#define QEMU_CFG_NUMA 0x0d
+#define QEMU_CFG_ARCH_LOCAL 0x8000
+#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0)
+#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1)
+
// Define the application NAME
#if defined(BX_QEMU)
# define BX_APPNAME "QEMU"
diff --git a/bios/rombios32.c b/bios/rombios32.c
index f861f81..3fe4e48 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -468,16 +468,6 @@ void wrmsr_smp(uint32_t index, uint64_t val)
}
#ifdef BX_QEMU
-#define QEMU_CFG_CTL_PORT 0x510
-#define QEMU_CFG_DATA_PORT 0x511
-#define QEMU_CFG_SIGNATURE 0x00
-#define QEMU_CFG_ID 0x01
-#define QEMU_CFG_UUID 0x02
-#define QEMU_CFG_NUMA 0x0D
-#define QEMU_CFG_ARCH_LOCAL 0x8000
-#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0)
-#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1)
-
int qemu_cfg_port;
void qemu_cfg_select(int f)
--
1.6.2.5
From fff8ffe1c92474ee58ebd6da82fede0ab7929214 Mon Sep 17 00:00:00 2001
From: Jan Kiszka <jan.kiszka@web.de>
Date: Thu, 2 Jul 2009 00:11:44 +0200
Subject: [PATCH 2/2] bochs-bios: Make boot prompt optional
Check via QEMU's firmware configuration interface if the boot prompt
should be given. This allows to disable the prompt with its several
seconds long delay, speeding up the common boot case.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
bios/rombios.c | 19 +++++++++++++++++++
bios/rombios.h | 1 +
2 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/bios/rombios.c b/bios/rombios.c
index 0f13b53..560e6d5 100644
--- a/bios/rombios.c
+++ b/bios/rombios.c
@@ -2015,6 +2015,21 @@ Bit16u i; ipl_entry_t *e;
}
#if BX_ELTORITO_BOOT
+#ifdef BX_QEMU
+int
+qemu_cfg_probe_bootkey()
+{
+ outw(QEMU_CFG_CTL_PORT, QEMU_CFG_SIGNATURE);
+ if (inb(QEMU_CFG_DATA_PORT) != 'Q' ||
+ inb(QEMU_CFG_DATA_PORT) != 'E' ||
+ inb(QEMU_CFG_DATA_PORT) != 'M' ||
+ inb(QEMU_CFG_DATA_PORT) != 'U') return 1;
+
+ outw(QEMU_CFG_CTL_PORT, QEMU_CFG_BOOT_MENU);
+ return inb(QEMU_CFG_DATA_PORT);
+}
+#endif // BX_QEMU
+
void
interactive_bootkey()
{
@@ -2026,6 +2041,10 @@ interactive_bootkey()
Bit16u ss = get_SS();
Bit16u valid_choice = 0;
+#ifdef BX_QEMU
+ if (!qemu_cfg_probe_bootkey()) return;
+#endif
+
while (check_for_keystroke())
get_keystroke();
diff --git a/bios/rombios.h b/bios/rombios.h
index 59ce19d..8ece2ee 100644
--- a/bios/rombios.h
+++ b/bios/rombios.h
@@ -64,6 +64,7 @@
#define QEMU_CFG_ID 0x01
#define QEMU_CFG_UUID 0x02
#define QEMU_CFG_NUMA 0x0d
+#define QEMU_CFG_BOOT_MENU 0x0e
#define QEMU_CFG_ARCH_LOCAL 0x8000
#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0)
#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1)
--
1.6.2.5
bios: Fix multiple calls into smbios_load_ex
We're marking the used entry bitmap in smbios_load_external() for each
type we check, regardless of whether we loaded anything. This makes
subsequent calls behave as if we've already loaded the tables from qemu
and can result in missing tables (ex. multiple type4 entries on an SMP
guest). Only mark the bitmap if we actually load something.
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
diff --git a/bios/rombios32.c b/bios/rombios32.c
index f861f81..c869798 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -2554,13 +2554,14 @@ smbios_load_external(int type, char **p, unsigned *nr_structs,
*max_struct_size = *p - (char *)header;
}
- /* Mark that we've reported on this type */
- used_bitmap[(type >> 6) & 0x3] |= (1ULL << (type & 0x3f));
+ if (start != *p) {
+ /* Mark that we've reported on this type */
+ used_bitmap[(type >> 6) & 0x3] |= (1ULL << (type & 0x3f));
+ return 1;
+ }
- return (start != *p);
-#else /* !BX_QEMU */
+#endif /* !BX_QEMU */
return 0;
-#endif
}
void smbios_init(void)
Read max_cpus variable from QEMU_CFG. If not provided, use value of
smp_cpus.
Signed-off-by: Jes Sorensen <jes@sgi.com>
diff --git a/bios/rombios.h b/bios/rombios.h
index 8ece2ee..dbf3bd3 100644
--- a/bios/rombios.h
+++ b/bios/rombios.h
@@ -65,6 +65,7 @@
#define QEMU_CFG_UUID 0x02
#define QEMU_CFG_NUMA 0x0d
#define QEMU_CFG_BOOT_MENU 0x0e
+#define QEMU_CFG_MAX_CPUS 0x0f
#define QEMU_CFG_ARCH_LOCAL 0x8000
#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0)
#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1)
diff --git a/bios/rombios32.c b/bios/rombios32.c
index 69e82b1..610fc1f 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -436,6 +436,7 @@ void delay_ms(int n)
}
uint16_t smp_cpus;
+uint16_t max_cpus;
uint32_t cpuid_signature;
uint32_t cpuid_features;
uint32_t cpuid_ext_features;
@@ -526,6 +527,19 @@ static uint16_t smbios_entries(void)
return cnt;
}
+static uint16_t get_max_cpus(void)
+{
+ uint16_t cnt;
+
+ qemu_cfg_select(QEMU_CFG_MAX_CPUS);
+ qemu_cfg_read((uint8_t*)&cnt, sizeof(cnt));
+
+ if (!cnt)
+ cnt = smp_cpus;
+
+ return cnt;
+}
+
uint64_t qemu_cfg_get64 (void)
{
uint64_t ret;
@@ -2689,6 +2703,12 @@ void rombios32_init(uint32_t *s3_resume_vector, uint8_t *shutdown_flag)
smp_probe();
+#ifdef BX_QEMU
+ max_cpus = get_max_cpus();
+#else
+ max_cpus = smp_cpus;
+#endif
+
find_bios_table_area();
if (*shutdown_flag == 0xfe) {
Use max_cpus when building bios tables.
Signed-off-by: Jes Sorensen <jes@sgi.com>
diff --git a/bios/rombios32.c b/bios/rombios32.c
index e6bb164..3d15283 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -1145,23 +1145,25 @@ static void mptable_init(void)
putle32(&q, 0); /* OEM table ptr */
putle16(&q, 0); /* OEM table size */
#ifdef BX_QEMU
- putle16(&q, smp_cpus + 17); /* entry count */
+ putle16(&q, max_cpus + 17); /* entry count */
#else
- putle16(&q, smp_cpus + 18); /* entry count */
+ putle16(&q, max_cpus + 18); /* entry count */
#endif
putle32(&q, 0xfee00000); /* local APIC addr */
putle16(&q, 0); /* ext table length */
putb(&q, 0); /* ext table checksum */
putb(&q, 0); /* reserved */
- for(i = 0; i < smp_cpus; i++) {
+ for(i = 0; i < max_cpus; i++) {
putb(&q, 0); /* entry type = processor */
putb(&q, i); /* APIC id */
putb(&q, 0x11); /* local APIC version number */
if (i == 0)
putb(&q, 3); /* cpu flags: enabled, bootstrap cpu */
- else
+ else if (i < smp_cpus)
putb(&q, 1); /* cpu flags: enabled */
+ else
+ putb(&q, 0); /* cpu flags: disabled */
putb(&q, 0); /* cpu signature */
putb(&q, 6);
putb(&q, 0);
@@ -1181,7 +1183,7 @@ static void mptable_init(void)
putstr(&q, "ISA ");
/* ioapic */
- ioapic_id = smp_cpus;
+ ioapic_id = max_cpus;
putb(&q, 2); /* entry type = I/O APIC */
putb(&q, ioapic_id); /* apic ID */
putb(&q, 0x11); /* I/O APIC version number */
@@ -1581,7 +1583,7 @@ int acpi_build_processor_ssdt(uint8_t *ssdt)
{
uint8_t *ssdt_ptr = ssdt;
int i, length;
- int acpi_cpus = smp_cpus > 0xff ? 0xff : smp_cpus;
+ int acpi_cpus = max_cpus > 0xff ? 0xff : max_cpus;
ssdt_ptr[9] = 0; // checksum;
ssdt_ptr += sizeof(struct acpi_table_header);
@@ -1713,7 +1715,7 @@ void acpi_bios_init(void)
addr = (addr + 7) & ~7;
srat_addr = addr;
srat_size = sizeof(*srat) +
- sizeof(struct srat_processor_affinity) * smp_cpus +
+ sizeof(struct srat_processor_affinity) * max_cpus +
sizeof(struct srat_memory_affinity) * (nb_numa_nodes + 2);
srat = (void *)(addr);
addr += srat_size;
@@ -1726,7 +1728,7 @@ void acpi_bios_init(void)
addr = (addr + 7) & ~7;
madt_addr = addr;
madt_size = sizeof(*madt) +
- sizeof(struct madt_processor_apic) * smp_cpus +
+ sizeof(struct madt_processor_apic) * max_cpus +
#ifdef BX_QEMU
sizeof(struct madt_io_apic) + sizeof(struct madt_int_override);
#else
@@ -1799,18 +1801,21 @@ void acpi_bios_init(void)
madt->local_apic_address = cpu_to_le32(0xfee00000);
madt->flags = cpu_to_le32(1);
apic = (void *)(madt + 1);
- for(i=0;i<smp_cpus;i++) {
+ for(i = 0;i < max_cpus; i++) {
apic->type = APIC_PROCESSOR;
apic->length = sizeof(*apic);
apic->processor_id = i;
apic->local_apic_id = i;
- apic->flags = cpu_to_le32(1);
+ if (i < smp_cpus)
+ apic->flags = cpu_to_le32(1);
+ else
+ apic->flags = 0;
apic++;
}
io_apic = (void *)apic;
io_apic->type = APIC_IO;
io_apic->length = sizeof(*io_apic);
- io_apic->io_apic_id = smp_cpus;
+ io_apic->io_apic_id = max_cpus;
io_apic->address = cpu_to_le32(0xfec00000);
io_apic->interrupt = cpu_to_le32(0);
#ifdef BX_QEMU
@@ -1844,7 +1849,7 @@ void acpi_bios_init(void)
srat->reserved1=1;
core = (void*)(srat + 1);
- for (i = 0; i < smp_cpus; ++i) {
+ for (i = 0; i < max_cpus; ++i) {
core->type = SRAT_PROCESSOR;
core->length = sizeof(*core);
core->local_apic_id = i;
@@ -2603,7 +2608,7 @@ void smbios_init(void)
add_struct(0, p);
add_struct(1, p);
add_struct(3, p);
- for (cpu_num = 1; cpu_num <= smp_cpus; cpu_num++)
+ for (cpu_num = 1; cpu_num <= max_cpus; cpu_num++)
add_struct(4, p, cpu_num);
/* Each 'memory device' covers up to 16GB of address space. */
04387139e3b5ac97b5633cd40b3d87cdf45efd6c
0001_bx-qemu.patch
0002_kvm-bios-update-smbios-table-to-report-memory-above-4g.patch
0003_kvm-bios-generate-mptable-unconditionally.patch
0004_kvm-bios-resolve-memory-device-roll-over-reporting--issues-with-32g-guests.patch
0005_kvm-bios-fix-smbios-memory-device-length-boundary--condition.patch
0006_qemu-bios-use-preprocessor-for-pci-link-routing.patch
0007_bios-add-26-pci-slots,-bringing-the-total-to-32.patch
0008_qemu-bios-provide-gpe-_l0x-methods.patch
0009_qemu-bios-pci-hotplug-support.patch
0010_bios-mark-the-acpi-sci-interrupt-as-connected-to-irq-9.patch
0011_read-additional-acpi-tables-from-a-vm.patch
0012-load-smbios-entries-and-files-from-qemu.patch
0013_fix-non-acpi-timer-interrupt-routing.patch
0014_add-srat-acpi-table-support.patch
0015_enable-power-button-even-generation.patch
0016-use-correct-mask-to-size-pci-option-rom-bar.patch
0017-bochs-bios-Move-QEMU_CFG-constants-to-rombios.h.patch
0018-bochs-bios-Make-boot-prompt-optional.patch
0019-bios-fix-multiple-calls.patch
0020-qemu-kvm-cfg-maxcpus.patch
0021-qemu-madt-maxcpus.patch
86ccbd96bf82d046d219141ac56cd4b26256889b
Subproject commit c658541caaec566c58a8afccc1ed8b56e0e0fbd9
Subproject commit 5c3f5dde217f382b02350973a38f50941904473d
Subproject commit 6e62666cfc19e7fd45dd0d7c3ad62fd8d0b5f67a
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册