Compare commits

...

32 Commits

Author SHA1 Message Date
Simon Glass
76a1a9ce8f efi: app: Enable the cat command
This can be handy for looking at extlinux.conf files, so enable it for
the app.

Series-to: concept
Series-cc: heinrich
Cover-letter:
efi: Improvements for the EFI app on ARM
This series provides a number of minor improvements for the EFI app when
running on ARM machines (on top of Tianocore, for example):

- Tidy up various comments
- Show the ARM exception level in bdinfo
- Tidy up the output of 'meminfo'
- Get the addr_find command running
- Reduce verbosity when not debugging
- Show the model at the top of the diplay when using vidconsole
- Allow faking the boot right into the actual OS jump (for debugging)
END

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:35:41 -06:00
Simon Glass
e923d25a78 efi: app: Show the model when the vidconsole starts
When running with a vidconsole we only see the prompt at the top of
the display. Set the option to show the model as well.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:35:41 -06:00
Simon Glass
2b025c6c1c efi: arm: Increase the cyclic timeout again
The video sync sometimes takes 20ms on this board when running under
emulation, so increase the limit to 50ms.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:35:41 -06:00
Simon Glass
0c3dc93542 efi: app: Add a simplefb node to the devicetree
Use simplefb on ARM devices so that we see a console earlier, assuming
that 'console=tty0' is passed to Linux.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:35:41 -06:00
Simon Glass
9f9bff17eb efi: app: Only show the memory map when debugging
This is quite a long dump and is only useful when debugging. Show it
only if LOG_DEBUG is defined in this file.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:35:41 -06:00
Simon Glass
a305d76c6e efi: app: Use the relocated global_data
The new global_data is set up by the app but it never uses it. Switch to
the new value after board_init_f(), so that the output of the 'meminfo'
command is more contiguous.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:35:41 -06:00
Simon Glass
5e2b63b8b8 efi: app: Print the final message before freeing memory
Printing may make use of tables which could go away when freed, so do
the free as the last thing before exiting the app.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:35:41 -06:00
Simon Glass
ff97664455 efi: app: Use EFI_PAGE_SHIFT instead of 12 in free_memory()
Use the constant intended for this purpose, instead of open-coding the
value.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:35:41 -06:00
Simon Glass
7118db7ae9 efi: app: Pick up the SMBIOS table
If an SMBIOS table is available, pick it up so that it can be parsed, or
examined with the 'smbios' command.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:35:41 -06:00
Simon Glass
4a07ed2d83 efi: app: Allocate pages in any region
Rather than immediately falling back to the pool allocator when we
cannot get enough memory below 4GB, try the page allocator first. This
provides 4K-aligned memory, which is nicer to look at when debugging.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:35:41 -06:00
Simon Glass
742e122069 efi: app: Tidy up some stale comments in setup_memory()
A few comments are out of date. Drop the one about global_data_ptr and
reword the one about memory above 4GB.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:35:41 -06:00
Simon Glass
92523bdee6 efi: Fix up the addr_find command
This command was written before the lmb unification, so does not
currently build. Tidy it up and enable it for the EFI app, by default.

Also allow it to search any partition, not just a FAT one, since we may
have the kernel on ext4

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:35:41 -06:00
Simon Glass
03937028db efi: app: Show only a summary of disks and partitions
The EFI app shows a list of every disk and partition it can find. On
Qualcomm x1e laptops this can fill the screen. The information is not
that useful, so just show a summary.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:35:41 -06:00
Simon Glass
eb69e2e498 fdt: Add debugging for fdt_simplefb
Add some simple debug output to see what it is doing.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:35:41 -06:00
Simon Glass
fe5a8bf044 boot: Pass flags to the bootm_final event
For a fake go, we should tell the event not to actually do anything
irreversable, so pass the flag along.

Move the enum into a separate event_decl.h header file since otherwise
we must include bootm.h which causes a breakage with qemu-ppce500

We also don't want to pull event.h into the tools build, since it uses
types like u8 which are not available outside U-Boot

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:34:38 -06:00
Simon Glass
bd61bd5bdd boot: Improve debugging in bootm_load_os()
This shows an image type as an OS, which is not correct. Fix it up to
show both.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:10:35 -06:00
Simon Glass
75583b2c9f event: Add a dummy function for event_notify()
When CONFIG_EVENT is disabled, we should not try to send an event. This
is already handled for events without parameters, so handle it for
events that do have parameters, too.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 16:10:35 -06:00
Simon Glass
c173a64651 meminfo: Allow for up to 10 hex digits
On platforms where most of the memory is above 4GB, the EFI app may find
itself using addresses with 9 or even 10 digits. Expand the width of the
columns to cope with this.

Add some double bars across digits 9 and 8 so that it is easier to make
the value.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 15:11:49 -06:00
Simon Glass
c5286fae66 arm: Drop kernel_entry for arm64
This variable is tricky to set up and is only used to show an address.
Drop it and use the source variable instead.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 15:11:49 -06:00
Simon Glass
6ae03fbd9b arm: Show the exception level with bdinfo
Some machines start U-Boot in a different exception level, so provide a
way to view it.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 15:11:48 -06:00
Simon Glass
5fd8ea61aa arm: Fix swtiching typo
This should say 'switching', so fix it.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 15:11:11 -06:00
Simon Glass
9dedbc9738 arm: bootm: Add some debugging
Provides some debugging info while doing bootm processing.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 15:11:11 -06:00
Simon Glass
6268c3c145 smbios: Add support for showing table types 16 and 19
In some cases it is useful to find out the location of physical memory,
e.g. so that the memory@ nodes can be correctly set up in the
devicetree. Add support for parsing this information from the SMBIOS
tables.

Series-to: concept
Series-cc: heinrich
Cover-letter:
smbios: Refactor the smbios command and parser
The 'smbios' command has its own code for parsing SMBIOS tables. There
in also lib/smbios-parser.c which parses tables, although only
version 2.

This series moved parsing to lib/ and rationalises the code a little. It
also adds support for a few more tables.

Finally, a hook is added so operation from coreboot can be tested on
ellesmere.
END

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:46 -06:00
Simon Glass
68aea48c74 smbios: coreboot: Update smbios_get_header() to use smbios_info
Use the smbios_info struct in this function, so it can deal with any
version of SMBIOS table.

Also update smbios_update_version_full() to work the same way.

