summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Habkost <ehabkost@redhat.com>2020-12-10 10:32:44 -0500
committerKevin O'Connor <kevin@koconnor.net>2021-12-18 11:39:13 -0500
commiteafea937e4c03a471ada20d88d39e7aa69a57530 (patch)
tree5310ab320126516599a41600b4c1643af4777ddb
parentddd0f7b877695bc15a88f5f0077868329518d7bf (diff)
downloadqemu-seabios-eafea937e4c03a471ada20d88d39e7aa69a57530.tar.gz
smbios: copy_smbios_30() function
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 <ehabkost@redhat.com>
-rw-r--r--src/fw/biostables.c36
-rw-r--r--src/std/smbios.h13
2 files changed, 47 insertions, 2 deletions
diff --git a/src/fw/biostables.c b/src/fw/biostables.c
index 91fe747..b2c84a1 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;
diff --git a/src/std/smbios.h b/src/std/smbios.h
index 17fdfed..208440b 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;