qemu: 2.1+ smbios tables support
Starting with version 2.1 qemu provides a full set of smbios tables for the virtual hardware emulated, except type 0 (bios information). This patch adds support for loading those tables to coreboot. The code is used by both i440fx and q35. Change-Id: Id034f0c214e8890194145a92f06354201dee7963 Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-on: http://review.coreboot.org/8608 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
f14bd79ae1
commit
db9d169ddb
|
@ -362,6 +362,89 @@ static void fw_cfg_smbios_init(void)
|
|||
}
|
||||
}
|
||||
|
||||
static unsigned long smbios_next(unsigned long current)
|
||||
{
|
||||
struct smbios_type0 *t0;
|
||||
int l, count = 0;
|
||||
char *s;
|
||||
|
||||
t0 = (void*)current;
|
||||
current += t0->length;
|
||||
for (;;) {
|
||||
s = (void*)current;
|
||||
l = strlen(s);
|
||||
if (!l)
|
||||
return current + (count ? 1 : 2);
|
||||
current += l + 1;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Starting with version 2.1 qemu provides a full set of smbios tables
|
||||
* for the virtual hardware emulated, except type 0 (bios information).
|
||||
*
|
||||
* What we are going to do here is find the type0 table, keep it, and
|
||||
* override everything else generated by coreboot with the qemu smbios
|
||||
* tables.
|
||||
*
|
||||
* It's a bit hackish, but qemu is a special case (compared to real
|
||||
* hardware) and this way we don't need special qemu support in the
|
||||
* generic smbios code.
|
||||
*/
|
||||
unsigned long fw_cfg_smbios_tables(int *handle, unsigned long *current)
|
||||
{
|
||||
struct smbios_type0 *t0;
|
||||
unsigned long start, end;
|
||||
int len, ret, i, count = 1;
|
||||
char *str;
|
||||
|
||||
len = fw_cfg_check_file("etc/smbios/smbios-tables");
|
||||
if (len < 0)
|
||||
return 0;
|
||||
printk(BIOS_DEBUG, "QEMU: found smbios tables in fw_cfg (len %d).\n", len);
|
||||
|
||||
/*
|
||||
* Search backwards for "coreboot" (first string in type0 table,
|
||||
* see src/arch/x86/boot/smbios.c), then find type0 table.
|
||||
*/
|
||||
for (i = 0; i < 16384; i++) {
|
||||
str = (char*)(*current - i);
|
||||
if (strcmp(str, "coreboot") == 0)
|
||||
break;
|
||||
}
|
||||
if (i == 16384)
|
||||
return 0;
|
||||
i += sizeof(struct smbios_type0) - 2;
|
||||
t0 = (struct smbios_type0*)(*current - i);
|
||||
if (t0->type != SMBIOS_BIOS_INFORMATION || t0->handle != 0)
|
||||
return 0;
|
||||
printk(BIOS_DEBUG, "QEMU: coreboot type0 table found at 0x%lx.\n",
|
||||
*current - i);
|
||||
start = smbios_next(*current - i);
|
||||
|
||||
/*
|
||||
* Fetch smbios tables from qemu, go find the end marker.
|
||||
* We'll exclude the end marker as coreboot will add one.
|
||||
*/
|
||||
printk(BIOS_DEBUG, "QEMU: loading smbios tables to 0x%lx\n", start);
|
||||
fw_cfg_load_file("etc/smbios/smbios-tables", (void*)start);
|
||||
end = start;
|
||||
do {
|
||||
t0 = (struct smbios_type0*)end;
|
||||
if (t0->type == SMBIOS_END_OF_TABLE)
|
||||
break;
|
||||
end = smbios_next(end);
|
||||
count++;
|
||||
} while (end < start + len);
|
||||
|
||||
/* final fixups. */
|
||||
ret = end - *current;
|
||||
*current = end;
|
||||
*handle = count;
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *smbios_mainboard_manufacturer(void)
|
||||
{
|
||||
fw_cfg_smbios_init();
|
||||
|
|
|
@ -19,3 +19,4 @@ void fw_cfg_get(int entry, void *dst, int dstlen);
|
|||
int fw_cfg_check_file(const char *name);
|
||||
void fw_cfg_load_file(const char *name, void *dst);
|
||||
int fw_cfg_max_cpus(void);
|
||||
unsigned long fw_cfg_smbios_tables(int *handle, unsigned long *current);
|
||||
|
|
|
@ -213,6 +213,11 @@ static int qemu_get_smbios_data17(int handle, int parent_handle, unsigned long *
|
|||
static int qemu_get_smbios_data(device_t dev, int *handle, unsigned long *current)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = fw_cfg_smbios_tables(handle, current);
|
||||
if (len != 0)
|
||||
return len;
|
||||
|
||||
len = qemu_get_smbios_data16(*handle, current);
|
||||
len += qemu_get_smbios_data17(*handle+1, *handle, current);
|
||||
*handle += 2;
|
||||
|
|
Loading…
Reference in New Issue