git: 4cfd4d54822b - stable/13 - smbios: support getting address from EFI

From: Eric van Gyzen <vangyzen_at_FreeBSD.org>
Date: Thu, 03 Mar 2022 14:20:39 UTC
The branch stable/13 has been updated by vangyzen:

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

commit 4cfd4d54822bae9794558c988bb59ca9039e9feb
Author:     Greg V <greg@unrelenting.technology>
AuthorDate: 2021-04-07 19:46:29 +0000
Commit:     Eric van Gyzen <vangyzen@FreeBSD.org>
CommitDate: 2022-03-03 14:20:07 +0000

    smbios: support getting address from EFI
    
    On some systems (e.g. Lenovo ThinkPad X240, Apple MacBookPro12,1)
    the SMBIOS entry point is not found in the <0xFFFFF space.
    
    Follow the SMBIOS spec and use the EFI Configuration Table for
    locating the entry point on EFI systems.
    
    Reviewed by:    rpokala, dab
    MFC after:      1 week
    Sponsored by:   Dell EMC Isilon
    Differential Revision:  https://reviews.freebsd.org/D29276
    
    (cherry picked from commit a29bff7a5216bd5f4a76228788e7eacf235004de)
---
 sys/amd64/conf/MINIMAL  |  1 -
 sys/amd64/conf/NOTES    |  2 +-
 sys/amd64/include/efi.h |  1 +
 sys/arm64/include/efi.h |  2 ++
 sys/dev/smbios/smbios.c | 22 +++++++++++++++++-----
 sys/sys/efi.h           |  8 ++++----
 6 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/sys/amd64/conf/MINIMAL b/sys/amd64/conf/MINIMAL
index 030fb171c43a..a55a63d6b3ad 100644
--- a/sys/amd64/conf/MINIMAL
+++ b/sys/amd64/conf/MINIMAL
@@ -93,7 +93,6 @@ device		cpufreq
 
 # Bus support.
 device		acpi
-device		smbios
 options 	IOMMU
 device		pci
 
diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
index bf75a0eb4184..229a63bd23b9 100644
--- a/sys/amd64/conf/NOTES
+++ b/sys/amd64/conf/NOTES
@@ -516,7 +516,7 @@ device 		xenpci		# Xen HVM Hypervisor services driver
 #
 # ipmi: Intelligent Platform Management Interface
 # pbio: Parallel (8255 PPI) basic I/O (mode 0) port (e.g. Advantech PCL-724)
-# smbios: DMI/SMBIOS entry point
+# smbios: DMI/SMBIOS entry point (requires EFIRT option)
 # vpd: Vital Product Data kernel interface
 # asmc: Apple System Management Controller
 # si: Specialix International SI/XIO or SX intelligent serial card
diff --git a/sys/amd64/include/efi.h b/sys/amd64/include/efi.h
index a0037084d3d4..b7bda5388c21 100644
--- a/sys/amd64/include/efi.h
+++ b/sys/amd64/include/efi.h
@@ -46,6 +46,7 @@
 
 #ifdef _KERNEL
 #include <isa/rtc.h>
+#define ARCH_MAY_USE_EFI
 
 #define	EFI_TIME_LOCK()		mtx_lock(&atrtc_time_lock)
 #define	EFI_TIME_UNLOCK()	mtx_unlock(&atrtc_time_lock)
diff --git a/sys/arm64/include/efi.h b/sys/arm64/include/efi.h
index a8fddfad8d0f..6db16e5b8291 100644
--- a/sys/arm64/include/efi.h
+++ b/sys/arm64/include/efi.h
@@ -36,6 +36,8 @@
 #define	EFIABI_ATTR
 
 #ifdef _KERNEL
+#define ARCH_MAY_USE_EFI
+
 #define	EFI_TIME_LOCK()
 #define	EFI_TIME_UNLOCK()
 #define	EFI_TIME_OWNED()
diff --git a/sys/dev/smbios/smbios.c b/sys/dev/smbios/smbios.c
index 10589ed8d49d..f3519634e1a4 100644
--- a/sys/dev/smbios/smbios.c
+++ b/sys/dev/smbios/smbios.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/socket.h>
+#include <sys/efi.h>
 
 #include <sys/module.h>
 #include <sys/bus.h>
@@ -79,20 +80,28 @@ static int	smbios_cksum	(struct smbios_eps *);
 static void
 smbios_identify (driver_t *driver, device_t parent)
 {
+#ifdef ARCH_MAY_USE_EFI
+	struct uuid efi_smbios = EFI_TABLE_SMBIOS;
+	void *addr_efi;
+#endif
 	struct smbios_eps *eps;
 	device_t child;
-	vm_paddr_t addr;
+	vm_paddr_t addr = 0;
 	int length;
 	int rid;
 
 	if (!device_is_alive(parent))
 		return;
 
+#ifdef ARCH_MAY_USE_EFI
+	if (!efi_get_table(&efi_smbios, &addr_efi))
+		addr = (vm_paddr_t)addr_efi;
+#endif
+
 #if defined(__amd64__) || defined(__i386__)
-	addr = bios_sigsearch(SMBIOS_START, SMBIOS_SIG, SMBIOS_LEN,
-	    SMBIOS_STEP, SMBIOS_OFF);
-#else
-	addr = 0;
+	if (addr == 0)
+		addr = bios_sigsearch(SMBIOS_START, SMBIOS_SIG, SMBIOS_LEN,
+		    SMBIOS_STEP, SMBIOS_OFF);
 #endif
 
 	if (addr != 0) {
@@ -242,6 +251,9 @@ static driver_t smbios_driver = {
 };
 
 DRIVER_MODULE(smbios, nexus, smbios_driver, smbios_devclass, smbios_modevent, 0);
+#ifdef ARCH_MAY_USE_EFI
+MODULE_DEPEND(smbios, efirt, 1, 1, 1);
+#endif
 MODULE_VERSION(smbios, 1);
 
 static int
diff --git a/sys/sys/efi.h b/sys/sys/efi.h
index 220509853cb2..c71a3f23b8e8 100644
--- a/sys/sys/efi.h
+++ b/sys/sys/efi.h
@@ -36,10 +36,10 @@
 #define	EFI_PAGE_SIZE		(1 << EFI_PAGE_SHIFT)
 #define	EFI_PAGE_MASK		(EFI_PAGE_SIZE - 1)
 
-#define	EFI_TABLE_ACPI20			\
-	{0x8868e871,0xe4f1,0x11d3,0xbc,0x22,{0x00,0x80,0xc7,0x3c,0x88,0x81}}
-#define	EFI_TABLE_SAL				\
-	{0xeb9d2d32,0x2d88,0x11d3,0x9a,0x16,{0x00,0x90,0x27,0x3f,0xc1,0x4d}}
+#define	EFI_TABLE_SMBIOS				\
+	{0xeb9d2d31,0x2d88,0x11d3,0x9a,0x16,{0x00,0x90,0x27,0x3f,0xc1,0x4d}}
+#define	EFI_TABLE_SMBIOS3				\
+	{0xf2fd1544,0x9794,0x4a2c,0x99,0x2e,{0xe5,0xbb,0xcf,0x20,0xe3,0x94}}
 
 enum efi_reset {
 	EFI_RESET_COLD = 0,