summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/efi_loader/efi_memory.c')
-rw-r--r--lib/efi_loader/efi_memory.c65
1 files changed, 45 insertions, 20 deletions
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index ec66af98ea..967c3f733e 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -9,11 +9,14 @@
#include <efi_loader.h>
#include <inttypes.h>
#include <malloc.h>
+#include <mapmem.h>
#include <watchdog.h>
#include <linux/list_sort.h>
DECLARE_GLOBAL_DATA_PTR;
+efi_uintn_t efi_memory_map_key;
+
struct efi_mem_list {
struct list_head link;
struct efi_mem_desc desc;
@@ -159,9 +162,13 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
debug("%s: 0x%" PRIx64 " 0x%" PRIx64 " %d %s\n", __func__,
start, pages, memory_type, overlap_only_ram ? "yes" : "no");
+ if (memory_type >= EFI_MAX_MEMORY_TYPE)
+ return EFI_INVALID_PARAMETER;
+
if (!pages)
return start;
+ ++efi_memory_map_key;
newlist = calloc(1, sizeof(*newlist));
newlist->desc.type = memory_type;
newlist->desc.physical_start = start;
@@ -292,10 +299,13 @@ efi_status_t efi_allocate_pages(int type, int memory_type,
efi_status_t r = EFI_SUCCESS;
uint64_t addr;
+ if (!memory)
+ return EFI_INVALID_PARAMETER;
+
switch (type) {
case EFI_ALLOCATE_ANY_PAGES:
/* Any page */
- addr = efi_find_free_memory(len, gd->start_addr_sp);
+ addr = efi_find_free_memory(len, -1ULL);
if (!addr) {
r = EFI_NOT_FOUND;
break;
@@ -325,7 +335,7 @@ efi_status_t efi_allocate_pages(int type, int memory_type,
/* Reserve that map in our memory maps */
ret = efi_add_memory_map(addr, pages, memory_type, true);
if (ret == addr) {
- *memory = addr;
+ *memory = (uintptr_t)map_sysmem(addr, len);
} else {
/* Map would overlap, bail out */
r = EFI_OUT_OF_RESOURCES;
@@ -359,11 +369,12 @@ void *efi_alloc(uint64_t len, int memory_type)
efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
{
uint64_t r = 0;
+ uint64_t addr = map_to_sysmem((void *)(uintptr_t)memory);
- r = efi_add_memory_map(memory, pages, EFI_CONVENTIONAL_MEMORY, false);
+ r = efi_add_memory_map(addr, pages, EFI_CONVENTIONAL_MEMORY, false);
/* Merging of adjacent free regions is missing */
- if (r == memory)
+ if (r == addr)
return EFI_SUCCESS;
return EFI_NOT_FOUND;
@@ -380,20 +391,22 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size, void **buffer)
{
efi_status_t r;
- efi_physical_addr_t t;
+ struct efi_pool_allocation *alloc;
u64 num_pages = (size + sizeof(struct efi_pool_allocation) +
EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
+ if (!buffer)
+ return EFI_INVALID_PARAMETER;
+
if (size == 0) {
*buffer = NULL;
return EFI_SUCCESS;
}
r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, pool_type, num_pages,
- &t);
+ (uint64_t *)&alloc);
if (r == EFI_SUCCESS) {
- struct efi_pool_allocation *alloc = (void *)(uintptr_t)t;
alloc->num_pages = num_pages;
*buffer = alloc->data;
}
@@ -446,6 +459,9 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
struct list_head *lhandle;
efi_uintn_t provided_map_size = *memory_map_size;
+ if (!memory_map_size)
+ return EFI_INVALID_PARAMETER;
+
list_for_each(lhandle, &efi_mem)
map_entries++;
@@ -456,6 +472,9 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
if (provided_map_size < map_size)
return EFI_BUFFER_TOO_SMALL;
+ if (!memory_map)
+ return EFI_INVALID_PARAMETER;
+
if (descriptor_size)
*descriptor_size = sizeof(struct efi_mem_desc);
@@ -463,19 +482,18 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
*descriptor_version = EFI_MEMORY_DESCRIPTOR_VERSION;
/* Copy list into array */
- if (memory_map) {
- /* Return the list in ascending order */
- memory_map = &memory_map[map_entries - 1];
- list_for_each(lhandle, &efi_mem) {
- struct efi_mem_list *lmem;
+ /* Return the list in ascending order */
+ memory_map = &memory_map[map_entries - 1];
+ list_for_each(lhandle, &efi_mem) {
+ struct efi_mem_list *lmem;
- lmem = list_entry(lhandle, struct efi_mem_list, link);
- *memory_map = lmem->desc;
- memory_map--;
- }
+ lmem = list_entry(lhandle, struct efi_mem_list, link);
+ *memory_map = lmem->desc;
+ memory_map--;
}
- *map_key = 0;
+ if (map_key)
+ *map_key = efi_memory_map_key;
return EFI_SUCCESS;
}
@@ -496,14 +514,13 @@ __weak void efi_add_known_memory(void)
}
}
-int efi_memory_init(void)
+/* Add memory regions for U-Boot's memory and for the runtime services code */
+static void add_u_boot_and_runtime(void)
{
unsigned long runtime_start, runtime_end, runtime_pages;
unsigned long uboot_start, uboot_pages;
unsigned long uboot_stack_size = 16 * 1024 * 1024;
- efi_add_known_memory();
-
/* Add U-Boot */
uboot_start = (gd->start_addr_sp - uboot_stack_size) & ~EFI_PAGE_MASK;
uboot_pages = (gd->ram_top - uboot_start) >> EFI_PAGE_SHIFT;
@@ -516,6 +533,14 @@ int efi_memory_init(void)
runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT;
efi_add_memory_map(runtime_start, runtime_pages,
EFI_RUNTIME_SERVICES_CODE, false);
+}
+
+int efi_memory_init(void)
+{
+ efi_add_known_memory();
+
+ if (!IS_ENABLED(CONFIG_SANDBOX))
+ add_u_boot_and_runtime();
#ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
/* Request a 32bit 64MB bounce buffer region */