Convert fw_cfg SMBIOS entries into romfile entries.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
diff --git a/src/paravirt.c b/src/paravirt.c
index f17930f..e782227 100644
--- a/src/paravirt.c
+++ b/src/paravirt.c
@@ -12,7 +12,7 @@
#include "byteorder.h" // be32_to_cpu
#include "ioport.h" // outw
#include "paravirt.h" // qemu_cfg_preinit
-#include "smbios.h" // struct smbios_structure_header
+#include "smbios.h" // smbios_setup
#include "memmap.h" // add_e820
#include "cmos.h" // CMOS_*
#include "acpi.h" // acpi_setup
@@ -203,18 +203,6 @@
return v;
}
-u16 qemu_cfg_smbios_entries(void)
-{
- u16 cnt;
-
- if (!qemu_cfg_present)
- return 0;
-
- qemu_cfg_read_entry(&cnt, QEMU_CFG_SMBIOS_ENTRIES, sizeof(cnt));
-
- return cnt;
-}
-
u32 qemu_cfg_e820_entries(void)
{
u32 cnt;
@@ -232,134 +220,6 @@
return addr;
}
-struct smbios_header {
- u16 length;
- u8 type;
-} PACKED;
-
-struct smbios_field {
- struct smbios_header header;
- u8 type;
- u16 offset;
- u8 data[];
-} PACKED;
-
-struct smbios_table {
- struct smbios_header header;
- u8 data[];
-} PACKED;
-
-#define SMBIOS_FIELD_ENTRY 0
-#define SMBIOS_TABLE_ENTRY 1
-
-size_t qemu_cfg_smbios_load_field(int type, size_t offset, void *addr)
-{
- int i;
-
- for (i = qemu_cfg_smbios_entries(); i > 0; i--) {
- struct smbios_field field;
-
- qemu_cfg_read((u8 *)&field, sizeof(struct smbios_header));
- field.header.length -= sizeof(struct smbios_header);
-
- if (field.header.type != SMBIOS_FIELD_ENTRY) {
- qemu_cfg_skip(field.header.length);
- continue;
- }
-
- qemu_cfg_read((u8 *)&field.type,
- sizeof(field) - sizeof(struct smbios_header));
- field.header.length -= sizeof(field) - sizeof(struct smbios_header);
-
- if (field.type != type || field.offset != offset) {
- qemu_cfg_skip(field.header.length);
- continue;
- }
-
- qemu_cfg_read(addr, field.header.length);
- return (size_t)field.header.length;
- }
- return 0;
-}
-
-int qemu_cfg_smbios_load_external(int type, char **p, unsigned *nr_structs,
- unsigned *max_struct_size, char *end)
-{
- static u64 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 = qemu_cfg_smbios_entries(); i > 0; i--) {
- struct smbios_table table;
- struct smbios_structure_header *header = (void *)*p;
- int string;
-
- qemu_cfg_read((u8 *)&table, sizeof(struct smbios_header));
- table.header.length -= sizeof(struct smbios_header);
-
- if (table.header.type != SMBIOS_TABLE_ENTRY) {
- qemu_cfg_skip(table.header.length);
- continue;
- }
-
- if (end - *p < sizeof(struct smbios_structure_header)) {
- warn_noalloc();
- break;
- }
-
- qemu_cfg_read((u8 *)*p, sizeof(struct smbios_structure_header));
- table.header.length -= sizeof(struct smbios_structure_header);
-
- if (header->type != type) {
- qemu_cfg_skip(table.header.length);
- 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 */
- if (end - *p < table.header.length) {
- warn_noalloc();
- *p -= sizeof(struct smbios_structure_header);
- continue;
- }
- qemu_cfg_read((u8 *)*p, table.header.length);
- *p += table.header.length;
- *((u8*)*p) = 0;
- (*p)++;
- if (!string) {
- *((u8*)*p) = 0;
- (*p)++;
- }
-
- (*nr_structs)++;
- if (*p - (char *)header > *max_struct_size)
- *max_struct_size = *p - (char *)header;
- }
-
- if (start != *p) {
- /* Mark that we've reported on this type */
- used_bitmap[(type >> 6) & 0x3] |= (1ULL << (type & 0x3f));
- return 1;
- }
-
- return 0;
-}
-
int qemu_cfg_get_numa_nodes(void)
{
u64 cnt;
@@ -417,6 +277,16 @@
romfile_add(file);
}
+#define SMBIOS_FIELD_ENTRY 0
+#define SMBIOS_TABLE_ENTRY 1
+
+struct qemu_smbios_header {
+ u16 length;
+ u8 headertype;
+ u8 tabletype;
+ u16 fieldoffset;
+} PACKED;
+
// Populate romfile entries for legacy fw_cfg ports (that predate the
// "file" interface).
static void
@@ -436,6 +306,28 @@
qemu_cfg_skip(len);
offset += len;
}
+
+ // SMBIOS info
+ qemu_cfg_read_entry(&cnt, QEMU_CFG_SMBIOS_ENTRIES, sizeof(cnt));
+ offset = sizeof(cnt);
+ for (i = 0; i < cnt; i++) {
+ struct qemu_smbios_header header;
+ qemu_cfg_read(&header, sizeof(header));
+ if (header.headertype == SMBIOS_FIELD_ENTRY) {
+ snprintf(name, sizeof(name), "smbios/field%d-%d"
+ , header.tabletype, header.fieldoffset);
+ qemu_romfile_add(name, QEMU_CFG_SMBIOS_ENTRIES
+ , offset + sizeof(header)
+ , header.length - sizeof(header));
+ } else {
+ snprintf(name, sizeof(name), "smbios/table%d-%d"
+ , header.tabletype, i);
+ qemu_romfile_add(name, QEMU_CFG_SMBIOS_ENTRIES
+ , offset + 3, header.length - 3);
+ }
+ qemu_cfg_skip(header.length - sizeof(header));
+ offset += header.length;
+ }
}
struct QemuCfgFile {