@@ -611,6 +611,21 @@ int e820_add_entry(uint64_t address, uint64_t length, uint32_t type)
return e820_entries;
}
+int e820_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)) {
+ return false;
+ }
+ *address = le64_to_cpu(e820_table[idx].address);
+ *length = le64_to_cpu(e820_table[idx].length);
+ return true;
+}
+
/* Calculates the limit to CPU APIC ID values
*
* This function returns the limit for the APIC ID value, so that all
@@ -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"
@@ -666,11 +667,15 @@ uint8_t *smbios_get_table(size_t *length)
((ram_size_mb - 1) & 0x3FFF) + 1 : 0x4000;
smbios_build_type_17_table(i, size_mb);
}
- smbios_build_type_19_table(0, 0, smbios_below_4g_ram >> 10);
+ for (i = 0; i < e820_num_entries(); i++) {
+ uint64_t address, length;
+ if (e820_get_entry(i, E820_RAM, &address, &length)) {
+ smbios_build_type_19_table(i, address >> 10, length >> 10);
+ }
+ }
smbios_build_type_20_table(0, 0, 0, 0, smbios_below_4g_ram >> 10);
if (smbios_above_4g_ram) {
uint32_t start_mb = 4096, size_mb, j;
- smbios_build_type_19_table(1, 4 << 20, smbios_above_4g_ram >> 10);
for (j = 1, i = 0; i < memdev_count; i++, j++) {
size_mb = (i == memdev_count - 1) ?
((ram_size_mb - 1) & 0x3FFF) + 1 : 0x4000;
@@ -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_num_entries(void);
+bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
#define PC_Q35_COMPAT_1_7 \
PC_COMPAT_1_7, \