Files
u-boot-krane/cmd/efi_common.c
T
Aristo ChenandHeinrich Schuchardt e394b1e848 efi: Print ISA-specific and unknown memory attributes
The attribute mnemonic table did not cover EFI_MEMORY_ISA_VALID and the
EFI_MEMORY_ISA_MASK field, and attribute bits without a mnemonic were
silently dropped, so a memory map carrying ISA-specific, invalid or not
yet known attributes displayed incomplete information without any hint
that something was missing.

Add a mnemonic for EFI_MEMORY_ISA_VALID and print the ISA-specific
field as ISA=<value> when it is valid, instead of decoding bits whose
meaning U-Boot cannot know. Any remaining bits that match neither the
mnemonic table nor the ISA field are printed as a hexadecimal value.

Suggested-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Aristo Chen <aristo.chen@canonical.com>
2026-07-31 09:22:40 +02:00

161 lines
4.5 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Common code for EFI commands
*
* Copyright 2023 Google LLC
* Written by Simon Glass <sjg@chromium.org>
*/
#include <efi.h>
#include <efi_api.h>
#include <mapmem.h>
#include <u-boot/uuid.h>
/* Width of an EFI physical address in hexadecimal digits */
#define EFI_PHYS_ADDR_WIDTH (int)(sizeof(efi_physical_addr_t) * 2)
/* Width of the memory type column, sized for the longest type name */
#define EFI_MEM_TYPE_WIDTH 23
/*
* The type names of the UEFI specification without the leading 'Efi' and
* the trailing 'Type'
*/
static const char *const efi_mem_type_string[] = {
[EFI_RESERVED_MEMORY_TYPE] = "ReservedMemory",
[EFI_LOADER_CODE] = "LoaderCode",
[EFI_LOADER_DATA] = "LoaderData",
[EFI_BOOT_SERVICES_CODE] = "BootServicesCode",
[EFI_BOOT_SERVICES_DATA] = "BootServicesData",
[EFI_RUNTIME_SERVICES_CODE] = "RuntimeServicesCode",
[EFI_RUNTIME_SERVICES_DATA] = "RuntimeServicesData",
[EFI_CONVENTIONAL_MEMORY] = "ConventionalMemory",
[EFI_UNUSABLE_MEMORY] = "UnusableMemory",
[EFI_ACPI_RECLAIM_MEMORY] = "ACPIReclaimMemory",
[EFI_ACPI_MEMORY_NVS] = "ACPIMemoryNVS",
[EFI_MMAP_IO] = "MemoryMappedIO",
[EFI_MMAP_IO_PORT] = "MemoryMappedIOPortSpace",
[EFI_PAL_CODE] = "PalCode",
[EFI_PERSISTENT_MEMORY_TYPE] = "PersistentMemory",
[EFI_UNACCEPTED_MEMORY_TYPE] = "UnacceptedMemory",
};
static const struct efi_mem_attrs {
const u64 bit;
const char *text;
} efi_mem_attrs[] = {
{EFI_MEMORY_UC, "UC"},
{EFI_MEMORY_WC, "WC"},
{EFI_MEMORY_WT, "WT"},
{EFI_MEMORY_WB, "WB"},
{EFI_MEMORY_UCE, "UCE"},
{EFI_MEMORY_WP, "WP"},
{EFI_MEMORY_RP, "RP"},
{EFI_MEMORY_XP, "XP"},
{EFI_MEMORY_NV, "NV"},
{EFI_MEMORY_MORE_RELIABLE, "REL"},
{EFI_MEMORY_RO, "RO"},
{EFI_MEMORY_SP, "SP"},
{EFI_MEMORY_CPU_CRYPTO, "CRYPT"},
{EFI_MEMORY_HOT_PLUGGABLE, "HOTPL"},
{EFI_MEMORY_ISA_VALID, "ISA_VALID"},
{EFI_MEMORY_RUNTIME, "RT"},
};
void efi_show_tables(struct efi_system_table *systab)
{
int i;
for (i = 0; i < systab->nr_tables; i++) {
struct efi_configuration_table *tab = &systab->tables[i];
printf("%p %pUl %s\n", tab->table, tab->guid.b,
uuid_guid_get_str(tab->guid.b) ?: "(unknown)");
}
}
/**
* efi_mem_type_name() - get the name of an EFI memory type
*
* @type: memory type (enum efi_memory_type)
* Return: name of the memory type, or NULL if @type is unknown
*/
static const char *efi_mem_type_name(u32 type)
{
if (type >= ARRAY_SIZE(efi_mem_type_string))
return NULL;
return efi_mem_type_string[type];
}
/**
* efi_print_mem_attrs() - print the names of set EFI memory attributes
*
* Prints the set attribute bits as a '|'-separated list of mnemonics,
* e.g. ' UC|WB|RT', preceded by a space. When EFI_MEMORY_ISA_VALID is
* set, the EFI_MEMORY_ISA_MASK field is printed as ISA=<value>. Bits
* that have no mnemonic are printed as a hexadecimal value so that
* invalid or not yet known attributes are never dropped silently.
*
* @attributes: memory attributes (EFI_MEMORY_...)
*/
static void efi_print_mem_attrs(u64 attributes)
{
u64 unknown = attributes;
int sep, i;
for (sep = 0, i = 0; i < ARRAY_SIZE(efi_mem_attrs); i++)
if (attributes & efi_mem_attrs[i].bit) {
if (sep) {
putc('|');
} else {
putc(' ');
sep = 1;
}
puts(efi_mem_attrs[i].text);
unknown &= ~efi_mem_attrs[i].bit;
}
if (attributes & EFI_MEMORY_ISA_VALID) {
printf("%sISA=0x%llx", sep ? "|" : " ",
(attributes & EFI_MEMORY_ISA_MASK) >>
EFI_MEMORY_ISA_SHIFT);
sep = 1;
unknown &= ~EFI_MEMORY_ISA_MASK;
}
if (unknown)
printf("%s0x%llx", sep ? "|" : " ", unknown);
}
void efi_show_memmap(struct efi_mem_desc *map, efi_uintn_t map_size,
efi_uintn_t desc_size)
{
struct efi_mem_desc *end = (void *)map + map_size;
static const char sep[] = "========================";
const char *type;
printf("%-*s %-*s %-*s Attributes\n",
EFI_MEM_TYPE_WIDTH, "Type",
EFI_PHYS_ADDR_WIDTH, "Start", EFI_PHYS_ADDR_WIDTH, "End");
printf("%.*s %.*s %.*s ==========\n",
EFI_MEM_TYPE_WIDTH, sep,
EFI_PHYS_ADDR_WIDTH, sep, EFI_PHYS_ADDR_WIDTH, sep);
for (; map < end; map = efi_get_next_mem_desc(map, desc_size)) {
type = efi_mem_type_name(map->type) ?: "(unknown)";
printf("%-*s %.*llx-%.*llx", EFI_MEM_TYPE_WIDTH, type,
EFI_PHYS_ADDR_WIDTH,
(u64)map_to_sysmem((void *)(uintptr_t)
map->physical_start),
EFI_PHYS_ADDR_WIDTH,
(u64)map_to_sysmem((void *)(uintptr_t)
(map->physical_start +
map->num_pages * EFI_PAGE_SIZE)));
efi_print_mem_attrs(map->attribute);
putc('\n');
}
}