Build type 19 (memory array mapped address, a.k.a. memory area) tables by scanning the e820 map for E820_RAM entries. Since this supercedes below_4g and above_4g ram amounts, we no longer need them as arguments to smbios_set_defaults().
Signed-off-by: Gabriel Somlo somlo@cmu.edu --- hw/i386/pc.c | 15 +++++++++++++++ hw/i386/pc_piix.c | 3 +-- hw/i386/pc_q35.c | 3 +-- hw/i386/smbios.c | 23 +++++++++++------------ include/hw/i386/pc.h | 2 ++ include/hw/i386/smbios.h | 4 +--- 6 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c index b3c7cc2..8d54489 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -612,6 +612,21 @@ int e820_add_entry(uint64_t address, uint64_t length, uint32_t type) return e820_entries; }
+int e820_get_num_entries(void) +{ + return e820_entries; +} + +bool e820_get_entry(int idx, uint32_t type, uint64_t *address, uint64_t *length) +{ + if (idx < e820_entries && e820_table[idx].type == cpu_to_le32(type)) { + *address = le64_to_cpu(e820_table[idx].address); + *length = le64_to_cpu(e820_table[idx].length); + return true; + } + return false; +} + /* Calculates the limit to CPU APIC ID values * * This function returns the limit for the APIC ID value, so that all diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index db075eb..ba854eb 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -146,8 +146,7 @@ static void pc_init1(QEMUMachineInitArgs *args, if (smbios_defaults) { /* These values are guest ABI, do not change */ smbios_set_defaults("QEMU", "Standard PC (i440FX + PIIX, 1996)", - args->machine->name, - below_4g_mem_size, above_4g_mem_size); + args->machine->name); }
/* allocate ram and load rom/bios */ diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 3aaac7a..6d503ac 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -133,8 +133,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args) if (smbios_defaults) { /* These values are guest ABI, do not change */ smbios_set_defaults("QEMU", "Standard PC (Q35 + ICH9, 2009)", - args->machine->name, - below_4g_mem_size, above_4g_mem_size); + args->machine->name); }
/* allocate ram and load rom/bios */ diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c index f6fbb69..eb11095 100644 --- a/hw/i386/smbios.c +++ b/hw/i386/smbios.c @@ -18,6 +18,7 @@ #include "qemu/config-file.h" #include "qemu/error-report.h" #include "sysemu/sysemu.h" +#include "hw/i386/pc.h" #include "hw/i386/smbios.h" #include "hw/loader.h"
@@ -31,7 +32,6 @@ static int smbios_type4_count = 0; static bool smbios_immutable; static bool smbios_have_defaults; static uint32_t smbios_cpuid_version, smbios_cpuid_features; /* for type 4 */ -static ram_addr_t smbios_below_4g_ram, smbios_above_4g_ram; /* for type 19 */
static DECLARE_BITMAP(have_binfile_bitmap, SMBIOS_MAX_TYPE+1); static DECLARE_BITMAP(have_fields_bitmap, SMBIOS_MAX_TYPE+1); @@ -591,16 +591,10 @@ void smbios_set_cpuid(uint32_t version, uint32_t features) }
void smbios_set_defaults(const char *manufacturer, - const char *product, const char *version, - ram_addr_t below_4g_mem_size, - ram_addr_t above_4g_mem_size) + const char *product, const char *version) { smbios_have_defaults = true;
- assert(ram_size == below_4g_mem_size + above_4g_mem_size); - smbios_below_4g_ram = below_4g_mem_size; - smbios_above_4g_ram = above_4g_mem_size; - SMBIOS_SET_DEFAULT(type0.vendor, manufacturer); SMBIOS_SET_DEFAULT(type0.version, version); SMBIOS_SET_DEFAULT(type0.date, "01/01/2014"); @@ -645,7 +639,7 @@ static void smbios_entry_point_setup(void) void smbios_get_tables(uint8_t **tables, size_t *tables_len, uint8_t **anchor, size_t *anchor_len) { - unsigned i, dimm_cnt; + unsigned i, dimm_cnt, instance;
if (!smbios_immutable) { smbios_build_type_0_table(); @@ -660,13 +654,18 @@ void smbios_get_tables(uint8_t **tables, size_t *tables_len, #define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ : ram_size % MAX_DIMM_SZ)
dimm_cnt = QEMU_ALIGN_UP(ram_size, MAX_DIMM_SZ) / MAX_DIMM_SZ; + smbios_build_type_16_table(dimm_cnt); + for (i = 0; i < dimm_cnt; i++) { smbios_build_type_17_table(i, GET_DIMM_SZ); } - smbios_build_type_19_table(0, 0, smbios_below_4g_ram); - if (smbios_above_4g_ram) { - smbios_build_type_19_table(1, 4 * ONE_GB, smbios_above_4g_ram); + + for (i = 0, instance = 0; i < e820_get_num_entries(); i++) { + ram_addr_t address, length; + if (e820_get_entry(i, E820_RAM, &address, &length)) { + smbios_build_type_19_table(instance++, address, length); + } }
smbios_build_type_32_table(); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 9010246..9f26e14 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -239,6 +239,8 @@ uint16_t pvpanic_port(void); #define E820_UNUSABLE 5
int e820_add_entry(uint64_t, uint64_t, uint32_t); +int e820_get_num_entries(void); +bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
#define PC_Q35_COMPAT_1_7 \ PC_COMPAT_1_7, \ diff --git a/include/hw/i386/smbios.h b/include/hw/i386/smbios.h index 83a3604..6be0445 100644 --- a/include/hw/i386/smbios.h +++ b/include/hw/i386/smbios.h @@ -20,9 +20,7 @@ void smbios_entry_add(QemuOpts *opts); void smbios_set_cpuid(uint32_t version, uint32_t features); void smbios_set_defaults(const char *manufacturer, - const char *product, const char *version, - ram_addr_t below_4g_mem_size, - ram_addr_t above_4g_mem_size); + const char *product, const char *version); void smbios_get_tables(uint8_t **tables, size_t *tables_len, uint8_t **anchor, size_t *anchor_len);