]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
efi: Unify the memory map output of 'efi mem' and 'efidebug memmap'
authorAristo Chen <aristo.chen@canonical.com>
Fri, 24 Jul 2026 09:26:56 +0000 (09:26 +0000)
committerHeinrich Schuchardt <heinrich.schuchardt@canonical.com>
Fri, 31 Jul 2026 07:21:02 +0000 (09:21 +0200)
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 '<invalid>', neither table knew
EFI_UNACCEPTED_MEMORY_TYPE, and the 'efi mem' printer had misaligned
column headers, a broken '<gap>' 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 <xypron.glpk@gmx.de>
Signed-off-by: Aristo Chen <aristo.chen@canonical.com>
cmd/efi.c
cmd/efi_common.c
cmd/efidebug.c
doc/usage/cmd/efi.rst
include/efi.h

index 687ccb5204282a42e3c984ef5bd422c3c9e743dc..c49a873f3da37b83a12731166d5a2e1cd52dd64f 100644 (file)
--- a/cmd/efi.c
+++ b/cmd/efi.c
 #include <errno.h>
 #include <log.h>
 #include <malloc.h>
-#include <sort.h>
 #include <u-boot/uuid.h>
 #include <asm/global_data.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static const char *const type_name[] = {
-       "reserved",
-       "loader_code",
-       "loader_data",
-       "bs_code",
-       "bs_data",
-       "rt_code",
-       "rt_data",
-       "conv",
-       "unusable",
-       "acpi_reclaim",
-       "acpi_nvs",
-       "io",
-       "io_port",
-       "pal_code",
-};
-
-static struct attr_info {
-       u64 val;
-       const char *name;
-} mem_attr[] = {
-       { EFI_MEMORY_UC, "uncached" },
-       { EFI_MEMORY_WC, "write-coalescing" },
-       { EFI_MEMORY_WT, "write-through" },
-       { EFI_MEMORY_WB, "write-back" },
-       { EFI_MEMORY_UCE, "uncached & exported" },
-       { EFI_MEMORY_WP, "write-protect" },
-       { EFI_MEMORY_RP, "read-protect" },
-       { EFI_MEMORY_XP, "execute-protect" },
-       { EFI_MEMORY_NV, "non-volatile" },
-       { EFI_MEMORY_MORE_RELIABLE, "higher reliability" },
-       { EFI_MEMORY_RO, "read-only" },
-       { EFI_MEMORY_SP, "specific purpose" },
-       { EFI_MEMORY_RUNTIME, "needs runtime mapping" }
-};
-
-/* Maximum different attribute values we can track */
-#define ATTR_SEEN_MAX  30
-
-static inline bool is_boot_services(int type)
-{
-       return type == EFI_LOADER_CODE || type == EFI_LOADER_DATA ||
-               type == EFI_BOOT_SERVICES_CODE ||
-               type == EFI_BOOT_SERVICES_DATA;
-}
-
-static int h_cmp_entry(const void *v1, const void *v2)
-{
-       const struct efi_mem_desc *desc1 = v1;
-       const struct efi_mem_desc *desc2 = v2;
-       int64_t diff = desc1->physical_start - desc2->physical_start;
-
-       /*
-        * Manually calculate the difference to avoid sign loss in the 64-bit
-        * to 32-bit conversion
-        */
-       return diff < 0 ? -1 : diff > 0 ? 1 : 0;
-}
-
-/**
- * efi_build_mem_table() - make a sorted copy of the memory table
- *
- * @desc_base: Pointer to EFI memory map table
- * @size:      Size of table in bytes
- * @desc_size: Size of each @desc_base record
- * @skip_bs:   True to skip boot-time memory and merge it with conventional
- *             memory. This will significantly reduce the number of table
- *             entries.
- * Return:     pointer to the new table. It should be freed with free() by the
- *             caller.
- */
-static void *efi_build_mem_table(struct efi_mem_desc *desc_base, int size,
-                                int desc_size, bool skip_bs)
-{
-       struct efi_mem_desc *desc, *end, *base, *dest, *prev;
-       int count;
-       u64 addr;
-
-       base = malloc(size + sizeof(*desc));
-       if (!base) {
-               debug("%s: Cannot allocate %#x bytes\n", __func__, size);
-               return NULL;
-       }
-       end = (void *)desc_base + size;
-       count = ((ulong)end - (ulong)desc_base) / desc_size;
-       memcpy(base, desc_base, (ulong)end - (ulong)desc_base);
-       qsort(base, count, desc_size, h_cmp_entry);
-       prev = NULL;
-       addr = 0;
-       dest = base;
-       end = (struct efi_mem_desc *)((ulong)base + count * desc_size);
-       for (desc = base; desc < end;
-            desc = efi_get_next_mem_desc(desc, desc_size)) {
-               bool merge = true;
-               u32 type = desc->type;
-
-               if (type >= EFI_MAX_MEMORY_TYPE) {
-                       printf("Memory map contains invalid entry type %u\n",
-                              type);
-                       continue;
-               }
-
-               if (skip_bs && is_boot_services(desc->type))
-                       type = EFI_CONVENTIONAL_MEMORY;
-
-               memcpy(dest, desc, desc_size);
-               dest->type = type;
-               if (!skip_bs || !prev)
-                       merge = false;
-               else if (desc->physical_start != addr)
-                       merge = false;
-               else if (type != EFI_CONVENTIONAL_MEMORY)
-                       merge = false;
-               else if (prev->type != EFI_CONVENTIONAL_MEMORY)
-                       merge = false;
-
-               if (merge) {
-                       prev->num_pages += desc->num_pages;
-               } else {
-                       prev = dest;
-                       dest = efi_get_next_mem_desc(dest, desc_size);
-               }
-               addr = desc->physical_start + (desc->num_pages <<
-                               EFI_PAGE_SHIFT);
-       }
-
-       /* Mark the end */
-       dest->type = EFI_MAX_MEMORY_TYPE;
-
-       return base;
-}
-
-static void efi_print_mem_table(struct efi_mem_desc *desc, int desc_size,
-                               bool skip_bs)
-{
-       u64 attr_seen[ATTR_SEEN_MAX];
-       int attr_seen_count;
-       int upto, i;
-       u64 addr;
-
-       printf(" #  %-14s  %10s  %10s  %10s  %s\n", "Type", "Physical",
-              "Virtual", "Size", "Attributes");
-
-       /* Keep track of all the different attributes we have seen */
-       attr_seen_count = 0;
-       addr = 0;
-       for (upto = 0; desc->type != EFI_MAX_MEMORY_TYPE;
-            upto++, desc = efi_get_next_mem_desc(desc, desc_size)) {
-               const char *name;
-               u64 size;
-
-               if (skip_bs && is_boot_services(desc->type))
-                       continue;
-               if (desc->physical_start != addr) {
-                       printf("    %-14s  %010llx  %10s  %010llx\n", "<gap>",
-                              addr, "", desc->physical_start - addr);
-               }
-               size = desc->num_pages << EFI_PAGE_SHIFT;
-
-               name = desc->type < ARRAY_SIZE(type_name) ?
-                               type_name[desc->type] : "<invalid>";
-               printf("%2d  %x:%-12s  %010llx  %010llx  %010llx  ", upto,
-                      desc->type, name, desc->physical_start,
-                      desc->virtual_start, size);
-               if (desc->attribute & EFI_MEMORY_RUNTIME)
-                       putc('r');
-               printf("%llx", desc->attribute & ~EFI_MEMORY_RUNTIME);
-               putc('\n');
-
-               for (i = 0; i < attr_seen_count; i++) {
-                       if (attr_seen[i] == desc->attribute)
-                               break;
-               }
-               if (i == attr_seen_count && i < ATTR_SEEN_MAX)
-                       attr_seen[attr_seen_count++] = desc->attribute;
-               addr = desc->physical_start + size;
-       }
-
-       printf("\nAttributes key:\n");
-       for (i = 0; i < attr_seen_count; i++) {
-               u64 attr = attr_seen[i];
-               bool first;
-               int j;
-
-               printf("%c%llx: ", (attr & EFI_MEMORY_RUNTIME) ? 'r' : ' ',
-                      attr & ~EFI_MEMORY_RUNTIME);
-               for (j = 0, first = true; j < ARRAY_SIZE(mem_attr); j++) {
-                       if (attr & mem_attr[j].val) {
-                               if (first)
-                                       first = false;
-                               else
-                                       printf(", ");
-                               printf("%s", mem_attr[j].name);
-                       }
-               }
-               putc('\n');
-       }
-       if (skip_bs)
-               printf("*Some areas are merged (use 'all' to see)\n");
-}
-
 static int do_efi_mem(struct cmd_tbl *cmdtp, int flag, int argc,
                      char *const argv[])
 {
-       struct efi_mem_desc *orig, *desc;
-       uint version, key;
+       struct efi_mem_desc *orig;
+       uint version, key = 0;
        int desc_size;
        int size, ret;
-       bool skip_bs;
 
-       skip_bs = !argc || *argv[0] != 'a';
        if (IS_ENABLED(CONFIG_EFI_APP)) {
                ret = efi_get_mmap(&orig, &size, &key, &desc_size, &version);
                if (ret) {
@@ -257,14 +53,7 @@ static int do_efi_mem(struct cmd_tbl *cmdtp, int flag, int argc,
                goto done;
        }
 
-       desc = efi_build_mem_table(orig, size, desc_size, skip_bs);
-       if (!desc) {
-               ret = -ENOMEM;
-               goto done;
-       }
-
-       efi_print_mem_table(desc, desc_size, skip_bs);
-       free(desc);
+       efi_show_memmap(orig, size, desc_size);
        if (IS_ENABLED(CONFIG_EFI_APP))
                free(orig);
 done:
@@ -300,7 +89,7 @@ static int do_efi_tables(struct cmd_tbl *cmdtp, int flag, int argc,
 }
 
 static struct cmd_tbl efi_commands[] = {
-       U_BOOT_CMD_MKENT(mem, 1, 1, do_efi_mem, "", ""),
+       U_BOOT_CMD_MKENT(mem, 0, 1, do_efi_mem, "", ""),
        U_BOOT_CMD_MKENT(tables, 1, 1, do_efi_tables, "", ""),
 };
 
@@ -325,6 +114,6 @@ static int do_efi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 U_BOOT_CMD(
        efi,     3,      1,      do_efi,
        "EFI access",
-       "mem [all]        Dump memory information [include boot services]\n"
+       "mem              Dump memory map\n"
        "tables               Dump tables"
 );
index d2f2b59e9e3b75df628fa307063d4ffa4a21401b..904747c5b32fa4cd6268123483c4ec0d9c653574 100644 (file)
@@ -8,8 +8,59 @@
 
 #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_RUNTIME, "RT"},
+};
+
 void efi_show_tables(struct efi_system_table *systab)
 {
        int i;
@@ -21,3 +72,73 @@ void efi_show_tables(struct efi_system_table *systab)
                       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. Prints nothing if no known
+ * attribute bit is set.
+ *
+ * @attributes: memory attributes (EFI_MEMORY_...)
+ */
+static void efi_print_mem_attrs(u64 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);
+               }
+}
+
+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');
+       }
+}
index a6faa36b500a066f61e601b2ce629ccdd5d36917..e55de04c69946f03ff5995e7f9eec4a1ddb9dbb0 100644 (file)
@@ -574,70 +574,6 @@ static int do_efi_show_ecpt(struct cmd_tbl *cmdtp, int flag, int argc,
 }
 #endif /* CONFIG_IS_ENABLED(EFI_ECPT) */
 
