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)
|
const char *smbios_mainboard_manufacturer(void)
|
||||||
{
|
{
|
||||||
fw_cfg_smbios_init();
|
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);
|
int fw_cfg_check_file(const char *name);
|
||||||
void fw_cfg_load_file(const char *name, void *dst);
|
void fw_cfg_load_file(const char *name, void *dst);
|
||||||
int fw_cfg_max_cpus(void);
|
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)
|
static int qemu_get_smbios_data(device_t dev, int *handle, unsigned long *current)
|
||||||
{
|
{
|
||||||
int len;
|
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_data16(*handle, current);
|
||||||
len += qemu_get_smbios_data17(*handle+1, *handle, current);
|
len += qemu_get_smbios_data17(*handle+1, *handle, current);
|
||||||
*handle += 2;
|
*handle += 2;
|
||||||
|
|
Loading…
Reference in New Issue