
From: Simon Glass <sjg@chromium.org> The 'efi mem' command dumps out the memory map. This is useful within the app, even if commands are not enabled, so move it to a common file. Rename it from 'print' to 'dump' since most things that dump information use that word. Signed-off-by: Simon Glass <sjg@chromium.org> --- cmd/efi.c | 119 +------------------------------------------ include/efi.h | 23 +++++++++ lib/efi/Makefile | 1 + lib/efi/memory.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 117 deletions(-) create mode 100644 lib/efi/memory.c diff --git a/cmd/efi.c b/cmd/efi.c index 53213be0a2f..91feec1c051 100644 --- a/cmd/efi.c +++ b/cmd/efi.c @@ -17,52 +17,6 @@ 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; @@ -119,7 +73,7 @@ static void *efi_build_mem_table(struct efi_mem_desc *desc_base, int size, continue; } - if (skip_bs && is_boot_services(desc->type)) + if (skip_bs && efi_mem_is_boot_services(desc->type)) type = EFI_CONVENTIONAL_MEMORY; memcpy(dest, desc, desc_size); @@ -149,75 +103,6 @@ static void *efi_build_mem_table(struct efi_mem_desc *desc_base, int size, 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[]) { @@ -264,7 +149,7 @@ static int do_efi_mem(struct cmd_tbl *cmdtp, int flag, int argc, goto done; } - efi_print_mem_table(desc, desc_size, skip_bs); + efi_dump_mem_table(desc, size, desc_size, skip_bs); free(desc); if (IS_ENABLED(CONFIG_EFI_APP)) free(orig); diff --git a/include/efi.h b/include/efi.h index 11966ffc417..e95bb2e7d96 100644 --- a/include/efi.h +++ b/include/efi.h @@ -733,6 +733,29 @@ static inline bool efi_use_host_arch(void) */ int efi_get_pxe_arch(void); +/** + * efi_mem_is_boot_services() - checks if the memory type relates to boot-time + * + * Return: true if loader code/data or boot-services code/data + */ +static inline bool efi_mem_is_boot_services(int type) +{ + return type == EFI_LOADER_CODE || type == EFI_LOADER_DATA || + type == EFI_BOOT_SERVICES_CODE || + type == EFI_BOOT_SERVICES_DATA; +} + +/** + * efi_dump_mem_table() - Dump out the EFI memory map + * + * @desc: List of descriptors to dump + * @size: Size of desc array in bytes + * @desc_size: Size of each description in @desc + * @skip_bs: true to skip boot-services allocations + */ +void efi_dump_mem_table(struct efi_mem_desc *desc, int size, int desc_size, + bool skip_bs); + /** * calculate_paths() - Calculate the device and image patch from strings * diff --git a/lib/efi/Makefile b/lib/efi/Makefile index 37816a93192..213c9910b39 100644 --- a/lib/efi/Makefile +++ b/lib/efi/Makefile @@ -5,4 +5,5 @@ obj-y += basename.o obj-y += device_path.o +obj-y += memory.o obj-y += run.o diff --git a/lib/efi/memory.c b/lib/efi/memory.c new file mode 100644 index 00000000000..2e9aa2df5e9 --- /dev/null +++ b/lib/efi/memory.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Functions shared by the app and stub + * + * Copyright (c) 2015 Google, Inc + * + * EFI information obtained here: + * http://wiki.phoenix.com/wiki/index.php/EFI_BOOT_SERVICES + * + * Common EFI functions + */ + +#include <debug_uart.h> +#include <malloc.h> +#include <linux/err.h> +#include <linux/types.h> +#include <efi.h> +#include <efi_api.h> + +enum { + /* Maximum different attribute values we can track */ + ATTR_SEEN_MAX = 30, +}; + +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" } +}; + +void efi_dump_mem_table(struct efi_mem_desc *desc, int size, int desc_size, + bool skip_bs) +{ + u64 attr_seen[ATTR_SEEN_MAX]; + struct efi_mem_desc *end; + 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 */ + end = (struct efi_mem_desc *)((ulong)desc + size); + attr_seen_count = 0; + addr = 0; + for (upto = 0; desc < end; + upto++, desc = efi_get_next_mem_desc(desc, desc_size)) { + const char *name; + u64 size; + + if (skip_bs && efi_mem_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"); +} -- 2.43.0