This unit test checks the following runtime services:
AllocatePages, FreePages, GetMemoryMap

Signed-off-by: Heinrich Schuchardt <xypron.g...@gmx.de>
---
 lib/efi_selftest/Makefile              |   1 +
 lib/efi_selftest/efi_selftest_memory.c | 163 +++++++++++++++++++++++++
 2 files changed, 164 insertions(+)
 create mode 100644 lib/efi_selftest/efi_selftest_memory.c

diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index 4b1c0bb84b1..743b4820449 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -27,6 +27,7 @@ efi_selftest_fdt.o \
 efi_selftest_gop.o \
 efi_selftest_loaded_image.o \
 efi_selftest_manageprotocols.o \
+efi_selftest_memory.o \
 efi_selftest_rtc.o \
 efi_selftest_snp.o \
 efi_selftest_textinput.o \
diff --git a/lib/efi_selftest/efi_selftest_memory.c 
b/lib/efi_selftest/efi_selftest_memory.c
new file mode 100644
index 00000000000..0623e8e62da
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_memory.c
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * efi_selftest_memory
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.g...@gmx.de>
+ *
+ * This unit test checks the following runtime services:
+ * AllocatePages, FreePages, GetMemoryMap
+ */
+
+#include <efi_selftest.h>
+
+#define EFI_ST_NUM_PAGES 8
+
+static struct efi_boot_services *boottime;
+
+/**
+ * setup() - setup unit test
+ *
+ * @handle:    handle of the loaded image
+ * @systable:  system table
+ * Return:     EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+                const struct efi_system_table *systable)
+{
+       boottime = systable->boottime;
+
+       return EFI_ST_SUCCESS;
+}
+
+/**
+ * find_in_memory_map() - check matching memory map entry exists
+ *
+ * @memory_map:                memory map
+ * @desc_size:         number of memory map entries
+ * @addr:              physical address to find in the map
+ * @type:              expected memory type
+ * Return:             EFI_ST_SUCCESS for success
+ */
+static int find_in_memory_map(efi_uintn_t map_size,
+                             struct efi_mem_desc *memory_map,
+                             efi_uintn_t desc_size,
+                             u64 addr, int memory_type)
+{
+       efi_uintn_t i;
+       bool found = false;
+
+       for (i = 0; map_size; ++i, map_size -= desc_size) {
+               struct efi_mem_desc *entry = &memory_map[i];
+
+               if (addr >= entry->physical_start &&
+                   addr < entry->physical_start +
+                           (entry->num_pages << EFI_PAGE_SHIFT)) {
+                       if (found) {
+                               efi_st_error("Duplicate memory map entry\n");
+                               return EFI_ST_FAILURE;
+                       }
+                       found = true;
+                       if (memory_type != entry->type) {
+                               efi_st_error
+                                       ("Wrong memory type %d, expected %d\n",
+                                        entry->type, memory_type);
+                               return EFI_ST_FAILURE;
+                       }
+               }
+       }
+       if (!found) {
+               efi_st_error("Missing memory map entry\n");
+               return EFI_ST_FAILURE;
+       }
+       return EFI_ST_SUCCESS;
+}
+
+/*
+ * execute() - execute unit test
+ *
+ * Return:     EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+       u64 p1;
+       u64 p2;
+       efi_uintn_t map_size = 0;
+       efi_uintn_t map_key;
+       efi_uintn_t desc_size;
+       u32 desc_version;
+       struct efi_mem_desc *memory_map;
+       efi_status_t ret;
+
+       /* Allocate two page ranges with different memory type */
+       ret = boottime->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
+                                      EFI_RUNTIME_SERVICES_CODE,
+                                      EFI_ST_NUM_PAGES, &p1);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("AllocatePages did not return EFI_SUCCESS\n");
+               return EFI_ST_FAILURE;
+       }
+       ret = boottime->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
+                                      EFI_RUNTIME_SERVICES_DATA,
+                                      EFI_ST_NUM_PAGES, &p2);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("AllocatePages did not return EFI_SUCCESS\n");
+               return EFI_ST_FAILURE;
+       }
+
+       /* Load memory map */
+       ret = boottime->get_memory_map(&map_size, NULL, &map_key, &desc_size,
+                                      &desc_version);
+       if (ret != EFI_BUFFER_TOO_SMALL) {
+               efi_st_error
+                       ("GetMemoryMap did not return EFI_BUFFER_TOO_SMALL\n");
+               return EFI_ST_FAILURE;
+       }
+       /* Allocate extra space for newly allocated memory */
+       map_size += sizeof(struct efi_mem_desc);
+       ret = boottime->allocate_pool(EFI_BOOT_SERVICES_DATA, map_size,
+                                     (void **)&memory_map);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("AllocatePool did not return EFI_SUCCESS\n");
+               return EFI_ST_FAILURE;
+       }
+       ret = boottime->get_memory_map(&map_size, memory_map, &map_key,
+                                      &desc_size, &desc_version);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("GetMemoryMap did not return EFI_SUCCESS\n");
+               return EFI_ST_FAILURE;
+       }
+
+       /* Check memory map entries */
+       if (find_in_memory_map(map_size, memory_map, desc_size, p1,
+                              EFI_RUNTIME_SERVICES_CODE) != EFI_ST_SUCCESS)
+               return EFI_ST_FAILURE;
+       if (find_in_memory_map(map_size, memory_map, desc_size, p2,
+                              EFI_RUNTIME_SERVICES_DATA) != EFI_ST_SUCCESS)
+               return EFI_ST_FAILURE;
+
+       /* Free memory */
+       ret = boottime->free_pages(p1, EFI_ST_NUM_PAGES);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("FreePages did not return EFI_SUCCESS\n");
+               return EFI_ST_FAILURE;
+       }
+       ret = boottime->free_pages(p2, EFI_ST_NUM_PAGES);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("FreePages did not return EFI_SUCCESS\n");
+               return EFI_ST_FAILURE;
+       }
+       ret = boottime->free_pool(memory_map);
+       if (ret != EFI_SUCCESS) {
+               efi_st_error("FreePool did not return EFI_SUCCESS\n");
+               return EFI_ST_FAILURE;
+       }
+
+       return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(memory) = {
+       .name = "memory",
+       .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+       .setup = setup,
+       .execute = execute,
+};
-- 
2.19.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to