git: a9cd3b675e24 - main - kboot: Print UEFI memory map

From: Warner Losh <imp_at_FreeBSD.org>
Date: Mon, 11 Mar 2024 21:23:26 UTC
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=a9cd3b675e243648aa681bc6ce1bf3e788be88c8

commit a9cd3b675e243648aa681bc6ce1bf3e788be88c8
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2024-03-11 20:15:34 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-03-11 21:21:52 +0000

    kboot: Print UEFI memory map
    
    If we can read the UEFI memory map, go ahead and print the memory map.
    While the kernel prints this with bootverbose, having it at this stage
    is useful for debugging other problems.
    
    Sponsored by:           Netflix
    Differential Revision:  https://reviews.freebsd.org/D44287
---
 stand/kboot/kboot/arch/aarch64/load_addr.c | 85 ++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/stand/kboot/kboot/arch/aarch64/load_addr.c b/stand/kboot/kboot/arch/aarch64/load_addr.c
index 4cbbd5192f5b..8ea3516a5cff 100644
--- a/stand/kboot/kboot/arch/aarch64/load_addr.c
+++ b/stand/kboot/kboot/arch/aarch64/load_addr.c
@@ -23,6 +23,87 @@ uint32_t efi_map_size;
 vm_paddr_t efi_map_phys_src;	/* From DTB */
 vm_paddr_t efi_map_phys_dst;	/* From our memory map metadata module */
 
+typedef void (*efi_map_entry_cb)(struct efi_md *, void *argp);
+
+static void
+foreach_efi_map_entry(struct efi_map_header *efihdr, efi_map_entry_cb cb, void *argp)
+{
+	struct efi_md *map, *p;
+	size_t efisz;
+	int ndesc, i;
+
+	/*
+	 * Memory map data provided by UEFI via the GetMemoryMap
+	 * Boot Services API.
+	 */
+	efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
+	map = (struct efi_md *)((uint8_t *)efihdr + efisz);
+
+	if (efihdr->descriptor_size == 0)
+		return;
+	ndesc = efihdr->memory_size / efihdr->descriptor_size;
+
+	for (i = 0, p = map; i < ndesc; i++,
+	    p = efi_next_descriptor(p, efihdr->descriptor_size)) {
+		cb(p, argp);
+	}
+}
+
+static void
+print_efi_map_entry(struct efi_md *p, void *argp __unused)
+{
+	const char *type;
+	static const char *types[] = {
+		"Reserved",
+		"LoaderCode",
+		"LoaderData",
+		"BootServicesCode",
+		"BootServicesData",
+		"RuntimeServicesCode",
+		"RuntimeServicesData",
+		"ConventionalMemory",
+		"UnusableMemory",
+		"ACPIReclaimMemory",
+		"ACPIMemoryNVS",
+		"MemoryMappedIO",
+		"MemoryMappedIOPortSpace",
+		"PalCode",
+		"PersistentMemory"
+	};
+
+	if (p->md_type < nitems(types))
+		type = types[p->md_type];
+	else
+		type = "<INVALID>";
+	printf("%23s %012lx %012lx %08lx ", type, p->md_phys,
+	    p->md_virt, p->md_pages);
+	if (p->md_attr & EFI_MD_ATTR_UC)
+		printf("UC ");
+	if (p->md_attr & EFI_MD_ATTR_WC)
+		printf("WC ");
+	if (p->md_attr & EFI_MD_ATTR_WT)
+		printf("WT ");
+	if (p->md_attr & EFI_MD_ATTR_WB)
+		printf("WB ");
+	if (p->md_attr & EFI_MD_ATTR_UCE)
+		printf("UCE ");
+	if (p->md_attr & EFI_MD_ATTR_WP)
+		printf("WP ");
+	if (p->md_attr & EFI_MD_ATTR_RP)
+		printf("RP ");
+	if (p->md_attr & EFI_MD_ATTR_XP)
+		printf("XP ");
+	if (p->md_attr & EFI_MD_ATTR_NV)
+		printf("NV ");
+	if (p->md_attr & EFI_MD_ATTR_MORE_RELIABLE)
+		printf("MORE_RELIABLE ");
+	if (p->md_attr & EFI_MD_ATTR_RO)
+		printf("RO ");
+	if (p->md_attr & EFI_MD_ATTR_RT)
+		printf("RUNTIME");
+	printf("\n");
+}
+
 static bool
 do_memory_from_fdt(int fd)
 {
@@ -130,6 +211,10 @@ do_memory_from_fdt(int fd)
 	printf("Read UEFI mem map from physmem\n");
 	efi_map_phys_src = 0; /* Mark MODINFOMD_EFI_MAP as valid */
 	close(fd2);
+	printf("UEFI MAP:\n");
+	printf("%23s %12s %12s %8s %4s\n",
+	    "Type", "Physical", "Virtual", "#Pages", "Attr");
+	foreach_efi_map_entry(efihdr, print_efi_map_entry, NULL);
 	return true;	/* OK, we really have the memory map */
 
 no_read: