X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=cmd%2Fbootefi.c;h=f55a40dc84cd05dc2f3cbb39583f9c70f7e5a68c;hb=a1b73c18724eb8cb75f7a60d851578d933c78095;hp=2a31a914cdb3be29e4d5b411cc5d178958c093f9;hpb=2db1eba1c3717856ebcf01727379ad2d3f19b3cc;p=u-boot diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 2a31a914cd..f55a40dc84 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -1,9 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * EFI application loader * * Copyright (c) 2016 Alexander Graf - * - * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -18,6 +17,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -56,7 +56,7 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out; #endif -#ifdef CONFIG_CMD_NET +#ifdef CONFIG_NET ret = efi_net_register(); if (ret != EFI_SUCCESS) goto out; @@ -83,6 +83,15 @@ out: return ret; } +/* + * Allow unaligned memory access. + * + * This routine is overridden by architectures providing this feature. + */ +void __weak allow_unaligned(void) +{ +} + /* * Set the load options of an image from an environment variable. * @@ -134,11 +143,13 @@ static void *copy_fdt(void *fdt) /* Safe fdt location is at 128MB */ new_fdt_addr = fdt_ram_start + (128 * 1024 * 1024) + fdt_size; - if (efi_allocate_pages(1, EFI_RUNTIME_SERVICES_DATA, fdt_pages, + if (efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, + EFI_RUNTIME_SERVICES_DATA, fdt_pages, &new_fdt_addr) != EFI_SUCCESS) { /* If we can't put it there, put it somewhere */ new_fdt_addr = (ulong)memalign(EFI_PAGE_SIZE, fdt_size); - if (efi_allocate_pages(1, EFI_RUNTIME_SERVICES_DATA, fdt_pages, + if (efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, + EFI_RUNTIME_SERVICES_DATA, fdt_pages, &new_fdt_addr) != EFI_SUCCESS) { printf("ERROR: Failed to reserve space for FDT\n"); return NULL; @@ -178,6 +189,27 @@ static efi_status_t efi_run_in_el2(EFIAPI efi_status_t (*entry)( } #endif +/* Carve out DT reserved memory ranges */ +static efi_status_t efi_carve_out_dt_rsv(void *fdt) +{ + int nr_rsv, i; + uint64_t addr, size, pages; + + nr_rsv = fdt_num_mem_rsv(fdt); + + /* Look for an existing entry and add it to the efi mem map. */ + for (i = 0; i < nr_rsv; i++) { + if (fdt_get_mem_rsv(fdt, i, &addr, &size) != 0) + continue; + + pages = ALIGN(size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT; + efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE, + false); + } + + return EFI_SUCCESS; +} + static efi_status_t efi_install_fdt(void *fdt) { bootm_headers_t img = { 0 }; @@ -199,6 +231,11 @@ static efi_status_t efi_install_fdt(void *fdt) return EFI_LOAD_ERROR; } + if (efi_carve_out_dt_rsv(fdt) != EFI_SUCCESS) { + printf("ERROR: failed to carve out memory\n"); + return EFI_LOAD_ERROR; + } + /* Link to it in the efi tables */ ret = efi_install_configuration_table(&efi_guid_fdt, fdt); if (ret != EFI_SUCCESS) @@ -226,6 +263,7 @@ static efi_status_t do_bootefi_exec(void *efi, { struct efi_loaded_image loaded_image_info = {}; struct efi_object loaded_image_info_obj = {}; + struct efi_object mem_obj = {}; struct efi_device_path *memdp = NULL; efi_status_t ret; @@ -242,6 +280,12 @@ static efi_status_t do_bootefi_exec(void *efi, /* actual addresses filled in after efi_load_pe() */ memdp = efi_dp_from_mem(0, 0, 0); device_path = image_path = memdp; + efi_add_handle(&mem_obj); + + ret = efi_add_protocol(mem_obj.handle, &efi_guid_device_path, + device_path); + if (ret != EFI_SUCCESS) + goto exit; } else { assert(device_path && image_path); } @@ -306,6 +350,8 @@ static efi_status_t do_bootefi_exec(void *efi, exit: /* image has returned, loaded-image obj goes *poof*: */ list_del(&loaded_image_info_obj.link); + if (mem_obj.handle) + list_del(&mem_obj.link); return ret; } @@ -345,6 +391,9 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) efi_status_t r; void *fdt_addr; + /* Allow unaligned memory access */ + allow_unaligned(); + /* Initialize EFI drivers */ r = efi_init_obj_list(); if (r != EFI_SUCCESS) { @@ -403,8 +452,6 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) * callback entry */ efi_save_gd(); - /* Initialize and populate EFI object list */ - efi_init_obj_list(); /* Transfer environment variable efi_selftest as load options */ set_load_options(&loaded_image_info, "efi_selftest"); /* Execute the test */ @@ -485,7 +532,7 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path) bootefi_device_path = efi_dp_from_part(desc, part); } else { -#ifdef CONFIG_CMD_NET +#ifdef CONFIG_NET bootefi_device_path = efi_dp_from_eth(); #endif }