-static const char * const efi_mem_type_string[] = {
-       [EFI_RESERVED_MEMORY_TYPE] = "RESERVED",
-       [EFI_LOADER_CODE] = "LOADER CODE",
-       [EFI_LOADER_DATA] = "LOADER DATA",
-       [EFI_BOOT_SERVICES_CODE] = "BOOT CODE",
-       [EFI_BOOT_SERVICES_DATA] = "BOOT DATA",
-       [EFI_RUNTIME_SERVICES_CODE] = "RUNTIME CODE",
-       [EFI_RUNTIME_SERVICES_DATA] = "RUNTIME DATA",
-       [EFI_CONVENTIONAL_MEMORY] = "CONVENTIONAL",
-       [EFI_UNUSABLE_MEMORY] = "UNUSABLE MEM",
-       [EFI_ACPI_RECLAIM_MEMORY] = "ACPI RECLAIM MEM",
-       [EFI_ACPI_MEMORY_NVS] = "ACPI NVS",
-       [EFI_MMAP_IO] = "IO",
-       [EFI_MMAP_IO_PORT] = "IO PORT",
-       [EFI_PAL_CODE] = "PAL",
-       [EFI_PERSISTENT_MEMORY_TYPE] = "PERSISTENT",
-};
-
-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_RUNTIME, "RT"},
-};
-
-/**
- * print_memory_attributes() - print memory map attributes
- *
- * @attributes:        Attribute value
- *
- * Print memory map attributes
- */
-static void print_memory_attributes(u64 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);
-               }
-}
-
-#define EFI_PHYS_ADDR_WIDTH (int)(sizeof(efi_physical_addr_t) * 2)
-
 /**
  * do_efi_show_memmap() - show UEFI memory map
  *
@@ -653,43 +589,15 @@ static void print_memory_attributes(u64 attributes)
 static int do_efi_show_memmap(struct cmd_tbl *cmdtp, int flag,
                              int argc, char *const argv[])
 {
-       struct efi_mem_desc *memmap, *map;
+       struct efi_mem_desc *memmap;
        efi_uintn_t map_size;
-       const char *type;
-       int i;
        efi_status_t ret;
 
        ret = efi_get_memory_map_alloc(&map_size, &memmap);
        if (ret != EFI_SUCCESS)
                return CMD_RET_FAILURE;
 
-       printf("Type             Start%.*s End%.*s Attributes\n",
-              EFI_PHYS_ADDR_WIDTH - 5, spc, EFI_PHYS_ADDR_WIDTH - 3, spc);
-       printf("================ %.*s %.*s ==========\n",
-              EFI_PHYS_ADDR_WIDTH, sep, EFI_PHYS_ADDR_WIDTH, sep);
-       /*
-        * Coverity check: dereferencing null pointer "map."
-        * This is a false positive as memmap will always be
-        * populated by allocate_pool() above.
-        */
-       for (i = 0, map = memmap; i < map_size / sizeof(*map); map++, i++) {
-               if (map->type < ARRAY_SIZE(efi_mem_type_string))
-                       type = efi_mem_type_string[map->type];
-               else
-                       type = "(unknown)";
-
-               printf("%-16s %.*llx-%.*llx", 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)));
-
-               print_memory_attributes(map->attribute);
-               putc('\n');
-       }
+       efi_show_memmap(memmap, map_size, sizeof(*memmap));
 
        efi_free_pool(memmap);
 
