The branch main has been updated by jmg:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=ee97f198b42d50437f87aa4111d478eca2a5be16

commit ee97f198b42d50437f87aa4111d478eca2a5be16
Author:     John-Mark Gurney <j...@freebsd.org>
AuthorDate: 2023-02-22 02:27:37 +0000
Commit:     John-Mark Gurney <j...@freebsd.org>
CommitDate: 2023-02-22 04:10:12 +0000

    Support SMBIOS v3 for 64-bit entry systems
    
    Summary:
    Under QEMU on arm64 systems, the smbios table is above 4GB
    requiring a 64-bit address to access.
    
    Reviewers: manu
    
    Subscribers: imp, bcran, dab
    
    Differential Revision: https://reviews.freebsd.org/D38721
---
 stand/efi/loader/main.c |  3 ++-
 stand/libsa/smbios.c    | 54 +++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c
index 446c267a517a..9ff5f1dd7674 100644
--- a/stand/efi/loader/main.c
+++ b/stand/efi/loader/main.c
@@ -1187,7 +1187,8 @@ main(int argc, CHAR16 *argv[])
 #if !defined(__arm__)
        for (k = 0; k < ST->NumberOfTableEntries; k++) {
                guid = &ST->ConfigurationTable[k].VendorGuid;
-               if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) {
+               if (!memcmp(guid, &smbios, sizeof(EFI_GUID)) ||
+                   !memcmp(guid, &smbios3, sizeof(EFI_GUID))) {
                        char buf[40];
 
                        snprintf(buf, sizeof(buf), "%p",
diff --git a/stand/libsa/smbios.c b/stand/libsa/smbios.c
index 61bd82f9d6f0..15c5c7e50565 100644
--- a/stand/libsa/smbios.c
+++ b/stand/libsa/smbios.c
@@ -32,6 +32,11 @@ __FBSDID("$FreeBSD$");
 
 #define PTOV(x)                ptov(x)
 
+/* Only enable 64-bit entry point if it makes sense */
+#if __SIZEOF_POINTER__ > 4
+#define        HAS_SMBV3       1
+#endif
+
 /*
  * Detect SMBIOS and export information about the SMBIOS into the
  * environment.
@@ -53,11 +58,13 @@ __FBSDID("$FreeBSD$");
 #define        SMBIOS_LENGTH           0x10000
 #define        SMBIOS_STEP             0x10
 #define        SMBIOS_SIG              "_SM_"
+#define        SMBIOS3_SIG             "_SM3_"
 #define        SMBIOS_DMI_SIG          "_DMI_"
 
 #define        SMBIOS_GET8(base, off)  (*(uint8_t *)((base) + (off)))
 #define        SMBIOS_GET16(base, off) (*(uint16_t *)((base) + (off)))
 #define        SMBIOS_GET32(base, off) (*(uint32_t *)((base) + (off)))
+#define        SMBIOS_GET64(base, off) (*(uint64_t *)((base) + (off)))
 
 #define        SMBIOS_GETLEN(base)     SMBIOS_GET8(base, 0x01)
 #define        SMBIOS_GETSTR(base)     ((base) + SMBIOS_GETLEN(base))
@@ -80,6 +87,9 @@ struct smbios_attr {
 };
 
 static struct smbios_attr smbios;
+#ifdef HAS_SMBV3
+static int isv3;
+#endif
 
 static uint8_t
 smbios_checksum(const caddr_t addr, const uint8_t len)
@@ -98,12 +108,23 @@ smbios_sigsearch(const caddr_t addr, const uint32_t len)
        caddr_t         cp;
 
        /* Search on 16-byte boundaries. */
-       for (cp = addr; cp < addr + len; cp += SMBIOS_STEP)
-               if (strncmp(cp, SMBIOS_SIG, 4) == 0 &&
+       for (cp = addr; cp < addr + len; cp += SMBIOS_STEP) {
+               /* v2.1, 32-bit Entry point */
+               if (strncmp(cp, SMBIOS_SIG, sizeof(SMBIOS_SIG) - 1) == 0 &&
                    smbios_checksum(cp, SMBIOS_GET8(cp, 0x05)) == 0 &&
                    strncmp(cp + 0x10, SMBIOS_DMI_SIG, 5) == 0 &&
                    smbios_checksum(cp + 0x10, 0x0f) == 0)
                        return (cp);
+
+#ifdef HAS_SMBV3
+               /* v3.0, 64-bit Entry point */
+               if (strncmp(cp, SMBIOS3_SIG, sizeof(SMBIOS3_SIG) - 1) == 0 &&
+                   smbios_checksum(cp, SMBIOS_GET8(cp, 0x06)) == 0) {
+                       isv3 = 1;
+                       return (cp);
+               }
+#endif
+       }
        return (NULL);
 }
 
@@ -450,6 +471,8 @@ smbios_probe(const caddr_t addr)
 {
        caddr_t         saddr, info;
        uintptr_t       paddr;
+       int             maj_off;
+       int             min_off;
 
        if (smbios.probed)
                return;
@@ -461,10 +484,25 @@ smbios_probe(const caddr_t addr)
        if (saddr == NULL)
                return;
 
-       smbios.length = SMBIOS_GET16(saddr, 0x16);      /* Structure Table 
Length */
-       paddr = SMBIOS_GET32(saddr, 0x18);              /* Structure Table 
Address */
-       smbios.count = SMBIOS_GET16(saddr, 0x1c);       /* No of SMBIOS 
Structures */
-       smbios.ver = SMBIOS_GET8(saddr, 0x1e);          /* SMBIOS BCD Revision 
*/
+#ifdef HAS_SMBV3
+       if (isv3) {
+               smbios.length = SMBIOS_GET16(saddr, 0x0c);      /* Structure 
Table Length */
+               paddr = SMBIOS_GET64(saddr, 0x10);              /* Structure 
Table Address */
+               smbios.count = -1;                              /* not present 
in V3 */
+               smbios.ver = 0;                                 /* not present 
in V3 */
+               maj_off = 0x07;
+               min_off = 0x08;
+       } else
+#endif
+       {
+               smbios.length = SMBIOS_GET16(saddr, 0x16);      /* Structure 
Table Length */
+               paddr = SMBIOS_GET32(saddr, 0x18);              /* Structure 
Table Address */
+               smbios.count = SMBIOS_GET16(saddr, 0x1c);       /* No of SMBIOS 
Structures */
+               smbios.ver = SMBIOS_GET8(saddr, 0x1e);          /* SMBIOS BCD 
Revision */
+               maj_off = 0x06;
+               min_off = 0x07;
+       }
+
 
        if (smbios.ver != 0) {
                smbios.major = smbios.ver >> 4;
@@ -473,8 +511,8 @@ smbios_probe(const caddr_t addr)
                        smbios.ver = 0;
        }
        if (smbios.ver == 0) {
-               smbios.major = SMBIOS_GET8(saddr, 0x06);/* SMBIOS Major Version 
*/
-               smbios.minor = SMBIOS_GET8(saddr, 0x07);/* SMBIOS Minor Version 
*/
+               smbios.major = SMBIOS_GET8(saddr, maj_off);/* SMBIOS Major 
Version */
+               smbios.minor = SMBIOS_GET8(saddr, min_off);/* SMBIOS Minor 
Version */
        }
        smbios.ver = (smbios.major << 8) | smbios.minor;
        smbios.addr = PTOV(paddr);

Reply via email to