Add new copy_smbios_30() function, that will be used to support
SMBIOS 3.0 entry points.

The SMBIOS 3.0 entry point will be tracked in a separate
SMBios30Addr variable, because both 2.1 and 3.0 entry points may
exist at the same time.

Adjust the smbios_get_tables(), smbios_major_version(), and
smbios_minor_version() helpers to use the SMBIOS 3.0 entry point
if available.

Signed-off-by: Eduardo Habkost <ehabk...@redhat.com>
---
 src/std/smbios.h    | 13 +++++++++++++
 src/fw/biostables.c | 36 ++++++++++++++++++++++++++++++++++--
 2 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/src/std/smbios.h b/src/std/smbios.h
index 17fdfed6..208440b1 100644
--- a/src/std/smbios.h
+++ b/src/std/smbios.h
@@ -25,6 +25,19 @@ struct smbios_21_entry_point {
     u8 smbios_bcd_revision;
 } PACKED;
 
+struct smbios_30_entry_point {
+    char signature[5];
+    u8 checksum;
+    u8 length;
+    u8 smbios_major_version;
+    u8 smbios_minor_version;
+    u8 smbios_docrev;
+    u8 entry_point_revision;
+    u8 reserved;
+    u32 structure_table_max_size;
+    u64 structure_table_address;
+} PACKED;
+
 /* This goes at the beginning of every SMBIOS structure. */
 struct smbios_structure_header {
     u8 type;
diff --git a/src/fw/biostables.c b/src/fw/biostables.c
index 91fe7470..b2c84a12 100644
--- a/src/fw/biostables.c
+++ b/src/fw/biostables.c
@@ -315,8 +315,36 @@ copy_smbios_21(void *pos)
     SMBios21Addr = copy_fseg_table("SMBIOS", pos, p->length);
 }
 
+static struct smbios_30_entry_point *SMBios30Addr;
+
+static int
+valid_smbios_30_signature(struct smbios_30_entry_point *p)
+{
+    return !memcmp(p->signature, "_SM3_", 5);
+}
+
+void
+copy_smbios_30(void *pos)
+{
+    if (SMBios30Addr)
+        return;
+    struct smbios_30_entry_point *p = pos;
+    if (!valid_smbios_30_signature(p))
+        return;
+    if (checksum(pos, p->length) != 0)
+        return;
+    SMBios30Addr = copy_fseg_table("SMBIOS 3.0", pos, p->length);
+}
+
 void *smbios_get_tables(u32 *length)
 {
+    if (SMBios30Addr) {
+        u32 addr32 = SMBios30Addr->structure_table_address;
+        if (addr32 == SMBios30Addr->structure_table_address) {
+            *length = SMBios30Addr->structure_table_max_size;
+            return (void *)addr32;
+        }
+    }
     if (SMBios21Addr) {
         *length = SMBios21Addr->structure_table_length;
         return (void *)SMBios21Addr->structure_table_address;
@@ -327,7 +355,9 @@ void *smbios_get_tables(u32 *length)
 static int
 smbios_major_version(void)
 {
-    if (SMBios21Addr)
+    if (SMBios30Addr)
+        return SMBios30Addr->smbios_major_version;
+    else if (SMBios21Addr)
         return SMBios21Addr->smbios_major_version;
     else
         return 0;
@@ -336,7 +366,9 @@ smbios_major_version(void)
 static int
 smbios_minor_version(void)
 {
-    if (SMBios21Addr)
+    if (SMBios30Addr)
+        return SMBios30Addr->smbios_minor_version;
+    else if (SMBios21Addr)
         return SMBios21Addr->smbios_minor_version;
     else
         return 0;
-- 
2.28.0
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-le...@seabios.org

Reply via email to