[PATCH v5 21/28] efi: Support the efi command in the app
Heinrich Schuchardt
xypron.glpk at gmx.de
Thu Dec 9 21:27:23 CET 2021
On 12/4/21 07:56, Simon Glass wrote:
> At present the 'efi' command only works in the EFI payload. Update it to
> work in the app too, so the memory map can be examined.
cmd/efi.c seems to be duplicating function do_efi_show_memmap(). In a
future patch we should try to move to using common code for commands efi
and efidebug.
Best regards
Heinrich
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> (no changes since v1)
>
> cmd/Makefile | 2 +-
> cmd/efi.c | 48 ++++++++++++++++++++++++++++++++---------------
> include/efi.h | 15 +++++++++++++++
> lib/efi/efi_app.c | 33 ++++++++++++++++++++++++++++++++
> 4 files changed, 82 insertions(+), 16 deletions(-)
>
> diff --git a/cmd/Makefile b/cmd/Makefile
> index 891819ae0f6..df50625bde7 100644
> --- a/cmd/Makefile
> +++ b/cmd/Makefile
> @@ -58,7 +58,7 @@ obj-$(CONFIG_CMD_EXTENSION) += extension_board.o
> obj-$(CONFIG_CMD_ECHO) += echo.o
> obj-$(CONFIG_ENV_IS_IN_EEPROM) += eeprom.o
> obj-$(CONFIG_CMD_EEPROM) += eeprom.o
> -obj-$(CONFIG_EFI_STUB) += efi.o
> +obj-$(CONFIG_EFI) += efi.o
> obj-$(CONFIG_CMD_EFIDEBUG) += efidebug.o
> obj-$(CONFIG_CMD_ELF) += elf.o
> obj-$(CONFIG_HUSH_PARSER) += exit.o
> diff --git a/cmd/efi.c b/cmd/efi.c
> index d2400acbbba..c0384e0db28 100644
> --- a/cmd/efi.c
> +++ b/cmd/efi.c
> @@ -13,6 +13,8 @@
> #include <sort.h>
> #include <asm/global_data.h>
>
> +DECLARE_GLOBAL_DATA_PTR;
> +
> static const char *const type_name[] = {
> "reserved",
> "loader_code",
> @@ -217,37 +219,53 @@ static void efi_print_mem_table(struct efi_mem_desc *desc, int desc_size,
> static int do_efi_mem(struct cmd_tbl *cmdtp, int flag, int argc,
> char *const argv[])
> {
> - struct efi_mem_desc *desc;
> - struct efi_entry_memmap *map;
> + struct efi_mem_desc *orig, *desc;
> + uint version, key;
> + int desc_size;
> int size, ret;
> bool skip_bs;
>
> skip_bs = !argc || *argv[0] != 'a';
> - ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
> - switch (ret) {
> - case -ENOENT:
> - printf("No EFI table available\n");
> - goto done;
> - case -EPROTONOSUPPORT:
> - printf("Incorrect EFI table version\n");
> - goto done;
> + if (IS_ENABLED(CONFIG_EFI_APP)) {
> + ret = efi_get_mmap(&orig, &size, &key, &desc_size, &version);
> + if (ret) {
> + printf("Cannot read memory map (err=%d)\n", ret);
> + return CMD_RET_FAILURE;
> + }
> + } else {
> + struct efi_entry_memmap *map;
> +
> + ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
> + switch (ret) {
> + case -ENOENT:
> + printf("No EFI table available\n");
> + goto done;
> + case -EPROTONOSUPPORT:
> + printf("Incorrect EFI table version\n");
> + goto done;
> + }
> + orig = map->desc;
> + desc_size = map->desc_size;
> + version = map->version;
> }
> - printf("EFI table at %lx, memory map %p, size %x, version %x, descr. size %#x\n",
> - gd->arch.table, map, size, map->version, map->desc_size);
> - if (map->version != EFI_MEM_DESC_VERSION) {
> + printf("EFI table at %lx, memory map %p, size %x, key %x, version %x, descr. size %#x\n",
> + gd->arch.table, orig, size, key, version, desc_size);
> + if (version != EFI_MEM_DESC_VERSION) {
> printf("Incorrect memory map version\n");
> ret = -EPROTONOSUPPORT;
> goto done;
> }
>
> - desc = efi_build_mem_table(map->desc, size, map->desc_size, skip_bs);
> + desc = efi_build_mem_table(orig, size, desc_size, skip_bs);
> if (!desc) {
> ret = -ENOMEM;
> goto done;
> }
>
> - efi_print_mem_table(desc, map->desc_size, skip_bs);
> + efi_print_mem_table(desc, desc_size, skip_bs);
> free(desc);
> + if (IS_ENABLED(CONFIG_EFI_APP))
> + free(orig);
> done:
> if (ret)
> printf("Error: %d\n", ret);
> diff --git a/include/efi.h b/include/efi.h
> index 1dc806a1267..8a43430d3df 100644
> --- a/include/efi.h
> +++ b/include/efi.h
> @@ -610,4 +610,19 @@ int efi_store_memory_map(struct efi_priv *priv);
> */
> int efi_call_exit_boot_services(void);
>
> +/**
> + * efi_get_mmap() - Get the memory map from EFI
> + *
> + * This is used in the app. The caller must free *@descp when done
> + *
> + * @descp: Returns allocated pointer to EFI memory map table
> + * @sizep: Returns size of table in bytes
> + * @keyp: Returns memory-map key
> + * @desc_sizep: Returns size of each @desc_base record
> + * @versionp: Returns version number of memory map
> + * @return 0 on success, -ve on error
> + */
> +int efi_get_mmap(struct efi_mem_desc **descp, int *sizep, uint *keyp,
> + int *desc_sizep, uint *versionp);
> +
> #endif /* _LINUX_EFI_H */
> diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c
> index 36e3f1de427..55fa1ac57d5 100644
> --- a/lib/efi/efi_app.c
> +++ b/lib/efi/efi_app.c
> @@ -32,6 +32,39 @@ int efi_info_get(enum efi_entry_t type, void **datap, int *sizep)
> return -ENOSYS;
> }
>
> +int efi_get_mmap(struct efi_mem_desc **descp, int *sizep, uint *keyp,
> + int *desc_sizep, uint *versionp)
> +{
> + struct efi_priv *priv = efi_get_priv();
> + struct efi_boot_services *boot = priv->sys_table->boottime;
> + efi_uintn_t size, desc_size, key;
> + struct efi_mem_desc *desc;
> + efi_status_t ret;
> + u32 version;
> +
> + /* Get the memory map so we can switch off EFI */
> + size = 0;
> + ret = boot->get_memory_map(&size, NULL, &key, &desc_size, &version);
> + if (ret != EFI_BUFFER_TOO_SMALL)
> + return log_msg_ret("get", -ENOMEM);
> +
> + desc = malloc(size);
> + if (!desc)
> + return log_msg_ret("mem", -ENOMEM);
> +
> + ret = boot->get_memory_map(&size, desc, &key, &desc_size, &version);
> + if (ret)
> + return log_msg_ret("get", -EINVAL);
> +
> + *descp = desc;
> + *sizep = size;
> + *desc_sizep = desc_size;
> + *versionp = version;
> + *keyp = key;
> +
> + return 0;
> +}
> +
> /**
> * efi_print_str() - Print a UFT-16 string to the U-Boot console
> *
>
More information about the U-Boot
mailing list