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.

Signed-off-by: Simon Glass <s...@chromium.org>
---

(no changes since v2)

Changes in v2:
- Add new patch to support the efi command in the app

 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 ed3669411e6..3e9f23ebf30 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
  *
-- 
2.33.0.1079.g6e70778dc9-goog

Reply via email to