[Concept,11/18] efidebug: Support sorting with efidebug memmap

Message ID 20250902152158.2285264-12-sjg@u-boot.org
State New
Headers
Series efi: Improve integration of the app with a Shim environment |

Commit Message

Simon Glass Sept. 2, 2025, 3:21 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

Provide a -s option to sort the memory map in order of address. Add
documentation while we are here. Also fix an errant extra line before
do_efi_show_media()

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

 cmd/efidebug.c             | 51 +++++++++++++++++++--
 doc/usage/cmd/efidebug.rst | 92 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 139 insertions(+), 4 deletions(-)
  

Patch

diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index f88da42c2c4..627045a295e 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -25,6 +25,7 @@ 
 #include <net.h>
 #include <part.h>
 #include <search.h>
+#include <sort.h>
 #include <linux/ctype.h>
 #include <linux/err.h>
 
@@ -655,6 +656,26 @@  static void print_memory_attributes(u64 attributes)
 
 #define EFI_PHYS_ADDR_WIDTH (int)(sizeof(efi_physical_addr_t) * 2)
 
+/**
+ * efi_memmap_sort_by_addr() - compare two memory descriptors by address
+ *
+ * @a:	first memory descriptor
+ * @b:	second memory descriptor
+ * Return:	-1 if a < b, 0 if a == b, 1 if a > b
+ */
+static int efi_memmap_sort_by_addr(const void *a, const void *b)
+{
+	const struct efi_mem_desc *desc_a = a;
+	const struct efi_mem_desc *desc_b = b;
+
+	if (desc_a->physical_start < desc_b->physical_start)
+		return -1;
+	else if (desc_a->physical_start > desc_b->physical_start)
+		return 1;
+
+	return 0;
+}
+
 /**
  * do_efi_show_memmap() - show UEFI memory map
  *
@@ -676,6 +697,25 @@  static int do_efi_show_memmap(struct cmd_tbl *cmdtp, int flag,
 	int desc_size, i;
 	efi_status_t eret;
 	int ret;
+	bool sort_by_addr = false;
+	int num_entries;
+
+	argc--;
+	argv++;
+	while (argc > 0 && *argv[0] == '-') {
+		if (!strcmp(argv[0], "-s")) {
+			sort_by_addr = true;
+		} else {
+			printf("Unknown option: %s\n", argv[0]);
+			return CMD_RET_USAGE;
+		}
+		argc--;
+	}
+
+	if (argc > 0) {
+		printf("Too many arguments\n");
+		return CMD_RET_USAGE;
+	}
 
 	if (IS_ENABLED(CONFIG_EFI_APP)) {
 		uint key, version;
@@ -692,6 +732,12 @@  static int do_efi_show_memmap(struct cmd_tbl *cmdtp, int flag,
 		desc_size = sizeof(*map);
 	}
 
+	/* Sort entries by address if requested */
+	if (sort_by_addr) {
+		num_entries = map_size / desc_size;
+		qsort(memmap, num_entries, desc_size, efi_memmap_sort_by_addr);
+	}
+
 	printf("Type             Start%.*s End%.*s Attributes\n",
 	       EFI_PHYS_ADDR_WIDTH - 5, spc, EFI_PHYS_ADDR_WIDTH - 3, spc);
 	printf("================ %.*s %.*s ==========\n",
@@ -1594,7 +1640,6 @@  static int do_efi_test(struct cmd_tbl *cmdtp, int flag,
 	return cp->cmd(cmdtp, flag, argc, argv);
 }
 
-
 /**
  * do_efi_show_media() - show EFI media devices
  *
@@ -1807,8 +1852,8 @@  U_BOOT_LONGHELP(efidebug,
 	"  - show UEFI log\n"
 	"efidebug media\n"
 	"  - show EFI media devices\n"
-	"efidebug memmap\n"
-	"  - show UEFI memory map\n"
+	"efidebug memmap [-s]\n"
+	"  - show UEFI memory map (use -s to sort by address)\n"
 	"efidebug tables\n"
 	"  - show UEFI configuration tables\n"
 #ifdef CONFIG_EFI_BOOTMGR
diff --git a/doc/usage/cmd/efidebug.rst b/doc/usage/cmd/efidebug.rst
index 5dd68a689a6..8c8a4895197 100644
--- a/doc/usage/cmd/efidebug.rst
+++ b/doc/usage/cmd/efidebug.rst
@@ -15,6 +15,7 @@  Synopsis
 
     efidebug log
     efidebug media
+    efidebug memmap [-s]
 
 Description
 -----------
@@ -22,7 +23,7 @@  Description
 The *efidebug* command provides access to debugging features for the EFI-loader
 subsystem.
 
-Only two of the subcommands are documented at present.
+Only three of the subcommands are documented at present.
 
 efidebug log
 ~~~~~~~~~~~~
@@ -43,6 +44,15 @@  driver subsystem would likely handle the device (e.g., "ahci" for SATA drives,
 device, which can be useful for debugging boot issues or understanding the
 system topology.
 
+efidebug memmap
+~~~~~~~~~~~~~~~
+
+This shows the UEFI memory map, which displays all memory regions and their
+types as known to the EFI loader subsystem. This includes information about
+memory allocation, reserved regions, and available memory.
+
+The command supports an optional '-s' flag to sort the memory map entries by
+address, making it easier to visualize the memory layout in ascending order.
 
 Example
 -------
@@ -55,6 +65,86 @@  This shows checking the EFI media devices::
     efi_media_1          ahci             PciRoot(0x0)/Pci(0x3,0x0)/Sata(0x0,0xFFFF,0x0)
     efi_media_2          pci              PciRoot(0x0)/Pci(0x5,0x0)
 
+This shows checking the UEFI memory map, first unsorted and then sorted by
+address::
+
+    => efidebug mem
+    Type             Start            End              Attributes
+    ================ ================ ================ ==========
+    CONVENTIONAL     0000000040000000-0000000044000000 WB
+    BOOT DATA        0000000044000000-0000000044020000 WB
+    CONVENTIONAL     0000000044020000-00000000475ee000 WB
+    BOOT DATA        00000000475ee000-0000000047610000 WB
+    BOOT CODE        0000000047610000-0000000047647000 WB
+    BOOT DATA        0000000047647000-0000000047ef2000 WB
+    BOOT CODE        0000000047ef2000-0000000047ef6000 WB
+    BOOT DATA        0000000047ef6000-0000000047ff7000 WB
+    BOOT CODE        0000000047ff7000-0000000047ffa000 WB
+    BOOT DATA        0000000047ffa000-0000000048000000 WB
+    CONVENTIONAL     0000000048000000-00000000e0000000 WB
+    LOADER DATA      00000000e0000000-0000000100000000 WB
+    CONVENTIONAL     0000000100000000-000000013c278000 WB
+    LOADER DATA      000000013c278000-000000013c27c000 WB
+    LOADER CODE      000000013c27c000-000000013c3e0000 WB
+    ACPI RECLAIM MEM 000000013c3e0000-000000013c3f0000 WB
+    RUNTIME CODE     000000013c3f0000-000000013c470000 WB|RT
+    RUNTIME DATA     000000013c470000-000000013c630000 WB|RT
+    RUNTIME CODE     000000013c630000-000000013c730000 WB|RT
+    CONVENTIONAL     000000013c730000-000000013dc2a000 WB
+    BOOT DATA        000000013dc2a000-000000013e9f1000 WB
+    CONVENTIONAL     000000013e9f1000-000000013e9fe000 WB
+    BOOT DATA        000000013e9fe000-000000013ea1c000 WB
+    CONVENTIONAL     000000013ea1c000-000000013ea1e000 WB
+    BOOT DATA        000000013ea1e000-000000013ea47000 WB
+    CONVENTIONAL     000000013ea47000-000000013ea48000 WB
+    BOOT DATA        000000013ea48000-000000013f624000 WB
+    CONVENTIONAL     000000013f624000-000000013f731000 WB
+    BOOT CODE        000000013f731000-000000013fc00000 WB
+    RUNTIME CODE     000000013fc00000-000000013fd90000 WB|RT
+    RUNTIME DATA     000000013fd90000-000000013ffe0000 WB|RT
+    CONVENTIONAL     000000013ffe0000-000000013ffff000 WB
+    BOOT DATA        000000013ffff000-0000000140000000 WB
+    IO               0000000004000000-0000000008000000 UC|RT
+    IO               0000000009010000-0000000009011000 UC|RT
+    => efidebug mem -s
+    Type             Start            End              Attributes
+    ================ ================ ================ ==========
+    IO               0000000004000000-0000000008000000 UC|RT
+    IO               0000000009010000-0000000009011000 UC|RT
+    CONVENTIONAL     0000000040000000-0000000044000000 WB
+    BOOT DATA        0000000044000000-0000000044020000 WB
+    CONVENTIONAL     0000000044020000-00000000475ee000 WB
+    BOOT DATA        00000000475ee000-0000000047610000 WB
+    BOOT CODE        0000000047610000-0000000047647000 WB
+    BOOT DATA        0000000047647000-0000000047ef2000 WB
+    BOOT CODE        0000000047ef2000-0000000047ef6000 WB
+    BOOT DATA        0000000047ef6000-0000000047ff7000 WB
+    BOOT CODE        0000000047ff7000-0000000047ffa000 WB
+    BOOT DATA        0000000047ffa000-0000000048000000 WB
+    CONVENTIONAL     0000000048000000-00000000e0000000 WB
+    LOADER DATA      00000000e0000000-0000000100000000 WB
+    CONVENTIONAL     0000000100000000-000000013c278000 WB
+    LOADER DATA      000000013c278000-000000013c27c000 WB
+    LOADER CODE      000000013c27c000-000000013c3e0000 WB
+    ACPI RECLAIM MEM 000000013c3e0000-000000013c3f0000 WB
+    RUNTIME CODE     000000013c3f0000-000000013c470000 WB|RT
+    RUNTIME DATA     000000013c470000-000000013c630000 WB|RT
+    RUNTIME CODE     000000013c630000-000000013c730000 WB|RT
+    CONVENTIONAL     000000013c730000-000000013dc2a000 WB
+    BOOT DATA        000000013dc2a000-000000013e9f1000 WB
+    CONVENTIONAL     000000013e9f1000-000000013e9fe000 WB
+    BOOT DATA        000000013e9fe000-000000013ea1c000 WB
+    CONVENTIONAL     000000013ea1c000-000000013ea1e000 WB
+    BOOT DATA        000000013ea1e000-000000013ea47000 WB
+    CONVENTIONAL     000000013ea47000-000000013ea48000 WB
+    BOOT DATA        000000013ea48000-000000013f624000 WB
+    CONVENTIONAL     000000013f624000-000000013f731000 WB
+    BOOT CODE        000000013f731000-000000013fc00000 WB
+    RUNTIME CODE     000000013fc00000-000000013fd90000 WB|RT
+    RUNTIME DATA     000000013fd90000-000000013ffe0000 WB|RT
+    CONVENTIONAL     000000013ffe0000-000000013ffff000 WB
+    BOOT DATA        000000013ffff000-0000000140000000 WB
+    =>
 
 This shows checking the log, then using 'efidebug tables' to fully set up the
 EFI-loader subsystem, then checking the log again::