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
This commit is contained in:
Greg V 2021-04-07 14:46:29 -05:00 committed by Eric van Gyzen
parent 13d4f96130
commit a29bff7a52
6 changed files with 25 additions and 11 deletions

View File

@ -103,7 +103,6 @@ device cpufreq
# Bus support. # Bus support.
device acpi device acpi
device smbios
options IOMMU options IOMMU
device pci device pci

View File

@ -513,7 +513,7 @@ device xenpci # Xen HVM Hypervisor services driver
# #
# ipmi: Intelligent Platform Management Interface # ipmi: Intelligent Platform Management Interface
# pbio: Parallel (8255 PPI) basic I/O (mode 0) port (e.g. Advantech PCL-724) # 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 # vpd: Vital Product Data kernel interface
# asmc: Apple System Management Controller # asmc: Apple System Management Controller
# si: Specialix International SI/XIO or SX intelligent serial card # si: Specialix International SI/XIO or SX intelligent serial card

View File

@ -47,6 +47,7 @@
#ifdef _KERNEL #ifdef _KERNEL
#include <isa/rtc.h> #include <isa/rtc.h>
#define ARCH_MAY_USE_EFI
#define EFI_TIME_LOCK() mtx_lock(&atrtc_time_lock) #define EFI_TIME_LOCK() mtx_lock(&atrtc_time_lock)
#define EFI_TIME_UNLOCK() mtx_unlock(&atrtc_time_lock) #define EFI_TIME_UNLOCK() mtx_unlock(&atrtc_time_lock)

View File

@ -36,6 +36,8 @@
#define EFIABI_ATTR #define EFIABI_ATTR
#ifdef _KERNEL #ifdef _KERNEL
#define ARCH_MAY_USE_EFI
#define EFI_TIME_LOCK() #define EFI_TIME_LOCK()
#define EFI_TIME_UNLOCK() #define EFI_TIME_UNLOCK()
#define EFI_TIME_OWNED() #define EFI_TIME_OWNED()

View File

@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h> #include <sys/kernel.h>
#include <sys/malloc.h> #include <sys/malloc.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/efi.h>
#include <sys/module.h> #include <sys/module.h>
#include <sys/bus.h> #include <sys/bus.h>
@ -79,20 +80,28 @@ static int smbios_cksum (struct smbios_eps *);
static void static void
smbios_identify (driver_t *driver, device_t parent) 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; struct smbios_eps *eps;
device_t child; device_t child;
vm_paddr_t addr; vm_paddr_t addr = 0;
int length; int length;
int rid; int rid;
if (!device_is_alive(parent)) if (!device_is_alive(parent))
return; 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__) #if defined(__amd64__) || defined(__i386__)
addr = bios_sigsearch(SMBIOS_START, SMBIOS_SIG, SMBIOS_LEN, if (addr == 0)
SMBIOS_STEP, SMBIOS_OFF); addr = bios_sigsearch(SMBIOS_START, SMBIOS_SIG, SMBIOS_LEN,
#else SMBIOS_STEP, SMBIOS_OFF);
addr = 0;
#endif #endif
if (addr != 0) { if (addr != 0) {
@ -242,6 +251,9 @@ static driver_t smbios_driver = {
}; };
DRIVER_MODULE(smbios, nexus, smbios_driver, smbios_devclass, smbios_modevent, 0); 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); MODULE_VERSION(smbios, 1);
static int static int

View File

@ -36,10 +36,10 @@
#define EFI_PAGE_SIZE (1 << EFI_PAGE_SHIFT) #define EFI_PAGE_SIZE (1 << EFI_PAGE_SHIFT)
#define EFI_PAGE_MASK (EFI_PAGE_SIZE - 1) #define EFI_PAGE_MASK (EFI_PAGE_SIZE - 1)
#define EFI_TABLE_ACPI20 \ #define EFI_TABLE_SMBIOS \
{0x8868e871,0xe4f1,0x11d3,0xbc,0x22,{0x00,0x80,0xc7,0x3c,0x88,0x81}} {0xeb9d2d31,0x2d88,0x11d3,0x9a,0x16,{0x00,0x90,0x27,0x3f,0xc1,0x4d}}
#define EFI_TABLE_SAL \ #define EFI_TABLE_SMBIOS3 \
{0xeb9d2d32,0x2d88,0x11d3,0x9a,0x16,{0x00,0x90,0x27,0x3f,0xc1,0x4d}} {0xf2fd1544,0x9794,0x4a2c,0x99,0x2e,{0xe5,0xbb,0xcf,0x20,0xe3,0x94}}
enum efi_reset { enum efi_reset {
EFI_RESET_COLD = 0, EFI_RESET_COLD = 0,