[SeaBIOS] [QEMU v6 PATCH 14/17] SMBIOS: Use e820 memory map to generate type 19 tables
Gabriel L. Somlo
gsomlo at gmail.com
Mon Apr 14 22:55:08 CEST 2014
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 at 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);
--
1.9.0
More information about the SeaBIOS
mailing list