Drop find_next_header() which is now unused.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:46 -06:00
Simon Glass
69f0425961 smbios: Pass smbios_info to smbios_next_table()
At present smbios_next_table() does not support SMBIOS v2 tables. Pass
in the info struct so that it can check for the end of the tables.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:45 -06:00
Simon Glass
31d89f2dac smbios: Create a function to locate the tables
The code in the smbios command is a nice implementation of finding the
tables. It supports both SMBIOS2 and SMBIOS3, which smbios-parser.c does
not.

Move this code over to the library, creating a struct to hold the
result.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:45 -06:00
Simon Glass
00b2d3ea4e smbios: Move some parsing code to smbios-parser.c
The 'smbios' command has some parsing code, as does the SMBIOS parser
in the lib/ directory. Start to unify these by moving over a few
functions.

Require CONFIG_SMBIOS_PARSER to be enabled when using the command.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:45 -06:00
Simon Glass
1ab7ea8419 smbios: Rename smbios_header()
This function has the same name as the struct, which is confusing.
Rename it to smbios_get_header() and update the function comment a
little.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:45 -06:00
Simon Glass
f5576bd01b smbios: x86: Enable command by default
If SMBIOS is enabled on x86, enable the 'smbios' command by default,
so that the tables can be examined.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:45 -06:00
Simon Glass
a63ecb45b7 coreboot: Increase the cyclic limit
This fails in CI sometimes, so increase the limit to 50ms:

 cyclic_run() cyclic function video_init took too long: 20725us vs 5000us max

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:10 -06:00
Simon Glass
8145d7ea4b hooks: Add ellesmere riscv64_spl board
Add a symlink for this board to the travis-ci board.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 13:06:46 -06:00
Simon Glass
e7408cafdd hooks: ellesmere: Add a coreboot board
Add a coreboot board which can run under QEMU on ellesmere.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 11:44:52 -06:00
27 changed files with 508 additions and 195 deletions

View File

@@ -61,4 +61,11 @@ void arch_print_bdinfo(void)
printf("Early malloc usage: %x / %x\n", gd->malloc_ptr,
CONFIG_VAL(SYS_MALLOC_F_LEN));
#endif
#ifdef CONFIG_ARM64
ulong el;
/* the CurrentEL register holds the current Exception Level in bits 3:2 */
asm volatile("mrs %0, CurrentEL" : "=r" (el));
lprint_num_l("CurrentEL", el);
#endif
}

View File

@@ -11,6 +11,8 @@
* Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
*/
#define LOG_CATEGORY LOGC_BOOT
#include <bootm.h>
#include <bootstage.h>
#include <command.h>
@@ -154,7 +156,7 @@ static void do_nonsec_virt_switch(void)
{
if (ll_boot_init()) {
smp_kick_all_cpus();
dcache_disable(); /* flush cache before swtiching to EL2 */
dcache_disable(); /* flush cache before switching to EL2 */
}
}
#endif
@@ -258,15 +260,10 @@ static void switch_to_el1(void)
static void boot_jump_linux(struct bootm_headers *images, int flag)
{
#ifdef CONFIG_ARM64
void (*kernel_entry)(void *fdt_addr, void *res0, void *res1,
void *res2);
int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
kernel_entry = (void (*)(void *fdt_addr, void *res0, void *res1,
void *res2))images->ep;
debug("## Transferring control to Linux (at address %lx)...\n",
(ulong) kernel_entry);
(ulong)images->ep);
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
bootm_final(fake ? BOOTM_FINAL_FAKE : 0);
@@ -349,20 +346,24 @@ int do_bootm_linux(int flag, struct bootm_info *bmi)
{
struct bootm_headers *images = bmi->images;
log_debug("boot linux flag %x\n", flag);
/* No need for those on ARM */
if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE)
return -1;
if (flag & BOOTM_STATE_OS_PREP) {
log_debug("linux prep\n");
boot_prep_linux(images);
return 0;
}
if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {
log_debug("go/fake\n");
boot_jump_linux(images, flag);
return 0;
}
log_debug("cont\n");
boot_prep_linux(images);
boot_jump_linux(images, flag);
return 0;

View File

