qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [QEMU v5 PATCH 17/18] SMBIOS: Update memory table types (16


From: Gabriel L. Somlo
Subject: [Qemu-devel] [QEMU v5 PATCH 17/18] SMBIOS: Update memory table types (16, 17, and 19) to smbios spec v2.8
Date: Fri, 11 Apr 2014 12:11:57 -0400

This patch adds extended start/end address and extended size fields
to each memory table type.

Signed-off-by: Gabriel Somlo <address@hidden>
---
 hw/i386/smbios.c         | 46 +++++++++++++++++++++++++++++-----------------
 include/hw/i386/smbios.h | 15 ++++++++++++---
 2 files changed, 41 insertions(+), 20 deletions(-)

diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c
index 382b75d..2f0755f 100644
--- a/hw/i386/smbios.c
+++ b/hw/i386/smbios.c
@@ -521,21 +521,24 @@ static void smbios_build_type_4_table(unsigned instance)
 #define ONE_MB ((ram_addr_t)1 << 20)
 #define ONE_GB ((ram_addr_t)1 << 30)
 
+#define MAX_T16_STD_SZ 0x80000000 /* 2T in Kilobytes */
+
 static void smbios_build_type_16_table(unsigned dimm_cnt)
 {
-    ram_addr_t  ram_size_kb = ram_size >> 10;
+    ram_addr_t size_kb;
 
     SMBIOS_BUILD_TABLE_PRE(16, 0x1000, true); /* required */
 
     t->location = 0x01; /* Other */
     t->use = 0x03; /* System memory */
     t->error_correction = 0x06; /* Multi-bit ECC (for Microsoft, per SeaBIOS) 
*/
-    /* if ram_size < 2T, use value in Kilobytes; 0x80000000 == 2T and over */
-    t->maximum_capacity = (ram_size_kb < 0x80000000) ? ram_size_kb : 
0x80000000;
-    if (t->maximum_capacity == 0x80000000) {
-        /* TODO: support smbios v2.7 extended capacity */
-        fprintf(stderr, "qemu: warning: SMBIOS v2.7+ required for "
-                        "ram_size >= 2T (%ld)\n", ram_size);
+    size_kb = QEMU_ALIGN_UP(ram_size, ONE_KB) / ONE_KB;
+    if (size_kb < MAX_T16_STD_SZ) {
+        t->maximum_capacity = size_kb;
+        t->extended_maximum_capacity = 0;
+    } else {
+        t->maximum_capacity = MAX_T16_STD_SZ;
+        t->extended_maximum_capacity = ram_size;
     }
     t->memory_error_information_handle = 0xFFFE; /* Not provided */
     t->number_of_memory_devices = dimm_cnt;
@@ -543,6 +546,9 @@ static void smbios_build_type_16_table(unsigned dimm_cnt)
     SMBIOS_BUILD_TABLE_POST;
 }
 
+#define MAX_T17_STD_SZ 0x7FFF /* (32G - 1M), in Megabytes */
+#define MAX_T18_EXT_SZ 0x80000000 /* in Megabytes */
+
 static void smbios_build_type_17_table(unsigned instance, ram_addr_t size)
 {
     char loc_str[128];
@@ -555,13 +561,13 @@ static void smbios_build_type_17_table(unsigned instance, 
ram_addr_t size)
     t->total_width = 0xFFFF; /* Unknown */
     t->data_width = 0xFFFF; /* Unknown */
     size_mb = QEMU_ALIGN_UP(size, ONE_MB) / ONE_MB;
-    if (size_mb < 0x7FFF) {
+    if (size_mb < MAX_T17_STD_SZ) {
         t->size = size_mb;
+        t->extended_size = 0;
     } else {
-        t->size = 0x7FFF;
-        /* TODO: support smbios v2.7 extended capacity */
-        fprintf(stderr, "qemu: warning: SMBIOS v2.7+ required for "
-                        "DIMM size >= 0x7FFF Mbytes (0x%lx)\n", size_mb);
+        assert(size_mb < MAX_T18_EXT_SZ);
+        t->size = MAX_T17_STD_SZ;
+        t->extended_size = size_mb;
     }
     t->form_factor = 0x09; /* DIMM */
     t->device_set = 0; /* Not in a set */
@@ -575,6 +581,11 @@ static void smbios_build_type_17_table(unsigned instance, 
ram_addr_t size)
     SMBIOS_TABLE_SET_STR(17, serial_number_str, type17.serial);
     SMBIOS_TABLE_SET_STR(17, asset_tag_number_str, type17.asset);
     SMBIOS_TABLE_SET_STR(17, part_number_str, type17.part);
+    t->attributes = 0; /* Unknown */
+    t->configured_clock_speed = 0; /* Unknown */
+    t->minimum_voltage = 0; /* Unknown */
+    t->maximum_voltage = 0; /* Unknown */
+    t->configured_voltage = 0; /* Unknown */
 
     SMBIOS_BUILD_TABLE_POST;
 }
@@ -590,13 +601,14 @@ static void smbios_build_type_19_table(unsigned instance,
     assert(end > start);
     start_kb = start / ONE_KB;
     end_kb = end / ONE_KB;
-    if (start_kb >= UINT32_MAX || end_kb >= UINT32_MAX) {
-        t->starting_address = t->ending_address = UINT32_MAX;
-        fprintf(stderr, "qemu: warning: SMBIOS v2.7+ required for "
-                        "type19(start=%lx, size=%lx)\n", start, size);
-    } else {
+    if (start_kb < UINT32_MAX && end_kb < UINT32_MAX) {
         t->starting_address = start_kb;
         t->ending_address = end_kb;
+        t->extended_starting_address = t->extended_ending_address = 0;
+    } else {
+        t->starting_address = t->ending_address = UINT32_MAX;
+        t->extended_starting_address = start;
+        t->extended_ending_address = end;
     }
     t->memory_array_handle = 0x1000; /* Type 16 (Phys. Mem. Array) */
     t->partition_width = 1; /* One device per row */
diff --git a/include/hw/i386/smbios.h b/include/hw/i386/smbios.h
index 9067139..4525c9b 100644
--- a/include/hw/i386/smbios.h
+++ b/include/hw/i386/smbios.h
@@ -127,7 +127,7 @@ struct smbios_type_4 {
     uint16_t processor_family2;
 } QEMU_PACKED;
 
-/* SMBIOS type 16 - Physical Memory Array */
+/* SMBIOS type 16 - Physical Memory Array (v2.7) */
 struct smbios_type_16 {
     struct smbios_structure_header header;
     uint8_t location;
@@ -136,9 +136,10 @@ struct smbios_type_16 {
     uint32_t maximum_capacity;
     uint16_t memory_error_information_handle;
     uint16_t number_of_memory_devices;
+    uint64_t extended_maximum_capacity;
 } QEMU_PACKED;
 
-/* SMBIOS type 17 - Memory Device (v2.3) */
+/* SMBIOS type 17 - Memory Device (v2.8) */
 struct smbios_type_17 {
     struct smbios_structure_header header;
     uint16_t physical_memory_array_handle;
@@ -157,15 +158,23 @@ struct smbios_type_17 {
     uint8_t serial_number_str;
     uint8_t asset_tag_number_str;
     uint8_t part_number_str;
+    uint8_t attributes;
+    uint32_t extended_size;
+    uint32_t configured_clock_speed;
+    uint32_t minimum_voltage;
+    uint32_t maximum_voltage;
+    uint32_t configured_voltage;
 } QEMU_PACKED;
 
-/* SMBIOS type 19 - Memory Array Mapped Address */
+/* SMBIOS type 19 - Memory Array Mapped Address (v2.7) */
 struct smbios_type_19 {
     struct smbios_structure_header header;
     uint32_t starting_address;
     uint32_t ending_address;
     uint16_t memory_array_handle;
     uint8_t partition_width;
+    uint64_t extended_starting_address;
+    uint64_t extended_ending_address;
 } QEMU_PACKED;
 
 /* SMBIOS type 32 - System Boot Information */
-- 
1.9.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]