From 6ce67a533615dde47dc598abc960cbf867d63ffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Thu, 9 Oct 2025 18:12:37 +0200 Subject: [PATCH] smbios: support getting address from EFI * prefer v3 over v2 * adding efi attributes in gBootVolume KMessage is a bit of a hack, but shouldn't hurt older kernels. Change-Id: If5ea19dafa5a845872eb8d577e77a6935539ce20 Reviewed-on: https://review.haiku-os.org/c/haiku/+/9685 Tested-by: Commit checker robot Reviewed-by: waddlesplash --- headers/private/kernel/boot/kernel_args.h | 4 +++ src/add-ons/kernel/generic/smbios/smbios.cpp | 12 ++++++++- src/system/boot/platform/efi/cpu.cpp | 26 ++++++++++++++++++++ src/system/kernel/arch/x86/arch_platform.cpp | 15 +++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/headers/private/kernel/boot/kernel_args.h b/headers/private/kernel/boot/kernel_args.h index d77ef49d5b..8405960254 100644 --- a/headers/private/kernel/boot/kernel_args.h +++ b/headers/private/kernel/boot/kernel_args.h @@ -24,6 +24,10 @@ #define CURRENT_KERNEL_ARGS_VERSION 1 #define MAX_KERNEL_ARGS_RANGE 20 +// names of efi boot_volume fields +#define BOOT_EFI_SMBIOS_V2_ROOT "_boot_efi smbiosv2root" +#define BOOT_EFI_SMBIOS_V3_ROOT "_boot_efi smbiosv3root" + // names of common boot_volume fields #define BOOT_METHOD "boot method" #define BOOT_VOLUME_USER_SELECTED "user selected" diff --git a/src/add-ons/kernel/generic/smbios/smbios.cpp b/src/add-ons/kernel/generic/smbios/smbios.cpp index 429f107cdf..b4a7f4e3a4 100644 --- a/src/add-ons/kernel/generic/smbios/smbios.cpp +++ b/src/add-ons/kernel/generic/smbios/smbios.cpp @@ -13,6 +13,7 @@ #include #include +#include #include @@ -137,7 +138,16 @@ smbios_scan() // map SMBIOS area 0xf0000 - 0xfffff addr_t smBiosBase; - area_id smbiosArea = map_physical_memory("pc bios", 0xf0000, 0x10000, + phys_addr_t smBiosSearchBase = 0xf0000; + phys_addr_t* smbiosRootPointer = (phys_addr_t*)get_boot_item("SMBIOSv3_ROOT_POINTER", NULL); + if (smbiosRootPointer != NULL) { + smBiosSearchBase = *smbiosRootPointer; + } else { + smbiosRootPointer = (phys_addr_t*)get_boot_item("SMBIOSv2_ROOT_POINTER", NULL); + if (smbiosRootPointer != NULL) + smBiosSearchBase = *smbiosRootPointer; + } + area_id smbiosArea = map_physical_memory("pc bios", smBiosSearchBase, 0x10000, B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA, (void **)&smBiosBase); if (smbiosArea < 0) return; diff --git a/src/system/boot/platform/efi/cpu.cpp b/src/system/boot/platform/efi/cpu.cpp index 3e07994a3e..bc8779df8e 100644 --- a/src/system/boot/platform/efi/cpu.cpp +++ b/src/system/boot/platform/efi/cpu.cpp @@ -13,6 +13,30 @@ #include +#include "efi_platform.h" + + +static void +get_smbios_tables() +{ + const efi_configuration_table *table = kSystemTable->ConfigurationTable; + const size_t entries = kSystemTable->NumberOfTableEntries; + // Try to find any SMBIOS table. + for (uint32 i = 0; i < entries; i++) { + void* vendorTable = table[i].VendorTable; + if (table[i].VendorGuid.equals(SMBIOS_TABLE_GUID)) { + gBootParams.SetInt64(BOOT_EFI_SMBIOS_V2_ROOT, (addr_t)vendorTable); + dprintf("smbios: found v2 at %p\n", vendorTable); + continue; + } + if (table[i].VendorGuid.equals(SMBIOS3_TABLE_GUID)) { + gBootParams.SetInt64(BOOT_EFI_SMBIOS_V3_ROOT, (addr_t)vendorTable); + dprintf("smbios: found v3 at %p\n", vendorTable); + continue; + } + } +} + void cpu_init() @@ -28,4 +52,6 @@ extern "C" void platform_load_ucode(BootVolume& volume) { arch_ucode_load(volume); + + get_smbios_tables(); } diff --git a/src/system/kernel/arch/x86/arch_platform.cpp b/src/system/kernel/arch/x86/arch_platform.cpp index 2656200389..d98655f58e 100644 --- a/src/system/kernel/arch/x86/arch_platform.cpp +++ b/src/system/kernel/arch/x86/arch_platform.cpp @@ -15,6 +15,8 @@ static phys_addr_t sACPIRootPointer = 0; +static phys_addr_t sSMBIOSv2RootPointer = 0; +static phys_addr_t sSMBIOSv3RootPointer = 0; status_t @@ -32,6 +34,19 @@ arch_platform_init_post_vm(struct kernel_args *args) add_boot_item("ACPI_ROOT_POINTER", &sACPIRootPointer, sizeof(sACPIRootPointer)); + KMessage bootVolume; + bootVolume.SetTo(args->boot_volume, args->boot_volume_size); + sSMBIOSv2RootPointer = bootVolume.GetInt64(BOOT_EFI_SMBIOS_V2_ROOT, 0); + if (sSMBIOSv2RootPointer != 0) { + add_boot_item("SMBIOSv2_ROOT_POINTER", + &sSMBIOSv2RootPointer, sizeof(sSMBIOSv2RootPointer)); + } + sSMBIOSv3RootPointer = bootVolume.GetInt64(BOOT_EFI_SMBIOS_V3_ROOT, 0); + if (sSMBIOSv3RootPointer != 0) { + add_boot_item("SMBIOSv3_ROOT_POINTER", + &sSMBIOSv3RootPointer, sizeof(sSMBIOSv3RootPointer)); + } + return B_OK; }