index b19d36188a991f0122a455431747f3d8b6571e64..3ccdbe9410c375de2150493b4bb5c336956a7d03 100644 (file)
@@ -12,7 +12,7 @@ Synopsis
 
 ::
 
-    efi mem [all]
+    efi mem
     efi tables
 
 Description
@@ -29,34 +29,23 @@ happened.
 efi mem
 ~~~~~~~
 
-This shows the EFI memory map, sorted in order of physical address.
-
-This is normally a very large table. To help reduce the amount of detritus,
-boot-time memory is normally merged with conventional memory. Use the 'all'
-argument to show everything.
-
-The fields are as follows:
-
-#
-    Entry number (sequentially from 0)
+This shows the EFI memory map in the same format as the *efidebug memmap*
+command. One line is printed per memory region with the following fields:
 
 Type
-    Memory type. EFI has a large number of memory types. The type is shown in
-    the format <n>:<name> where in is the format number in hex and <name> is the
-    name.
+    Memory type, named as in the UEFI specification without the leading
+    'Efi' and the trailing 'Type', e.g. ConventionalMemory for
+    EfiConventionalMemory.
 
-Physical
-    Physical address
-
-Virtual
-    Virtual address
-
-Size
-    Size of memory area in bytes
+Start, End
+    Physical start and end address of the region. The virtual addresses of
+    the regions are not shown: the memory map is identity mapped when this
+    command can be used, i.e. before SetVirtualAddressMap() is called, so
+    the virtual address field of the memory map carries no information.
 
 Attributes
