efi: Use the installed SMBIOS tables

U-Boot should set up the SMBIOS tables during startup, as it does on x86.
Ensure that it does this correctly on non-x86 machines too, by creating
an event spy for last-stage init.

Tidy up the installation-condition code while we are here.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
Simon Glass 2023-09-20 07:29:51 -06:00 committed by Bin Meng
parent 50834884a8
commit 53fab13a7b
6 changed files with 58 additions and 35 deletions

View file

@ -307,7 +307,8 @@ static int last_stage_init(void)
struct udevice *bus; struct udevice *bus;
ofnode node; ofnode node;
if (!of_machine_is_compatible("globalscale,espressobin")) if (!CONFIG_IS_ENABLED(DM_MDIO) ||
!of_machine_is_compatible("globalscale,espressobin"))
return 0; return 0;
node = ofnode_by_compatible(ofnode_null(), "marvell,orion-mdio"); node = ofnode_by_compatible(ofnode_null(), "marvell,orion-mdio");

View file

@ -1049,6 +1049,7 @@ config SMBIOS
bool "SMBIOS support" bool "SMBIOS support"
depends on X86 || EFI_LOADER depends on X86 || EFI_LOADER
default y default y
select LAST_STAGE_INIT
help help
Indicates that this platform can support System Management BIOS Indicates that this platform can support System Management BIOS
(SMBIOS) tables. These provide various pieces of information about (SMBIOS) tables. These provide various pieces of information about

View file

@ -79,7 +79,7 @@ obj-$(CONFIG_VIDEO) += efi_gop.o
obj-$(CONFIG_BLK) += efi_disk.o obj-$(CONFIG_BLK) += efi_disk.o
obj-$(CONFIG_NETDEVICES) += efi_net.o obj-$(CONFIG_NETDEVICES) += efi_net.o
obj-$(CONFIG_ACPI) += efi_acpi.o obj-$(CONFIG_ACPI) += efi_acpi.o
obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += efi_smbios.o obj-$(CONFIG_SMBIOS) += efi_smbios.o
obj-$(CONFIG_EFI_RNG_PROTOCOL) += efi_rng.o obj-$(CONFIG_EFI_RNG_PROTOCOL) += efi_rng.o
obj-$(CONFIG_EFI_TCG2_PROTOCOL) += efi_tcg2.o obj-$(CONFIG_EFI_TCG2_PROTOCOL) += efi_tcg2.o
obj-$(CONFIG_EFI_RISCV_BOOT_PROTOCOL) += efi_riscv.o obj-$(CONFIG_EFI_RISCV_BOOT_PROTOCOL) += efi_riscv.o

View file

@ -326,11 +326,11 @@ efi_status_t efi_init_obj_list(void)
if (ret != EFI_SUCCESS) if (ret != EFI_SUCCESS)
goto out; goto out;
} }
#ifdef CONFIG_GENERATE_SMBIOS_TABLE if (IS_ENABLED(CONFIG_SMBIOS)) {
ret = efi_smbios_register(); ret = efi_smbios_register();
if (ret != EFI_SUCCESS) if (ret != EFI_SUCCESS)
goto out; goto out;
#endif }
ret = efi_watchdog_register(); ret = efi_watchdog_register();
if (ret != EFI_SUCCESS) if (ret != EFI_SUCCESS)
goto out; goto out;

View file

@ -10,8 +10,14 @@
#include <common.h> #include <common.h>
#include <efi_loader.h> #include <efi_loader.h>
#include <log.h> #include <log.h>
#include <malloc.h>
#include <mapmem.h> #include <mapmem.h>
#include <smbios.h> #include <smbios.h>
#include <linux/sizes.h>
enum {
TABLE_SIZE = SZ_4K,
};
/* /*
* Install the SMBIOS table as a configuration table. * Install the SMBIOS table as a configuration table.
@ -20,36 +26,50 @@
*/ */
efi_status_t efi_smbios_register(void) efi_status_t efi_smbios_register(void)
{ {
/* Map within the low 32 bits, to allow for 32bit SMBIOS tables */ ulong addr;
u64 dmi_addr = U32_MAX;
efi_status_t ret; efi_status_t ret;
void *dmi;
/* Reserve 4kiB page for SMBIOS */ addr = gd->arch.smbios_start;
ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, if (!addr) {
EFI_RUNTIME_SERVICES_DATA, 1, &dmi_addr); log_err("No SMBIOS tables to install\n");
return EFI_NOT_FOUND;
}
if (ret != EFI_SUCCESS) { /* Mark space used for tables */
/* Could not find space in lowmem, use highmem instead */ ret = efi_add_memory_map(addr, TABLE_SIZE, EFI_RUNTIME_SERVICES_DATA);
ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, if (ret)
EFI_RUNTIME_SERVICES_DATA, 1,
&dmi_addr);
if (ret != EFI_SUCCESS)
return ret; return ret;
log_debug("EFI using SMBIOS tables at %lx\n", addr);
/* Install SMBIOS information as configuration table */
return efi_install_configuration_table(&smbios_guid,
map_sysmem(addr, 0));
} }
/* static int install_smbios_table(void)
* Generate SMBIOS tables - we know that efi_allocate_pages() returns {
* a 4k-aligned address, so it is safe to assume that ulong addr;
* write_smbios_table() will write the table at that address. void *buf;
*/
assert(!(dmi_addr & 0xf)); if (!IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE) || IS_ENABLED(CONFIG_X86))
dmi = (void *)(uintptr_t)dmi_addr; return 0;
if (write_smbios_table(map_to_sysmem(dmi)))
/* Install SMBIOS information as configuration table */ /* Align the table to a 4KB boundary to keep EFI happy */
return efi_install_configuration_table(&smbios_guid, dmi); buf = memalign(SZ_4K, TABLE_SIZE);
efi_free_pages(dmi_addr, 1); if (!buf)
log_err("Cannot create SMBIOS table\n"); return log_msg_ret("mem", -ENOMEM);
return EFI_SUCCESS;
addr = map_to_sysmem(buf);
if (!write_smbios_table(addr)) {
log_err("Failed to write SMBIOS table\n");
return log_msg_ret("smbios", -EINVAL);
} }
/* Make a note of where we put it */
log_debug("SMBIOS tables written to %lx\n", addr);
gd->arch.smbios_start = addr;
return 0;
}
EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, install_smbios_table);

View file

@ -18,6 +18,7 @@ def test_event_dump(u_boot_console):
-------------------- ------------------------------ ------------------------------ -------------------- ------------------------------ ------------------------------
EVT_FT_FIXUP bootmeth_vbe_ft_fixup .*boot/vbe_request.c:.* EVT_FT_FIXUP bootmeth_vbe_ft_fixup .*boot/vbe_request.c:.*
EVT_FT_FIXUP bootmeth_vbe_simple_ft_fixup .*boot/vbe_simple_os.c:.* EVT_FT_FIXUP bootmeth_vbe_simple_ft_fixup .*boot/vbe_simple_os.c:.*
EVT_LAST_STAGE_INIT install_smbios_table .*lib/efi_loader/efi_smbios.c:.*
EVT_MISC_INIT_F sandbox_early_getopt_check .*arch/sandbox/cpu/start.c:.* EVT_MISC_INIT_F sandbox_early_getopt_check .*arch/sandbox/cpu/start.c:.*
EVT_TEST h_adder_simple .*test/common/event.c:''' EVT_TEST h_adder_simple .*test/common/event.c:'''
assert re.match(expect, out, re.MULTILINE) is not None assert re.match(expect, out, re.MULTILINE) is not None