Adjust EFI_LOADER to use the provided region for early memory allocations, to avoid going outside the U-Boot region.
Expand the available memory when efi_init_obj_list() is called. Signed-off-by: Simon Glass <s...@chromium.org> --- Changes in v5: - Rebase on top of efil and efik series - Reword cover letter a little Changes in v4: - Use a different technique to keep the memory-usage in place - Drop changes to pool allocation - Reorder the patches - Rewrite the cover letter - Make it a debug message for now Changes in v2: - Drop patch 'Show more information in efi index' - Drop patch 'Avoid pool allocation in efi_get_memory_map_alloc()' - Add the word 'warning', use log_warning() and show the end address include/efi_loader.h | 13 +++++++++++++ lib/efi_loader/efi_memory.c | 24 ++++++++++++++++++++++-- lib/efi_loader/efi_setup.c | 5 +++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index a0af0db6262..600dfc2b48c 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -871,6 +871,19 @@ int efi_disk_probe(void *ctx, struct event *event); int efi_disk_remove(void *ctx, struct event *event); /* Called by board init to initialize the EFI memory map */ int efi_memory_init(void); + +/** + * efi_memory_coop() - Allow EFI to use all available memory + * + * Up until this function is called, only a small portion of memory is available + * for use by the EFI memory-allocator. This function is called at the + * 'point of cooperation', before jumping into an EFI app, which needs to be + * able to make use of all the memory in the machine + * + * Return: efi_status_t (EFI_SUCCESS on success) + */ +int efi_memory_coop(void); + /* Adds new or overrides configuration table entry to the system table */ efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table); /* Sets up a loaded image */ diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 344656c4eb0..88ef111dc70 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -32,6 +32,9 @@ DECLARE_GLOBAL_DATA_PTR; */ #define EFI_EARLY_REGION_SIZE SZ_256K +/* Set when all memory has been added for use by EFI */ +static bool efi_full_memory; + efi_uintn_t efi_memory_map_key; /** @@ -832,8 +835,25 @@ static void add_u_boot_and_runtime(void) int efi_memory_init(void) { - efi_add_known_memory(); + efi_status_t ret; + + /* restrict EFI to its own region until efi_memory_coop() is called */ + ret = efi_add_memory_map_pg(gd->efi_region, + EFI_EARLY_REGION_SIZE >> EFI_PAGE_SHIFT, + EFI_CONVENTIONAL_MEMORY, false); + + return ret; +} +int efi_memory_coop(void) +{ + if (efi_full_memory) + return 0; + log_debug("Enabling coop memory\n"); + + efi_full_memory = true; + + efi_add_known_memory(); add_u_boot_and_runtime(); #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER @@ -843,7 +863,7 @@ int efi_memory_init(void) if (efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, EFI_BOOT_SERVICES_DATA, (64 * 1024 * 1024) >> EFI_PAGE_SHIFT, &efi_bounce_buffer_addr) != EFI_SUCCESS) - return -1; + return -ENOMEM; efi_bounce_buffer = (void*)(uintptr_t)efi_bounce_buffer_addr; #endif diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 468156db813..c68f3ff0748 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -228,6 +228,11 @@ efi_status_t efi_init_obj_list(void) if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED) return efi_obj_list_initialized; + /* Allow EFI to use all memory */ + ret = efi_memory_coop(); + if (ret != EFI_SUCCESS) + goto out; + /* Set up console modes */ efi_setup_console_size(); -- 2.43.0