-    Shows a code for memory attributes. The key for this is shown below the
-    table.
+    The attributes of the region as a '|'-separated list of mnemonics,
+    e.g. UC for EFI_MEMORY_UC and RT for EFI_MEMORY_RUNTIME.
 
 efi tables
 ~~~~~~~~~~
@@ -72,142 +61,139 @@ Example
 ::
 
     => efi mem
-    EFI table at 0, memory map 000000001ad38b60, size 1260, key a79, version 1, descr. size 0x30
-     #  Type              Physical     Virtual        Size  Attributes
-     0  7:conv          0000000000  0000000000  00000a0000  f
-        <gap>           00000a0000              0000060000
-     1  7:conv          0000100000  0000000000  0000700000  f
-     2  a:acpi_nvs      0000800000  0000000000  0000008000  f
-     3  7:conv          0000808000  0000000000  0000008000  f
-     4  a:acpi_nvs      0000810000  0000000000  00000f0000  f
-     5  7:conv          0000900000  0000000000  001efef000  f
-     6  6:rt_data       001f8ef000  0000000000  0000100000  rf
-     7  5:rt_code       001f9ef000  0000000000  0000100000  rf
-     8  0:reserved      001faef000  0000000000  0000080000  f
-     9  9:acpi_reclaim  001fb6f000  0000000000  0000010000  f
-    10  a:acpi_nvs      001fb7f000  0000000000  0000080000  f
-    11  7:conv          001fbff000  0000000000  0000359000  f
-    12  6:rt_data       001ff58000  0000000000  0000020000  rf
-    13  a:acpi_nvs      001ff78000  0000000000  0000088000  f
-        <gap>           0020000000              0090000000
-    14  0:reserved      00b0000000  0000000000  0010000000  1
-
-    Attributes key:
-     f: uncached, write-coalescing, write-through, write-back
-    rf: uncached, write-coalescing, write-through, write-back, needs runtime mapping
-     1: uncached
-    *Some areas are merged (use 'all' to see)
-
-
-    => efi mem  all
-    EFI table at 0, memory map 000000001ad38bb0, size 1260, key a79, version 1, descr. size 0x30
-     #  Type              Physical     Virtual        Size  Attributes
-     0  3:bs_code       0000000000  0000000000  0000001000  f
-     1  7:conv          0000001000  0000000000  000009f000  f
-        <gap>           00000a0000              0000060000
-     2  7:conv          0000100000  0000000000  0000700000  f
-     3  a:acpi_nvs      0000800000  0000000000  0000008000  f
-     4  7:conv          0000808000  0000000000  0000008000  f
-     5  a:acpi_nvs      0000810000  0000000000  00000f0000  f
-     6  4:bs_data       0000900000  0000000000  0000c00000  f
-     7  7:conv          0001500000  0000000000  000aa36000  f
-     8  2:loader_data   000bf36000  0000000000  0010000000  f
-     9  4:bs_data       001bf36000  0000000000  0000020000  f
-    10  7:conv          001bf56000  0000000000  00021e1000  f
-    11  1:loader_code   001e137000  0000000000  00000c4000  f
-    12  7:conv          001e1fb000  0000000000  000009b000  f
-    13  1:loader_code   001e296000  0000000000  00000e2000  f
-    14  7:conv          001e378000  0000000000  000005b000  f
-    15  4:bs_data       001e3d3000  0000000000  000001e000  f
-    16  7:conv          001e3f1000  0000000000  0000016000  f
-    17  4:bs_data       001e407000  0000000000  0000016000  f
-    18  2:loader_data   001e41d000  0000000000  0000002000  f
-    19  4:bs_data       001e41f000  0000000000  0000828000  f
-    20  3:bs_code       001ec47000  0000000000  0000045000  f
-    21  4:bs_data       001ec8c000  0000000000  0000001000  f
-    22  3:bs_code       001ec8d000  0000000000  000000e000  f
-    23  4:bs_data       001ec9b000  0000000000  0000001000  f
-    24  3:bs_code       001ec9c000  0000000000  000002c000  f
-    25  4:bs_data       001ecc8000  0000000000  0000001000  f
-    26  3:bs_code       001ecc9000  0000000000  000000c000  f
-    27  4:bs_data       001ecd5000  0000000000  0000006000  f
-    28  3:bs_code       001ecdb000  0000000000  0000014000  f
-    29  4:bs_data       001ecef000  0000000000  0000001000  f
-    30  3:bs_code       001ecf0000  0000000000  000005b000  f
-    31  4:bs_data       001ed4b000  0000000000  000000b000  f
-    32  3:bs_code       001ed56000  0000000000  0000024000  f
-    33  4:bs_data       001ed7a000  0000000000  0000006000  f
-    34  3:bs_code       001ed80000  0000000000  0000010000  f
-    35  4:bs_data       001ed90000  0000000000  0000002000  f
-    36  3:bs_code       001ed92000  0000000000  0000025000  f
-    37  4:bs_data       001edb7000  0000000000  0000003000  f
-    38  3:bs_code       001edba000  0000000000  0000011000  f
-    39  4:bs_data       001edcb000  0000000000  0000008000  f
-    40  3:bs_code       001edd3000  0000000000  000002d000  f
-    41  4:bs_data       001ee00000  0000000000  0000201000  f
-    42  3:bs_code       001f001000  0000000000  0000024000  f
-    43  4:bs_data       001f025000  0000000000  0000002000  f
-    44  3:bs_code       001f027000  0000000000  0000009000  f
-    45  4:bs_data       001f030000  0000000000  0000005000  f
-    46  3:bs_code       001f035000  0000000000  000002f000  f
-    47  4:bs_data       001f064000  0000000000  0000001000  f
-    48  3:bs_code       001f065000  0000000000  0000005000  f
-    49  4:bs_data       001f06a000  0000000000  0000005000  f
-    50  3:bs_code       001f06f000  0000000000  0000007000  f
-    51  4:bs_data       001f076000  0000000000  0000007000  f
-    52  3:bs_code       001f07d000  0000000000  000000d000  f
-    53  4:bs_data       001f08a000  0000000000  0000001000  f
-    54  3:bs_code       001f08b000  0000000000  0000006000  f
-    55  4:bs_data       001f091000  0000000000  0000004000  f
-    56  3:bs_code       001f095000  0000000000  000000d000  f
-    57  4:bs_data       001f0a2000  0000000000  0000003000  f
-    58  3:bs_code       001f0a5000  0000000000  0000026000  f
-    59  4:bs_data       001f0cb000  0000000000  0000005000  f
-    60  3:bs_code       001f0d0000  0000000000  0000019000  f
-    61  4:bs_data       001f0e9000  0000000000  0000004000  f
-    62  3:bs_code       001f0ed000  0000000000  0000024000  f
-    63  4:bs_data       001f111000  0000000000  0000008000  f
-    64  3:bs_code       001f119000  0000000000  000000b000  f
-    65  4:bs_data       001f124000  0000000000  0000001000  f
-    66  3:bs_code       001f125000  0000000000  0000002000  f
-    67  4:bs_data       001f127000  0000000000  0000002000  f
-    68  3:bs_code       001f129000  0000000000  0000009000  f
-    69  4:bs_data       001f132000  0000000000  0000003000  f
-    70  3:bs_code       001f135000  0000000000  0000005000  f
-    71  4:bs_data       001f13a000  0000000000  0000003000  f
-    72  3:bs_code       001f13d000  0000000000  0000005000  f
-    73  4:bs_data       001f142000  0000000000  0000003000  f
-    74  3:bs_code       001f145000  0000000000  0000011000  f
-    75  4:bs_data       001f156000  0000000000  000000b000  f
-    76  3:bs_code       001f161000  0000000000  0000009000  f
-    77  4:bs_data       001f16a000  0000000000  0000400000  f
-    78  3:bs_code       001f56a000  0000000000  0000006000  f
-    79  4:bs_data       001f570000  0000000000  0000001000  f
-    80  3:bs_code       001f571000  0000000000  0000001000  f
-    81  4:bs_data       001f572000  0000000000  0000002000  f
-    82  3:bs_code       001f574000  0000000000  0000017000  f
-    83  4:bs_data       001f58b000  0000000000  0000364000  f
-    84  6:rt_data       001f8ef000  0000000000  0000100000  rf
-    85  5:rt_code       001f9ef000  0000000000  0000100000  rf
-    86  0:reserved      001faef000  0000000000  0000080000  f
-    87  9:acpi_reclaim  001fb6f000  0000000000  0000010000  f
-    88  a:acpi_nvs      001fb7f000  0000000000  0000080000  f
-    89  4:bs_data       001fbff000  0000000000  0000201000  f
-    90  7:conv          001fe00000  0000000000  00000e8000  f
-    91  4:bs_data       001fee8000  0000000000  0000020000  f
-    92  3:bs_code       001ff08000  0000000000  0000026000  f
-    93  4:bs_data       001ff2e000  0000000000  0000009000  f
-    94  3:bs_code       001ff37000  0000000000  0000021000  f
-    95  6:rt_data       001ff58000  0000000000  0000020000  rf
-    96  a:acpi_nvs      001ff78000  0000000000  0000088000  f
-        <gap>           0020000000              0090000000
-    97  0:reserved      00b0000000  0000000000  0010000000  1
-
-    Attributes key:
-     f: uncached, write-coalescing, write-through, write-back
-    rf: uncached, write-coalescing, write-through, write-back, needs runtime mapping
-     1: uncached
-
+    EFI table at 0, memory map 000000001a977d90, size 1860, key 9e7, version 1, descr. size 0x30
+    Type                    Start            End              Attributes
+    ======================= ================ ================ ==========
+    BootServicesCode        0000000000000000-0000000000001000 UC|WC|WT|WB
+    ConventionalMemory      0000000000001000-00000000000a0000 UC|WC|WT|WB
+    ConventionalMemory      0000000000100000-0000000000800000 UC|WC|WT|WB
+    ACPIMemoryNVS           0000000000800000-0000000000808000 UC|WC|WT|WB
+    ConventionalMemory      0000000000808000-000000000080b000 UC|WC|WT|WB
+    ACPIMemoryNVS           000000000080b000-000000000080c000 UC|WC|WT|WB
+    ConventionalMemory      000000000080c000-0000000000810000 UC|WC|WT|WB
+    ACPIMemoryNVS           0000000000810000-0000000000900000 UC|WC|WT|WB
+    BootServicesData        0000000000900000-0000000001780000 UC|WC|WT|WB
+    ConventionalMemory      0000000001780000-000000000bb75000 UC|WC|WT|WB
+    LoaderData              000000000bb75000-000000001bb75000 UC|WC|WT|WB
+    BootServicesData        000000001bb75000-000000001bb95000 UC|WC|WT|WB
+    ConventionalMemory      000000001bb95000-000000001dd24000 UC|WC|WT|WB
+    LoaderCode              000000001dd24000-000000001ddfe000 UC|WC|WT|WB
+    ConventionalMemory      000000001ddfe000-000000001de99000 UC|WC|WT|WB
+    BootServicesData        000000001de99000-000000001dea9000 UC|WC|WT|WB
+    LoaderData              000000001dea9000-000000001deac000 UC|WC|WT|WB
+    BootServicesData        000000001deac000-000000001e58e000 UC|WC|WT|WB
+    BootServicesCode        000000001e58e000-000000001e642000 UC|WC|WT|WB
+    BootServicesData        000000001e642000-000000001e672000 UC|WC|WT|WB
+    BootServicesCode        000000001e672000-000000001e753000 UC|WC|WT|WB
+    BootServicesData        000000001e753000-000000001e7b8000 UC|WC|WT|WB
+    BootServicesCode        000000001e7b8000-000000001e7c1000 UC|WC|WT|WB
+    BootServicesData        000000001e7c1000-000000001e7c6000 UC|WC|WT|WB
+    BootServicesCode        000000001e7c6000-000000001e7e6000 UC|WC|WT|WB
+    BootServicesData        000000001e7e6000-000000001e7e8000 UC|WC|WT|WB
+    BootServicesCode        000000001e7e8000-000000001e7f2000 UC|WC|WT|WB
+    BootServicesData        000000001e7f2000-000000001e7f3000 UC|WC|WT|WB
+    BootServicesCode        000000001e7f3000-000000001e7fb000 UC|WC|WT|WB
+    BootServicesData        000000001e7fb000-000000001e7fc000 UC|WC|WT|WB
+    BootServicesCode        000000001e7fc000-000000001e80c000 UC|WC|WT|WB
+    BootServicesData        000000001e80c000-000000001e80f000 UC|WC|WT|WB
+    BootServicesCode        000000001e80f000-000000001e812000 UC|WC|WT|WB
+    BootServicesData        000000001e812000-000000001e819000 UC|WC|WT|WB
+    BootServicesCode        000000001e819000-000000001e82b000 UC|WC|WT|WB
+    BootServicesData        000000001e82b000-000000001e834000 UC|WC|WT|WB
+    BootServicesCode        000000001e834000-000000001e842000 UC|WC|WT|WB
+    BootServicesData        000000001e842000-000000001e851000 UC|WC|WT|WB
+    BootServicesCode        000000001e851000-000000001e85c000 UC|WC|WT|WB
+    BootServicesData        000000001e85c000-000000001e867000 UC|WC|WT|WB
+    BootServicesCode        000000001e867000-000000001e87d000 UC|WC|WT|WB
+    BootServicesData        000000001e87d000-000000001e886000 UC|WC|WT|WB
+    BootServicesCode        000000001e886000-000000001e8aa000 UC|WC|WT|WB
+    BootServicesData        000000001e8aa000-000000001e8ad000 UC|WC|WT|WB
+    BootServicesCode        000000001e8ad000-000000001e8c1000 UC|WC|WT|WB
+    BootServicesData        000000001e8c1000-000000001e8c8000 UC|WC|WT|WB
+    BootServicesCode        000000001e8c8000-000000001e8e1000 UC|WC|WT|WB
+    BootServicesData        000000001e8e1000-000000001e8e4000 UC|WC|WT|WB
+    BootServicesCode        000000001e8e4000-000000001e8ea000 UC|WC|WT|WB
+    BootServicesData        000000001e8ea000-000000001e8ec000 UC|WC|WT|WB
+    BootServicesCode        000000001e8ec000-000000001e8ff000 UC|WC|WT|WB
+    BootServicesData        000000001e8ff000-000000001e904000 UC|WC|WT|WB
+    BootServicesCode        000000001e904000-000000001e91a000 UC|WC|WT|WB
+    BootServicesData        000000001e91a000-000000001e91c000 UC|WC|WT|WB
+    BootServicesCode        000000001e91c000-000000001e929000 UC|WC|WT|WB
+    BootServicesData        000000001e929000-000000001e92c000 UC|WC|WT|WB
+    BootServicesCode        000000001e92c000-000000001e932000 UC|WC|WT|WB
+    BootServicesData        000000001e932000-000000001e934000 UC|WC|WT|WB
+    BootServicesCode        000000001e934000-000000001e935000 UC|WC|WT|WB
+    BootServicesData        000000001e935000-000000001e936000 UC|WC|WT|WB
+    BootServicesCode        000000001e936000-000000001e93b000 UC|WC|WT|WB
+    BootServicesData        000000001e93b000-000000001e940000 UC|WC|WT|WB
+    BootServicesCode        000000001e940000-000000001e94c000 UC|WC|WT|WB
+    BootServicesData        000000001e94c000-000000001e94e000 UC|WC|WT|WB
+    BootServicesCode        000000001e94e000-000000001e96b000 UC|WC|WT|WB
+    BootServicesData        000000001e96b000-000000001e96c000 UC|WC|WT|WB
+    BootServicesCode        000000001e96c000-000000001e976000 UC|WC|WT|WB
+    BootServicesData        000000001e976000-000000001e977000 UC|WC|WT|WB
+    BootServicesCode        000000001e977000-000000001e978000 UC|WC|WT|WB
+    BootServicesData        000000001e978000-000000001e97a000 UC|WC|WT|WB
+    BootServicesCode        000000001e97a000-000000001e98f000 UC|WC|WT|WB
+    BootServicesData        000000001e98f000-000000001e992000 UC|WC|WT|WB
+    BootServicesCode        000000001e992000-000000001e994000 UC|WC|WT|WB
+    BootServicesData        000000001e994000-000000001e996000 UC|WC|WT|WB
+    BootServicesCode        000000001e996000-000000001e99d000 UC|WC|WT|WB
+    BootServicesData        000000001e99d000-000000001e9a4000 UC|WC|WT|WB
+    BootServicesCode        000000001e9a4000-000000001e9a8000 UC|WC|WT|WB
+    BootServicesData        000000001e9a8000-000000001e9ae000 UC|WC|WT|WB
+    BootServicesCode        000000001e9ae000-000000001e9b2000 UC|WC|WT|WB
+    BootServicesData        000000001e9b2000-000000001e9b4000 UC|WC|WT|WB
+    BootServicesCode        000000001e9b4000-000000001e9ef000 UC|WC|WT|WB
+    BootServicesData        000000001e9ef000-000000001e9f1000 UC|WC|WT|WB
+    BootServicesCode        000000001e9f1000-000000001e9f5000 UC|WC|WT|WB
+    BootServicesData        000000001e9f5000-000000001e9fd000 UC|WC|WT|WB
+    BootServicesCode        000000001e9fd000-000000001ea00000 UC|WC|WT|WB
+    BootServicesData        000000001ea00000-000000001ec02000 UC|WC|WT|WB
+    BootServicesCode        000000001ec02000-000000001ec0a000 UC|WC|WT|WB
+    BootServicesData        000000001ec0a000-000000001ec0f000 UC|WC|WT|WB
+    RuntimeServicesData     000000001ec0f000-000000001ecd0000 UC|WC|WT|WB|RT
+    BootServicesCode        000000001ecd0000-000000001ece5000 UC|WC|WT|WB
+    BootServicesData        000000001ece5000-000000001ece6000 UC|WC|WT|WB
+    BootServicesCode        000000001ece6000-000000001ecea000 UC|WC|WT|WB
+    BootServicesData        000000001ecea000-000000001eced000 UC|WC|WT|WB
+    BootServicesCode        000000001eced000-000000001ecf6000 UC|WC|WT|WB
+    BootServicesData        000000001ecf6000-000000001ecf7000 UC|WC|WT|WB
+    BootServicesCode        000000001ecf7000-000000001ecf8000 UC|WC|WT|WB
+    BootServicesData        000000001ecf8000-000000001ecfa000 UC|WC|WT|WB
+    BootServicesCode        000000001ecfa000-000000001ecfd000 UC|WC|WT|WB
+    BootServicesData        000000001ecfd000-000000001ecfe000 UC|WC|WT|WB
+    BootServicesCode        000000001ecfe000-000000001ecff000 UC|WC|WT|WB
+    BootServicesData        000000001ecff000-000000001ed00000 UC|WC|WT|WB
+    BootServicesCode        000000001ed00000-000000001ed16000 UC|WC|WT|WB
+    BootServicesData        000000001ed16000-000000001ed17000 UC|WC|WT|WB
+    BootServicesCode        000000001ed17000-000000001ed19000 UC|WC|WT|WB
+    BootServicesData        000000001ed19000-000000001ed2c000 UC|WC|WT|WB
+    BootServicesCode        000000001ed2c000-000000001ed2e000 UC|WC|WT|WB
+    BootServicesData        000000001ed2e000-000000001f12e000 UC|WC|WT|WB
+    BootServicesCode        000000001f12e000-000000001f132000 UC|WC|WT|WB
+    BootServicesData        000000001f132000-000000001f133000 UC|WC|WT|WB
+    BootServicesCode        000000001f133000-000000001f137000 UC|WC|WT|WB
+    BootServicesData        000000001f137000-000000001f13d000 UC|WC|WT|WB
+    BootServicesCode        000000001f13d000-000000001f147000 UC|WC|WT|WB
+    BootServicesData        000000001f147000-000000001f148000 UC|WC|WT|WB
+    BootServicesCode        000000001f148000-000000001f14d000 UC|WC|WT|WB
+    BootServicesData        000000001f14d000-000000001f4ed000 UC|WC|WT|WB
+    RuntimeServicesData     000000001f4ed000-000000001f5ed000 UC|WC|WT|WB|RT
+    RuntimeServicesCode     000000001f5ed000-000000001f6ed000 UC|WC|WT|WB|RT
+    ReservedMemory          000000001f6ed000-000000001f76d000 UC|WC|WT|WB
+    ACPIReclaimMemory       000000001f76d000-000000001f77f000 UC|WC|WT|WB
+    ACPIMemoryNVS           000000001f77f000-000000001f7ff000 UC|WC|WT|WB
+    BootServicesData        000000001f7ff000-000000001fe00000 UC|WC|WT|WB
+    ConventionalMemory      000000001fe00000-000000001fe77000 UC|WC|WT|WB
+    BootServicesData        000000001fe77000-000000001fe97000 UC|WC|WT|WB
+    BootServicesCode        000000001fe97000-000000001feca000 UC|WC|WT|WB
+    BootServicesData        000000001feca000-000000001fedb000 UC|WC|WT|WB
+    BootServicesCode        000000001fedb000-000000001fef4000 UC|WC|WT|WB
+    RuntimeServicesData     000000001fef4000-000000001ff78000 UC|WC|WT|WB|RT
+    ACPIMemoryNVS           000000001ff78000-0000000020000000 UC|WC|WT|WB
+    MemoryMappedIO          00000000ffc00000-0000000100000000 UC|RT
+    ReservedMemory          000000fd00000000-0000010000000000
 
     => efi tables
     000000001f8edf98  ee4e5898-3914-4259-9d6e-dc7bd79403cf  EFI_LZMA_COMPRESSED
index b98871fedada37c224894f2bc56ec1048720efde..71234d1b6fe570e3fceb8caa9382393c8cd21750 100644 (file)
@@ -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
  *