From 6abd738e20dd09bdebc9e2f9ad6162cc4b1c678e Mon Sep 17 00:00:00 2001 From: Aristo Chen Date: Fri, 24 Jul 2026 09:26:56 +0000 Subject: efi: Unify the memory map output of 'efi mem' and 'efidebug memmap' The efi and efidebug commands each carried their own code for printing the EFI memory map, with separate tables of memory type and attribute names. The copies had drifted: efidebug knew EFI_PERSISTENT_MEMORY_TYPE while 'efi mem' printed it as '', neither table knew EFI_UNACCEPTED_MEMORY_TYPE, and the 'efi mem' printer had misaligned column headers, a broken '' line and a superfluous Virtual column: the map is identity mapped before SetVirtualAddressMap() is called, so the field carries no information at the time the command can run. Move the printing loop of 'efidebug memmap' into efi_common.c as efi_show_memmap(), which is linked into both commands, and use it from both. The second copy in 'efi mem' is deleted together with efi_print_mem_table() and the private sorting and merging code, including the 'all' argument. The memory type names follow the UEFI specification with the leading 'Efi' and the trailing 'Type' stripped, for example ConventionalMemory for EfiConventionalMemory, and the missing name for unaccepted memory is added. The type column is widened to fit the longest name, MemoryMappedIOPortSpace. The shared function iterates the map with the descriptor size reported by the firmware instead of assuming sizeof(struct efi_mem_desc). This matters for 'efi mem' under EDK II based firmware, which reports a descriptor size of 0x30. The memory map key, which was printed uninitialized on the payload path, is now initialized. The command documentation is updated with output captured from the app running under OVMF, and documents why virtual addresses are not shown. Suggested-by: Heinrich Schuchardt Signed-off-by: Aristo Chen --- include/efi.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include') diff --git a/include/efi.h b/include/efi.h index b98871fedad..71234d1b6fe 100644 --- a/include/efi.h +++ b/include/efi.h @@ -681,6 +681,24 @@ int efi_get_mmap(struct efi_mem_desc **descp, int *sizep, uint *keyp, */ void efi_show_tables(struct efi_system_table *systab); +/** + * efi_show_memmap() - print an EFI memory map + * + * Prints one line per descriptor with the memory type name, the physical + * start and end address and the attributes as a '|'-separated list of + * mnemonics. + * + * The virtual addresses of the descriptors are not shown: the map is + * identity mapped before SetVirtualAddressMap() is called, so the field + * carries no information at this point. + * + * @map: memory map to print + * @map_size: size of the memory map in bytes + * @desc_size: size of a single descriptor in bytes + */ +void efi_show_memmap(struct efi_mem_desc *map, efi_uintn_t map_size, + efi_uintn_t desc_size); + /** * efi_get_basename() - Get the default filename to use when loading * -- cgit v1.3.1 From e394b1e848918019a0521f5e30f9f81d6e0d0ae6 Mon Sep 17 00:00:00 2001 From: Aristo Chen Date: Fri, 24 Jul 2026 09:26:57 +0000 Subject: 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= 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 Signed-off-by: Aristo Chen --- cmd/efi_common.c | 20 ++++++++++++++++++-- doc/usage/cmd/efi.rst | 5 ++++- include/efi.h | 7 ++++++- 3 files changed, 28 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/cmd/efi_common.c b/cmd/efi_common.c index 904747c5b32..e57835d3bae 100644 --- a/cmd/efi_common.c +++ b/cmd/efi_common.c @@ -58,6 +58,7 @@ static const struct efi_mem_attrs { {EFI_MEMORY_SP, "SP"}, {EFI_MEMORY_CPU_CRYPTO, "CRYPT"}, {EFI_MEMORY_HOT_PLUGGABLE, "HOTPL"}, + {EFI_MEMORY_ISA_VALID, "ISA_VALID"}, {EFI_MEMORY_RUNTIME, "RT"}, }; @@ -91,13 +92,16 @@ static const char *efi_mem_type_name(u32 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. Prints nothing if no known - * attribute bit is set. + * 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=. 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++) @@ -109,7 +113,19 @@ static void efi_print_mem_attrs(u64 attributes) 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, diff --git a/doc/usage/cmd/efi.rst b/doc/usage/cmd/efi.rst index 3ccdbe9410c..62a2638feca 100644 --- a/doc/usage/cmd/efi.rst +++ b/doc/usage/cmd/efi.rst @@ -45,7 +45,10 @@ Start, End Attributes The attributes of the region as a '|'-separated list of mnemonics, - e.g. UC for EFI_MEMORY_UC and RT for EFI_MEMORY_RUNTIME. + e.g. UC for EFI_MEMORY_UC and RT for EFI_MEMORY_RUNTIME. When the + region carries ISA-specific attributes (EFI_MEMORY_ISA_VALID is set), + the ISA-specific field is shown as ISA=. Attribute bits without + a mnemonic are shown as a hexadecimal value. efi tables ~~~~~~~~~~ diff --git a/include/efi.h b/include/efi.h index 71234d1b6fe..a4c21d7681d 100644 --- a/include/efi.h +++ b/include/efi.h @@ -268,6 +268,9 @@ enum efi_memory_type { #define EFI_MEMORY_CPU_CRYPTO ((u64)0x0000000000080000ULL) /* cryptographically protectable */ #define EFI_MEMORY_HOT_PLUGGABLE \ ((u64)0x0000000000100000ULL) /* hot pluggable */ +#define EFI_MEMORY_ISA_MASK ((u64)0x0FFFF00000000000ULL) /* ISA-specific attributes */ +#define EFI_MEMORY_ISA_SHIFT 44 +#define EFI_MEMORY_ISA_VALID ((u64)0x4000000000000000ULL) /* ISA_MASK field is valid */ #define EFI_MEMORY_RUNTIME ((u64)0x8000000000000000ULL) /* range requires runtime mapping */ #define EFI_MEM_DESC_VERSION 1 @@ -686,7 +689,9 @@ void efi_show_tables(struct efi_system_table *systab); * * Prints one line per descriptor with the memory type name, the physical * start and end address and the attributes as a '|'-separated list of - * mnemonics. + * mnemonics. The ISA-specific attribute field is printed as ISA= + * when EFI_MEMORY_ISA_VALID is set, and any remaining bits without a + * mnemonic are printed as a hexadecimal value. * * The virtual addresses of the descriptors are not shown: the map is * identity mapped before SetVirtualAddressMap() is called, so the field -- cgit v1.3.1