@@ -55,15 +55,15 @@ static int cb_get_str(struct udevice *dev, int id, size_t size, char *val)
static int cb_detect(struct udevice *dev)
{
struct cb_sysinfo_priv *priv = dev_get_priv(dev);
const struct smbios_entry *smbios;
struct smbios_info info;
int ret;
smbios = smbios_entry(lib_sysinfo.smbios_start,
lib_sysinfo.smbios_size);
if (!smbios)
ret = smbios_locate(lib_sysinfo.smbios_start, &info);
if (ret)
return 0;
priv->bios = smbios_header(smbios, SMBIOS_BIOS_INFORMATION);
priv->system = smbios_header(smbios, SMBIOS_SYSTEM_INFORMATION);
priv->bios = smbios_get_header(&info, SMBIOS_BIOS_INFORMATION);
priv->system = smbios_get_header(&info, SMBIOS_SYSTEM_INFORMATION);
priv->t0 = (struct smbios_type0 *)priv->bios;
priv->t1 = (struct smbios_type1 *)priv->system;

View File

@@ -30,6 +30,10 @@ int board_exit_boot_services(void *ctx, struct event *evt)
uint key;
int ret;
if (evt->data.bootm_final.flags & BOOTM_FINAL_FAKE) {
printf("Not exiting EFI (fake go)\n");
return 0;
}
printf("Exiting EFI\n");
ret = efi_get_mmap(&desc, &size, &key, &desc_size, &version);
if (ret) {

View File

@@ -773,7 +773,8 @@ static int bootm_load_os(struct bootm_info *bmi, int boot_progress)
ulong decomp_len;
int err;
log_debug("load_os type '%s' comp '%s'\n",
log_debug("load_os type '%s' os '%s' comp '%s'\n",
genimg_get_type_short_name(os.type),
genimg_get_os_short_name(os.type),
genimg_get_comp_short_name(os.comp));
/*

View File

@@ -17,6 +17,7 @@ __weak void board_quiesce_devices(void)
void bootm_final(enum bootm_final_t flags)
{
struct event_bootm_final final;
int ret;
printf("\nStarting kernel ...%s\n\n", flags & BOOTM_FINAL_FAKE ?
@@ -43,15 +44,17 @@ void bootm_final(enum bootm_final_t flags)
*/
dm_remove_devices_active();
ret = event_notify_null(EVT_BOOTM_FINAL);
final.flags = flags;
ret = event_notify(EVT_BOOTM_FINAL, &final, sizeof(final));
if (ret) {
printf("Event handler failed to finalise (err %dE\n",
ret);
return;
}
if (!(flags & BOOTM_FINAL_FAKE)) {
bootm_disable_interrupts();
bootm_disable_interrupts();
if (!(flags & BOOTM_FINAL_NO_CLEANUP))
cleanup_before_linux();
if (!(flags & BOOTM_FINAL_NO_CLEANUP))
cleanup_before_linux();
}
}

View File

@@ -6,6 +6,8 @@
* Stephen Warren <swarren@wwwdotorg.org>
*/
#define LOG_CATEGORY LOGC_BOOT
#include <dm.h>
#include <fdt_support.h>
#include <asm/global_data.h>
@@ -48,6 +50,8 @@ static int fdt_simplefb_configure_node(void *blob, int off)
ysize = uc_priv->ysize;
bpix = uc_priv->bpix;
fb_base = plat->base;
log_debug("simplefb: fb %lx x %d y %d bpix %x\n", fb_base,
xsize, ysize, bpix);
}
switch (bpix) {

View File

@@ -129,7 +129,8 @@ config CMD_ACPI
want to make hardware changes without the OS needing to be adjusted.
config CMD_ADDR_FIND
bool "addr_find"
bool "addr_find"
default y if EFI_APP
help
This command searches for an unused region of address space
sufficiently large to hold a file. If successful, it sets the
@@ -267,6 +268,7 @@ config CMD_SBI
config CMD_SMBIOS
bool "smbios"
depends on SMBIOS
select SMBIOS_PARSER
help
Display the SMBIOS information.

View File

@@ -16,19 +16,17 @@ DECLARE_GLOBAL_DATA_PTR;
int do_addr_find(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
struct lmb_region *mem, *reserved;
const char *filename;
struct lmb lmb;
loff_t size;
ulong addr;
int ret;
int i, j;
if (!gd->fdt_blob) {
log_err("No FDT setup\n");
return CMD_RET_FAILURE;
}
if (fs_set_blk_dev(argv[1], argc >= 3 ? argv[2] : NULL, FS_TYPE_FAT)) {
if (fs_set_blk_dev(argv[1], argc >= 3 ? argv[2] : NULL, FS_TYPE_ANY)) {
log_err("Can't set block device\n");
return CMD_RET_FAILURE;
}
@@ -49,32 +47,20 @@ int do_addr_find(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
return CMD_RET_FAILURE;
}
lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
mem = &lmb.memory;
reserved = &lmb.reserved;
for (i = 0; i < mem->cnt; i++) {
unsigned long long start, end;
start = mem->region[i].base;
end = mem->region[i].base + mem->region[i].size - 1;
if ((start + size) > end)
continue;
for (j = 0; j < reserved->cnt; j++) {
if ((reserved->region[j].base + reserved->region[j].size) < start)
continue;
if ((start + size) > reserved->region[j].base)
start = reserved->region[j].base + reserved->region[j].size;
}
if ((start + size) <= end) {
env_set_hex("loadaddr", start);
debug("Set loadaddr to 0x%llx\n", start);
return CMD_RET_SUCCESS;
}
addr = lmb_alloc(size, SZ_1M);
if (!addr) {
log_err("Failed to find enough RAM for 0x%llx bytes\n", size);
return CMD_RET_FAILURE;
}
log_err("Failed to find enough RAM for 0x%llx bytes\n", size);
return CMD_RET_FAILURE;
if (env_set_hex("loadaddr", addr)) {
log_err("Could not set loadaddr\n");
return CMD_RET_FAILURE;
}
log_debug("Set loadaddr to %lx\n", addr);
return CMD_RET_SUCCESS;
}
U_BOOT_CMD(

View File

@@ -19,9 +19,9 @@ static void print_region(const char *name, ulong base, ulong size, ulong *uptop)
{
ulong end = base + size;
printf("%-12s %8lx %8lx %8lx", name, base, size, end);
printf("%-12s %10lx %10lx %10lx", name, base, size, end);
if (*uptop)
printf(" %8lx", *uptop - end);
printf(" %10lx", *uptop - end);
putc('\n');
*uptop = base;
}
@@ -58,9 +58,10 @@ static int do_meminfo(struct cmd_tbl *cmdtp, int flag, int argc,
if (!IS_ENABLED(CONFIG_CMD_MEMINFO_MAP))
return 0;
printf("\n%-12s %8s %8s %8s %8s\n", "Region", "Base", "Size", "End",
printf("\n%-12s %10s %10s %10s %10s\n", "Region", "|| Base",
"|| Size", "|| End",
"Gap");
printf("------------------------------------------------\n");
printf("--------------------------------------------------------\n");
upto = 0;
if (IS_ENABLED(CONFIG_VIDEO))
print_region("video", gd_video_bottom(),

View File

@@ -6,6 +6,7 @@
*/
#include <command.h>
#include <errno.h>
#include <hexdump.h>
#include <mapmem.h>
#include <smbios.h>
@@ -116,45 +117,46 @@ static const struct str_lookup_table associativity_strings[] = {
{ SMBIOS_CACHE_ASSOC_48WAY, "48-way Set-Associative" },
{ SMBIOS_CACHE_ASSOC_64WAY, "64-way Set-Associative" },
{ SMBIOS_CACHE_ASSOC_20WAY, "20-way Set-Associative" },
};
/**
* smbios_get_string() - get SMBIOS string from table
*
* @table: SMBIOS table
* @index: index of the string
* Return: address of string, may point to empty string
*/
static const char *smbios_get_string(void *table, int index)
{
const char *str = (char *)table +
((struct smbios_header *)table)->length;
static const char fallback[] = "";
static const struct str_lookup_table mem_array_location_strings[] = {
{ 0x01, "Other" },
{ 0x02, "Unknown" },
{ 0x03, "System board or motherboard" },
{ 0x04, "ISA add-on card" },
{ 0x05, "EISA add-on card" },
{ 0x06, "PCI add-on card" },
{ 0x07, "MCA add-on card" },
{ 0x08, "PCMCIA add-on card" },
{ 0x09, "Proprietary add-on card" },
{ 0x0A, "NuBus" },
{ 0xA0, "PC-98/C20 add-on card" },
{ 0xA1, "PC-98/C24 add-on card" },
{ 0xA2, "PC-98/E add-on card" },
{ 0xA3, "PC-98/Local bus add-on card" },
};
if (!index)
return fallback;
static const struct str_lookup_table mem_array_use_strings[] = {
{ 0x01, "Other" },
{ 0x02, "Unknown" },
{ 0x03, "System memory" },
{ 0x04, "Video memory" },
{ 0x05, "Flash memory" },
{ 0x06, "Non-volatile RAM" },
{ 0x07, "Cache memory" },
};
if (!*str)
++str;
for (--index; *str && index; --index)
str += strlen(str) + 1;
static const struct str_lookup_table mem_err_corr_strings[] = {
{ 0x01, "Other" },
{ 0x02, "Unknown" },
{ 0x03, "None" },
{ 0x04, "Parity" },
{ 0x05, "Single-bit ECC" },
{ 0x06, "Multi-bit ECC" },
{ 0x07, "CRC" },
};
return str;
}
static struct smbios_header *next_table(struct smbios_header *table)
{
const char *str;
if (table->type == SMBIOS_END_OF_TABLE)
return NULL;
str = smbios_get_string(table, -1);
return (struct smbios_header *)(++str);
}
static void smbios_print_generic(struct smbios_header *table)
static void smbios_print_generic(const struct smbios_header *table)
{
char *str = (char *)table + table->length;
@@ -403,6 +405,62 @@ static void smbios_print_type7(struct smbios_type7 *table)
printf("\tInstalled Cache Size 2: 0x%08x\n", table->inst_size2.data);
}
static void smbios_print_type16(struct smbios_type16 *table)
{
u64 capacity;
printf("Physical Memory Array\n");
smbios_print_lookup_str(mem_array_location_strings, table->location,
ARRAY_SIZE(mem_array_location_strings),
"Location");
smbios_print_lookup_str(mem_array_use_strings, table->use,
ARRAY_SIZE(mem_array_use_strings), "Use");
smbios_print_lookup_str(mem_err_corr_strings, table->error_correction,
ARRAY_SIZE(mem_err_corr_strings),
"Error Correction");
capacity = table->maximum_capacity;
if (capacity == 0x7fffffff &&
table->hdr.length >= offsetof(struct smbios_type16,
extended_maximum_capacity)) {
capacity = table->extended_maximum_capacity;
printf("\tMaximum Capacity: %llu GB\n", capacity >> 30);
} else if (capacity > 0) {
printf("\tMaximum Capacity: %llu MB\n", capacity >> 10);
} else {
printf("\tMaximum Capacity: No limit\n");
}
printf("\tError Information Handle: 0x%04x\n",
table->error_information_handle);
printf("\tNumber Of Devices: %u\n", table->number_of_memory_devices);
}
static void smbios_print_type19(struct smbios_type19 *table)
{
u64 start_addr, end_addr;
printf("Memory Array Mapped Address\n");
/* Check if extended address fields are present (SMBIOS v2.7+) */
if (table->hdr.length >= 0x1f) {
start_addr = table->extended_starting_address;
end_addr = table->extended_ending_address;
} else {
start_addr = table->starting_address;
end_addr = table->ending_address;
}
/* The ending address is the address of the last 1KB block */
if (end_addr != 0xffffffff && end_addr != 0xffffffffffffffff)
end_addr = (end_addr + 1) * 1024 - 1;
printf("\tStarting Address: 0x%016llx\n", start_addr);
printf("\tEnding Address: 0x%016llx\n", end_addr);
printf("\tMemory Array Handle: 0x%04x\n", table->memory_array_handle);
printf("\tPartition Width: %u\n", table->partition_width);
}
static void smbios_print_type127(struct smbios_type127 *table)
{
printf("End Of Table\n");
@@ -411,55 +469,31 @@ static void smbios_print_type127(struct smbios_type127 *table)
static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
ulong addr;
void *entry;
u32 size;
char version[12];
struct smbios_header *table;
static const char smbios_sig[] = "_SM_";
static const char smbios3_sig[] = "_SM3_";
size_t count = 0;
u32 table_maximum_size;
struct smbios_info info;
int ret;
addr = gd_smbios_start();
if (!addr) {
ret = smbios_locate(gd_smbios_start(), &info);
if (ret == -ENOENT) {
log_warning("SMBIOS not available\n");
return CMD_RET_FAILURE;
}
entry = map_sysmem(addr, 0);
if (!memcmp(entry, smbios3_sig, sizeof(smbios3_sig) - 1)) {
struct smbios3_entry *entry3 = entry;
table = (void *)(uintptr_t)entry3->struct_table_address;
snprintf(version, sizeof(version), "%d.%d.%d",
entry3->major_ver, entry3->minor_ver, entry3->doc_rev);
table = (void *)(uintptr_t)entry3->struct_table_address;
size = entry3->length;
table_maximum_size = entry3->table_maximum_size;
} else if (!memcmp(entry, smbios_sig, sizeof(smbios_sig) - 1)) {
struct smbios_entry *entry2 = entry;
snprintf(version, sizeof(version), "%d.%d",
entry2->major_ver, entry2->minor_ver);
table = (void *)(uintptr_t)entry2->struct_table_address;
size = entry2->length;
table_maximum_size = entry2->struct_table_length;
} else {
if (ret == -EINVAL) {
log_err("Unknown SMBIOS anchor format\n");
return CMD_RET_FAILURE;
}
if (table_compute_checksum(entry, size)) {
if (ret == -EIO) {
log_err("Invalid anchor checksum\n");
return CMD_RET_FAILURE;
}
printf("SMBIOS %s present.\n", version);
printf("SMBIOS %d.%d.%d present.\n", info.version >> 16,
(info.version >> 8) & 0xff, info.version & 0xff);
for (struct smbios_header *pos = table; pos; pos = next_table(pos))
++count;
printf("%zd structures occupying %d bytes\n", count, table_maximum_size);
printf("Table at 0x%llx\n", (unsigned long long)map_to_sysmem(table));
printf("%d structures occupying %d bytes\n", info.count, info.max_size);
printf("Table at 0x%llx\n",
(unsigned long long)map_to_sysmem(info.table));
for (struct smbios_header *pos = table; pos; pos = next_table(pos)) {
for (struct smbios_header *pos = info.table; pos;
pos = smbios_next_table(&info, pos)) {
printf("\nHandle 0x%04x, DMI type %d, %d bytes at 0x%llx\n",
pos->handle, pos->type, pos->length,
(unsigned long long)map_to_sysmem(pos));
@@ -482,6 +516,12 @@ static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc,
case SMBIOS_CACHE_INFORMATION:
smbios_print_type7((struct smbios_type7 *)pos);
break;
case SMBIOS_PHYS_MEMORY_ARRAY:
smbios_print_type16((struct smbios_type16 *)pos);
break;
case SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS:
smbios_print_type19((struct smbios_type19 *)pos);
break;
case SMBIOS_END_OF_TABLE:
smbios_print_type127((struct smbios_type127 *)pos);
break;

View File

@@ -32,6 +32,7 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_MISC_INIT_R=y
CONFIG_HUSH_PARSER=y
CONFIG_CMD_CPU=y
# CONFIG_CMD_SMBIOS is not set
CONFIG_CMD_GPIO=y
CONFIG_CMD_PART=y
CONFIG_CMD_SPI=y

View File

@@ -23,6 +23,7 @@ CONFIG_LOG=y
CONFIG_LOGF_LINE=y
CONFIG_LOGF_FUNC=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_CYCLIC_MAX_CPU_TIME_US=50000
CONFIG_PCI_INIT_R=y
CONFIG_CMD_IDE=y
CONFIG_CMD_MMC=y

View File

@@ -15,18 +15,21 @@ CONFIG_FIT=y
CONFIG_BOOTSTD_FULL=y
CONFIG_SHOW_BOOT_PROGRESS=y
CONFIG_OF_SYSTEM_SETUP=y
CONFIG_FDT_SIMPLEFB=y
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTCOMMAND="bootflow scan -lbp"
CONFIG_SYS_PBSIZE=532
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_LOG=y
CONFIG_CYCLIC_MAX_CPU_TIME_US=15000
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_CYCLIC_MAX_CPU_TIME_US=50000
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_MEMINFO=y
CONFIG_CMD_MEMINFO_MAP=y
CONFIG_CMD_DM=y
CONFIG_CMD_LSBLK=y
CONFIG_CMD_CAT=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_TIME=y
CONFIG_CMD_EXT4_WRITE=y

View File

@@ -7,6 +7,7 @@
#ifndef _BOOTM_H
#define _BOOTM_H
#include <event_decl.h>
#include <image.h>
struct boot_params;
@@ -16,18 +17,6 @@ struct cmd_tbl;
#define BOOTM_ERR_OVERLAP (-2)
#define BOOTM_ERR_UNIMPLEMENTED (-3)
/**
* enum bootm_final_t - flags to control bootm_final()
*
* @BOOTM_FINAL_FAKE: true to do everything except actually boot; it then
* returns to the caller
* @BOOTM_FINAL_NO_CLEANUP: true to skip calling cleanup_before_linux()
*/
enum bootm_final_t {
BOOTM_FINAL_FAKE = BIT(0),
BOOTM_FINAL_NO_CLEANUP = BIT(1),
};
/**
* struct bootm_info() - information used when processing images to boot
*

View File

@@ -12,6 +12,7 @@
#include <dm/ofnode_decl.h>
#include <linux/types.h>
#include <event_decl.h>
/**
* enum event_t - Types of events supported by U-Boot
@@ -260,6 +261,15 @@ union event_data {
struct event_ft_fixup_f {
oftree tree;
} ft_fixup_f;
/**
* struct event_bootm_final - State information
*
* @flags: Flags passed to bootm_final()
*/
struct event_bootm_final {
enum bootm_final_t flags;
} bootm_final;
};
/**
@@ -402,6 +412,7 @@ void event_show_spy_list(void);
*/
const char *event_type_name(enum event_t type);
#if CONFIG_IS_ENABLED(EVENT)
/**
* event_notify() - notify spies about an event
*
@@ -416,7 +427,6 @@ const char *event_type_name(enum event_t type);
*/
int event_notify(enum event_t type, void *data, int size);
#if CONFIG_IS_ENABLED(EVENT)
/**
* event_notify_null() - notify spies about an event
*
@@ -431,6 +441,11 @@ static inline int event_notify_null(enum event_t type)
{
return 0;
}
static inline int event_notify(enum event_t type, void *data, int size)
{
return 0;
}
#endif
#if CONFIG_IS_ENABLED(EVENT_DYNAMIC)

27
include/event_decl.h Normal file
View File

@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Declarations needed by events
*
* Copyright 2025 Simon Glass <sjg@chromium.org>
*/
#ifndef __event_decl_h
#define __event_decl_h
#include <linux/bitops.h>
/**
* enum bootm_final_t - flags to control bootm_final()
*
* Note that this is defined in event.h since it is used by events
*
* @BOOTM_FINAL_FAKE: true to do everything except actually boot; it then
* returns to the caller
* @BOOTM_FINAL_NO_CLEANUP: true to skip calling cleanup_before_linux()
*/
enum bootm_final_t {
BOOTM_FINAL_FAKE = BIT(0),
BOOTM_FINAL_NO_CLEANUP = BIT(1),
};
#endif

View File

@@ -15,6 +15,23 @@
#define SMBIOS_MAJOR_VER 3
#define SMBIOS_MINOR_VER 7
/**
* struct smbios_info - Information about SMBIOS tables
*
* @table: Pointer to the first table
* @count: Number of tables
* @max_size: Maximum size of the tables pointed to by struct_table_address
* @version: table version in the form 0xMMmmrr, where MM is the major version
* number (2 or 3), mm is the minor version number and rr is * the revision
* (always 0 for major-version 2)
*/
struct smbios_info {
struct smbios_header *table;
int count;
int max_size;
int version;
};
enum {
SMBIOS_STR_MAX = 64, /* Maximum length allowed for a string */
};
@@ -264,6 +281,31 @@ struct __packed smbios_type7 {
char eos[SMBIOS_STRUCT_EOS_BYTES];
};
struct __packed smbios_type16 {
struct smbios_header hdr;
u8 location;
u8 use;
u8 error_correction;
u32 maximum_capacity;
u16 error_information_handle;
u16 number_of_memory_devices;
/* The following field is only present in SMBIOS v2.7+ */
u64 extended_maximum_capacity;
char eos[SMBIOS_STRUCT_EOS_BYTES];
};
struct __packed smbios_type19 {
struct smbios_header hdr;
u32 starting_address;
u32 ending_address;
u16 memory_array_handle;
u8 partition_width;
/* The following fields are only present in SMBIOS v2.7+ */
u64 extended_starting_address;
u64 extended_ending_address;
char eos[SMBIOS_STRUCT_EOS_BYTES];
};
struct __packed smbios_type32 {
u8 type;
u8 length;
@@ -325,13 +367,14 @@ ulong write_smbios_table(ulong addr);
const struct smbios_entry *smbios_entry(u64 address, u32 size);
/**
* smbios_header() - Search for SMBIOS header type
* smbios_get_header() - Search for an SMBIOS header type
*
* @entry: pointer to a struct smbios_entry
* @entry: pointer to the first entry
* @type: SMBIOS type
* @return: NULL or a valid pointer to a struct smbios_header
*/
const struct smbios_header *smbios_header(const struct smbios_entry *entry, int type);
const struct smbios_header *smbios_get_header(const struct smbios_info *info,
int type);
/**
* smbios_string() - Return string from SMBIOS
@@ -379,8 +422,39 @@ int smbios_update_version_full(void *smbios_tab, const char *version);
*
* @entry: pointer to a struct smbios3_entry
* @header: pointer to a struct smbios_header
* @table_maximum_size: number of bytes used by the tables at @header
*/
void smbios_prepare_measurement(const struct smbios3_entry *entry,
struct smbios_header *header);
struct smbios_header *smbios_copy,
int table_maximum_size);
/**
* smbios_get_string() - get SMBIOS string from table
*
* @table: SMBIOS table
* @index: index of the string
* Return: address of string, may point to empty string
*/
const char *smbios_get_string(void *table, int index);
/**
* smbios_next_table() - Find the next table
*
* @info: SMBIOS info
* @table: Table to start from
* Return: Pointer to the next table, or NULL if @table is the last
*/
struct smbios_header *smbios_next_table(const struct smbios_info *info,
struct smbios_header *table);
/**
* smbios_locate() - Locate the SMBIOS tables
*
* @addr: Address of SMBIOS table, typically gd_smbios_start()
* @info: Returns the SMBIOS info, on success
* Return: 0 if OK, -ENOENT if no table is present, -EINVAL if the header
* signature is not recognised, -EIO if the checksum is wrong
*/
int smbios_locate(ulong addr, struct smbios_info *info);
#endif /* _SMBIOS_H_ */

View File

@@ -191,4 +191,38 @@
#define SMBIOS_CACHE_ASSOC_64WAY 13
#define SMBIOS_CACHE_ASSOC_20WAY 14
/* Physical Memory Array */
#define SMBIOS_MEM_ARRAY_LOCATION_OTHER 0x01
#define SMBIOS_MEM_ARRAY_LOCATION_UNKNOWN 0x02
#define SMBIOS_MEM_ARRAY_LOCATION_SYSTEM_BOARD 0x03
#define SMBIOS_MEM_ARRAY_LOCATION_ISA_ADDON 0x04
#define SMBIOS_MEM_ARRAY_LOCATION_EISA_ADDON 0x05
#define SMBIOS_MEM_ARRAY_LOCATION_PCI_ADDON 0x06
#define SMBIOS_MEM_ARRAY_LOCATION_MCA_ADDON 0x07
#define SMBIOS_MEM_ARRAY_LOCATION_PCMCIA_ADDON 0x08
#define SMBIOS_MEM_ARRAY_LOCATION_PROPRIETARY_ADDON 0x09
#define SMBIOS_MEM_ARRAY_LOCATION_NUBUS 0x0a
#define SMBIOS_MEM_ARRAY_LOCATION_PC98_C20_ADDON 0xa0
#define SMBIOS_MEM_ARRAY_LOCATION_PC98_C24_ADDON 0xa1
#define SMBIOS_MEM_ARRAY_LOCATION_PC98_E_ADDON 0xa2
#define SMBIOS_MEM_ARRAY_LOCATION_PC98_LOCAL_BUS_ADDON 0xa3
#define SMBIOS_MEM_ARRAY_USE_OTHER 0x01
#define SMBIOS_MEM_ARRAY_USE_UNKNOWN 0x02
#define SMBIOS_MEM_ARRAY_USE_SYSTEM 0x03
#define SMBIOS_MEM_ARRAY_USE_VIDEO 0x04
#define SMBIOS_MEM_ARRAY_USE_FLASH 0x05
#define SMBIOS_MEM_ARRAY_USE_NON_VOLATILE_RAM 0x06
#define SMBIOS_MEM_ARRAY_USE_CACHE 0x07
#define SMBIOS_MEM_ERR_CORR_OTHER 0x01
#define SMBIOS_MEM_ERR_CORR_UNKNOWN 0x02
#define SMBIOS_MEM_ERR_CORR_NONE 0x03
#define SMBIOS_MEM_ERR_CORR_PARITY 0x04
#define SMBIOS_MEM_ERR_CORR_SINGLE_BIT_ECC 0x05
#define SMBIOS_MEM_ERR_CORR_MULTI_BIT_ECC 0x06
#define SMBIOS_MEM_ERR_CORR_CRC 0x07
#define SMBIOS_MEM_CAPACITY_EXTENDED 0x80000000
#endif /* _SMBIOS_DEF_H_ */

View File

@@ -1168,9 +1168,10 @@ config SPL_OID_REGISTRY
config SMBIOS
bool "SMBIOS support"
depends on X86 || EFI_LOADER
depends on X86 || EFI_LOADER || EFI_APP
default y
select LAST_STAGE_INIT
imply CMD_SMBIOS if X86
help
Indicates that this platform can support System Management BIOS
(SMBIOS) tables. These provide various pieces of information about
@@ -1182,6 +1183,7 @@ config SMBIOS
config SMBIOS_PARSER
bool "SMBIOS parser"
default y if EFI_APP
help
A simple parser for SMBIOS data.

View File

@@ -8,6 +8,8 @@
* This file implements U-Boot running as an EFI application.
*/
#define LOG_CATEGORY LOGC_EFI
#include <cpu_func.h>
#include <debug_uart.h>
#include <dm.h>
@@ -15,6 +17,7 @@
#include <efi_api.h>
#include <efi_stub.h>
#include <errno.h>
#include <fdt_simplefb.h>
#include <image.h>
#include <init.h>
#include <malloc.h>
@@ -92,11 +95,6 @@ static efi_status_t setup_memory(struct efi_priv *priv)
efi_status_t ret;
int pages;
/*
* Use global_data_ptr instead of gd since it is an assignment. There
* are very few assignments to global_data in U-Boot and this makes
* it easier to find them.
*/
ptr = efi_malloc(priv, sizeof(*ptr), &ret);
if (!ptr)
return ret;
@@ -111,12 +109,17 @@ static efi_status_t setup_memory(struct efi_priv *priv)
pages = CONFIG_EFI_RAM_SIZE >> 12;
/*
* Don't allocate any memory above 4GB. U-Boot is a 32-bit application
* so we want it to load below 4GB.
* Try not to allocate any memory above 4GB, just for ease of looking at
* addresses.
*/
addr = 1ULL << 32;
ret = boot->allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
priv->image_data_type, pages, &addr);
if (ret) {
log_info("(any address) ");
ret = boot->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
priv->image_data_type, pages, &addr);
}
if (ret) {
log_info("(using pool %lx) ", ret);
priv->ram_base = (ulong)efi_malloc(priv, CONFIG_EFI_RAM_SIZE,
@@ -128,6 +131,7 @@ static efi_status_t setup_memory(struct efi_priv *priv)
log_info("(using allocated RAM address %lx) ", (ulong)addr);
priv->ram_base = addr;
}
gd->ram_base = addr;
gd->ram_size = pages << 12;
return 0;
@@ -148,7 +152,8 @@ static void free_memory(struct efi_priv *priv)
if (priv->use_pool_for_malloc)
efi_free(priv, (void *)priv->ram_base);
else
boot->free_pages(priv->ram_base, gd->ram_size >> 12);
boot->free_pages(priv->ram_base,
gd->ram_size >> EFI_PAGE_SHIFT);
efi_free(priv, (void *)gd->malloc_base);
efi_free(priv, (void *)gd);
@@ -158,6 +163,7 @@ static void free_memory(struct efi_priv *priv)
static void scan_tables(struct efi_system_table *sys_table)
{
efi_guid_t acpi = EFI_ACPI_TABLE_GUID;
efi_guid_t smbios = SMBIOS3_TABLE_GUID;
uint i;
for (i = 0; i < sys_table->nr_tables; i++) {
@@ -165,6 +171,8 @@ static void scan_tables(struct efi_system_table *sys_table)
if (!memcmp(&tab->guid, &acpi, sizeof(efi_guid_t)))
gd_set_acpi_start(map_to_sysmem(tab->table));
else if (!memcmp(&tab->guid, &smbios, sizeof(efi_guid_t)))
gd->arch.smbios_start = map_to_sysmem(tab->table);
}
}
@@ -216,6 +224,7 @@ efi_status_t EFIAPI efi_main(efi_handle_t image,
printf("starting\n");
board_init_f(GD_FLG_SKIP_RELOC);
gd = gd->new_gd;
board_init_r(NULL, 0);
free_memory(priv);
@@ -226,8 +235,8 @@ static void efi_exit(void)
{
struct efi_priv *priv = efi_get_priv();
free_memory(priv);
printf("U-Boot EFI exiting\n");
free_memory(priv);
priv->boot->exit(priv->parent_image, EFI_SUCCESS, 0, NULL);
}
@@ -301,7 +310,9 @@ int ft_system_setup(void *fdt, struct bd_info *bd)
if (ret)
return log_msg_ret("erm", ret);
efi_dump_mem_table(map, size, desc_size, false);
if (_DEBUG)
efi_dump_mem_table(map, size, desc_size, false);
ram_start = -1ULL;
ram_end = -1ULL;
end = (void *)map + size;
@@ -329,6 +340,12 @@ int ft_system_setup(void *fdt, struct bd_info *bd)
return ret;
}
ret = fdt_simplefb_add_node(fdt);
if (ret) {
printf("failed to set up simplefb\n");
return ret;
}
free(map);
return 0;

View File

@@ -128,6 +128,7 @@ static int setup_block(void)
struct efi_device_path_to_text_protocol *text;
struct efi_device_path *path;
struct efi_block_io *blkio;
int num_disks, num_parts;
efi_uintn_t num_handles;
efi_handle_t *handle;
int ret, i;
@@ -150,7 +151,7 @@ static int setup_block(void)
if (ret)
return log_msg_ret("text", -ENOTSUPP);
for (i = 0; i < num_handles; i++) {
for (num_disks = 0, num_parts = 0, i = 0; i < num_handles; i++) {
struct udevice *dev;
const u16 *name;
bool is_part;
@@ -174,6 +175,7 @@ static int setup_block(void)
is_part = devpath_is_partition(path);
if (!is_part) {
num_disks++;
len = util->get_device_path_size(path);
ret = efi_bind_block(handle[i], blkio, path, len, &dev);
if (ret) {
@@ -183,15 +185,17 @@ static int setup_block(void)
}
} else {
dev = NULL;
num_parts++;
}
/*
* Show the device name if we created one. Otherwise indicate
* that it is a partition.
*/
printf("%2d: %-12s %ls\n", i, dev ? dev->name : "<partition>",
name);
log_debug("%2d: %-12s %ls\n", i,
dev ? dev->name : "<partition>", name);
}
log_info("EFI: disks %d, partitions %d\n", num_disks, num_parts);
boot->free_pool(handle);
return 0;

View File

@@ -1127,7 +1127,8 @@ tcg2_measure_smbios(struct udevice *dev,
(void *)((uintptr_t)entry->struct_table_address),
entry->table_maximum_size);
smbios_prepare_measurement(entry, smbios_copy);
smbios_prepare_measurement(entry, smbios_copy,
entry->table_maximum_size);
ret = measure_event(dev, 1, EV_EFI_HANDOFF_TABLES2, event_size,
(u8 *)event);

View File

@@ -6,11 +6,46 @@
#define LOG_CATEGORY LOGC_BOOT
#include <errno.h>
#include <mapmem.h>
#include <smbios.h>
#include <string.h>
#include <tables_csum.h>
#include <asm/global_data.h>
#include <linux/kernel.h>
DECLARE_GLOBAL_DATA_PTR;
const char *smbios_get_string(void *table, int index)
{
const char *str = (char *)table +
((struct smbios_header *)table)->length;
static const char fallback[] = "";
if (!index)
return fallback;
if (!*str)
++str;
for (--index; *str && index; --index)
str += strlen(str) + 1;
return str;
}
struct smbios_header *smbios_next_table(const struct smbios_info *info,
struct smbios_header *table)
{
const char *str;
if ((ulong)table - (ulong)info->table >= info->max_size)
return NULL;
if (table->type == SMBIOS_END_OF_TABLE)
return NULL;
str = smbios_get_string(table, -1);
return (struct smbios_header *)(++str);
}
const struct smbios_entry *smbios_entry(u64 address, u32 size)
{
const struct smbios_entry *entry = (struct smbios_entry *)(uintptr_t)address;
@@ -27,35 +62,17 @@ const struct smbios_entry *smbios_entry(u64 address, u32 size)
return entry;
}
static u8 *find_next_header(u8 *pos)
const struct smbios_header *smbios_get_header(const struct smbios_info *info,
int type)
{
/* search for _double_ NULL bytes */
while (!((*pos == 0) && (*(pos + 1) == 0)))
pos++;
struct smbios_header *header;
/* step behind the double NULL bytes */
pos += 2;
return pos;
}
static struct smbios_header *get_next_header(const struct smbios_header *curr)
{
u8 *pos = ((u8 *)curr) + curr->length;
return (struct smbios_header *)find_next_header(pos);
}
const struct smbios_header *smbios_header(const struct smbios_entry *entry, int type)
{
const unsigned int num_header = entry->struct_count;
const struct smbios_header *header = (struct smbios_header *)((uintptr_t)entry->struct_table_address);
for (unsigned int i = 0; i < num_header; i++) {
for (header = info->table; header;
header = smbios_next_table(info, header)) {
if (header->type == type)
return header;
header = get_next_header(header);
header = smbios_next_table(info, header);
}
return NULL;
@@ -90,15 +107,21 @@ char *smbios_string(const struct smbios_header *header, int index)
return string_from_smbios_table(header, index);
}
int smbios_update_version_full(void *smbios_tab, const char *version)
int smbios_update_version_full(void *smbios_tab, const char *new_version)
{
const struct smbios_header *hdr;
struct smbios_info info;
struct smbios_type0 *bios;
uint old_len, len;
char *ptr;
int ret;
ret = smbios_locate(map_to_sysmem(smbios_tab), &info);
if (ret)
return log_msg_ret("tab", -ENOENT);
log_info("Updating SMBIOS table at %p\n", smbios_tab);
hdr = smbios_header(smbios_tab, SMBIOS_BIOS_INFORMATION);
hdr = smbios_get_header(&info, SMBIOS_BIOS_INFORMATION);
if (!hdr)
return log_msg_ret("tab", -ENOENT);
bios = (struct smbios_type0 *)hdr;
@@ -113,12 +136,12 @@ int smbios_update_version_full(void *smbios_tab, const char *version)
* are not disturbed. See smbios_add_string()
*/
old_len = strnlen(ptr, SMBIOS_STR_MAX);
len = strnlen(version, SMBIOS_STR_MAX);
len = strnlen(new_version, SMBIOS_STR_MAX);
if (len > old_len)
return log_ret(-ENOSPC);
log_debug("Replacing SMBIOS type 0 version string '%s'\n", ptr);
memcpy(ptr, version, len);
memcpy(ptr, new_version, len);
#ifdef LOG_DEBUG
print_buffer((ulong)ptr, ptr, 1, old_len + 1, 0);
#endif
@@ -224,23 +247,26 @@ static void clear_smbios_table(struct smbios_header *header,
}
void smbios_prepare_measurement(const struct smbios3_entry *entry,
struct smbios_header *smbios_copy)
struct smbios_header *smbios_copy,
int table_maximum_size)
{
u32 i, j;
void *table_end;
struct smbios_header *header;
struct smbios_info info;
u32 i;
table_end = (void *)((u8 *)smbios_copy + entry->table_maximum_size);
info.table = smbios_copy;
info.count = 0; /* unknown */
info.max_size = table_maximum_size;
info.version = 3 << 16;
for (i = 0; i < ARRAY_SIZE(smbios_filter_tables); i++) {
header = smbios_copy;
for (j = 0; (void *)header < table_end; j++) {
struct smbios_header *header;
for (header = info.table; header;
header = smbios_next_table(&info, header)) {
if (header->type == smbios_filter_tables[i].type)
break;
header = get_next_header(header);
}
if ((void *)header >= table_end)
if (!header)
continue;
clear_smbios_table(header,
@@ -248,3 +274,44 @@ void smbios_prepare_measurement(const struct smbios3_entry *entry,
smbios_filter_tables[i].count);
}
}
int smbios_locate(ulong addr, struct smbios_info *info)
{
static const char smbios3_sig[] = "_SM3_";
static const char smbios_sig[] = "_SM_";
void *entry;
uint size;
if (!addr)
return -ENOENT;
entry = map_sysmem(addr, 0);
if (!memcmp(entry, smbios3_sig, sizeof(smbios3_sig) - 1)) {
struct smbios3_entry *entry3 = entry;
info->table = (void *)(uintptr_t)entry3->struct_table_address;
info->version = entry3->major_ver << 16 |
entry3->minor_ver << 8 | entry3->doc_rev;
size = entry3->length;
info->max_size = entry3->table_maximum_size;
} else if (!memcmp(entry, smbios_sig, sizeof(smbios_sig) - 1)) {
struct smbios_entry *entry2 = entry;
info->version = entry2->major_ver << 16 |
entry2->minor_ver << 8;
info->table = (void *)(uintptr_t)entry2->struct_table_address;
size = entry2->length;
info->max_size = entry2->struct_table_length;
} else {
return -EINVAL;
}
if (table_compute_checksum(entry, size))
return -EIO;
info->count = 0;
for (struct smbios_header *pos = info->table; pos;
pos = smbios_next_table(info, pos))
info->count++;
return 0;
}

View File

@@ -17,7 +17,7 @@ static int cmd_test_meminfo(struct unit_test_state *uts)
ut_assert_nextline("DRAM: 256 MiB");
ut_assert_nextline_empty();
ut_assert_nextline("Region Base Size End Gap");
ut_assert_nextline("Region || Base || Size || End Gap");
ut_assert_nextlinen("-");
/* For now we don't worry about checking the values */

View File

@@ -0,0 +1,28 @@
# Copyright (c) 2016 Konsulko Group. All rights reserved.
# Copyright 2021 Google LLC
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
console_impl=qemu
qemu_machine="pc"
qemu_binary="qemu-system-i386"
qemu_extra_args="-nographic -cpu qemu32 -netdev user,id=net0,tftp=${UBOOT_TRAVIS_BUILD_DIR} -device e1000,netdev=net0"
qemu_kernel_args="-bios ${U_BOOT_BUILD_DIR}/coreboot.rom"
reset_impl=none
flash_impl=none

View File

@@ -0,0 +1 @@
../travis-ci/conf.qemu-riscv64_spl_na