diff options
Diffstat (limited to 'lib/efi_loader/efi_smbios.c')
-rw-r--r-- | lib/efi_loader/efi_smbios.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/lib/efi_loader/efi_smbios.c b/lib/efi_loader/efi_smbios.c new file mode 100644 index 00000000000..8d2ef6deb51 --- /dev/null +++ b/lib/efi_loader/efi_smbios.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * EFI application tables support + * + * Copyright (c) 2016 Alexander Graf + */ + +#define LOG_CATEGORY LOGC_EFI + +#include <efi_loader.h> +#include <log.h> +#include <malloc.h> +#include <mapmem.h> +#include <smbios.h> +#include <linux/sizes.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +const efi_guid_t smbios3_guid = SMBIOS3_TABLE_GUID; + +enum { + TABLE_SIZE = SZ_4K, +}; + +/* + * Install the SMBIOS table as a configuration table. + * + * Return: status code + */ +efi_status_t efi_smbios_register(void) +{ + ulong addr; + efi_status_t ret; + void *buf; + + addr = gd_smbios_start(); + if (!addr) { + log_err("No SMBIOS tables to install\n"); + return EFI_NOT_FOUND; + } + + /* Mark space used for tables */ + ret = efi_add_memory_map(addr, TABLE_SIZE, EFI_RUNTIME_SERVICES_DATA); + if (ret) + return ret; + + log_debug("EFI using SMBIOS tables at %lx\n", addr); + + /* Install SMBIOS information as configuration table */ + buf = map_sysmem(addr, 0); + ret = efi_install_configuration_table(&smbios3_guid, buf); + unmap_sysmem(buf); + + return ret; +} + +static int install_smbios_table(void) +{ + ulong addr; + void *buf; + + if (!IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE) || + IS_ENABLED(CONFIG_X86) || + IS_ENABLED(CONFIG_QFW_SMBIOS)) + return 0; + + /* Align the table to a 4KB boundary to keep EFI happy */ + buf = memalign(SZ_4K, TABLE_SIZE); + if (!buf) + return log_msg_ret("mem", -ENOMEM); + + 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); |