X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cmd%2Fbootefi.c;h=54b4b8f98455a8af7ccb60abcf1ae8074d45d032;hb=1321aef8cd13d89d36e8cda8482b87fcea93994a;hp=d347bd5ec064a2737f24da8a536d83a9cd45b3e6;hpb=336d4615f8fa774557d14f9b3245daa9e5fe3dbc;p=oweals%2Fu-boot.git diff --git a/cmd/bootefi.c b/cmd/bootefi.c index d347bd5ec0..54b4b8f984 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -149,6 +149,20 @@ done: return ret; } +static void efi_reserve_memory(u64 addr, u64 size) +{ + u64 pages; + + /* Convert from sandbox address space. */ + addr = (uintptr_t)map_sysmem(addr, 0); + pages = efi_size_in_pages(size + (addr & EFI_PAGE_MASK)); + addr &= ~EFI_PAGE_MASK; + if (efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE, + false) != EFI_SUCCESS) + printf("Reserved memory mapping failed addr %llx size %llx\n", + addr, size); +} + /** * efi_carve_out_dt_rsv() - Carve out DT reserved memory ranges * @@ -161,7 +175,8 @@ done: static void efi_carve_out_dt_rsv(void *fdt) { int nr_rsv, i; - uint64_t addr, size, pages; + u64 addr, size; + int nodeoffset, subnode; nr_rsv = fdt_num_mem_rsv(fdt); @@ -169,15 +184,26 @@ static void efi_carve_out_dt_rsv(void *fdt) for (i = 0; i < nr_rsv; i++) { if (fdt_get_mem_rsv(fdt, i, &addr, &size) != 0) continue; + efi_reserve_memory(addr, size); + } - /* Convert from sandbox address space. */ - addr = (uintptr_t)map_sysmem(addr, 0); - - pages = efi_size_in_pages(size + (addr & EFI_PAGE_MASK)); - addr &= ~EFI_PAGE_MASK; - if (efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE, - false) != EFI_SUCCESS) - printf("FDT memrsv map %d: Failed to add to map\n", i); + /* process reserved-memory */ + nodeoffset = fdt_subnode_offset(fdt, 0, "reserved-memory"); + if (nodeoffset >= 0) { + subnode = fdt_first_subnode(fdt, nodeoffset); + while (subnode >= 0) { + /* check if this subnode has a reg property */ + addr = fdtdec_get_addr_size(fdt, subnode, "reg", + (fdt_size_t *)&size); + /* + * The /reserved-memory node may have children with + * a size instead of a reg property. + */ + if (addr != FDT_ADDR_T_NONE && + fdtdec_get_is_enabled(fdt, subnode)) + efi_reserve_memory(addr, size); + subnode = fdt_next_subnode(fdt, subnode); + } } } @@ -203,15 +229,15 @@ static void *get_config_table(const efi_guid_t *guid) /** * efi_install_fdt() - install device tree * - * If fdt_addr is available, the device tree located at that memory address will - * will be installed as configuration table, otherwise the device tree located - * at the address indicated by environment variable fdt_addr or as fallback - * fdtcontroladdr will be used. + * If fdt is not EFI_FDT_USE_INTERNAL, the device tree located at that memory + * address will will be installed as configuration table, otherwise the device + * tree located at the address indicated by environment variable fdt_addr or as + * fallback fdtcontroladdr will be used. * * On architectures using ACPI tables device trees shall not be installed as * configuration table. * - * @fdt_addr: address of device tree or EFI_FDT_USE_INTERNAL to use the + * @fdt: address of device tree or EFI_FDT_USE_INTERNAL to use the * the hardware device tree as indicated by environment variable * fdt_addr or as fallback the internal device tree as indicated by * the environment variable fdtcontroladdr @@ -263,9 +289,6 @@ efi_status_t efi_install_fdt(void *fdt) return EFI_LOAD_ERROR; } - /* Create memory reservations as indicated by the device tree */ - efi_carve_out_dt_rsv(fdt); - /* Prepare device tree for payload */ ret = copy_fdt(&fdt); if (ret) { @@ -278,6 +301,9 @@ efi_status_t efi_install_fdt(void *fdt) return EFI_LOAD_ERROR; } + /* Create memory reservations as indicated by the device tree */ + efi_carve_out_dt_rsv(fdt); + /* Install device tree as UEFI table */ ret = efi_install_configuration_table(&efi_guid_fdt, fdt); if (ret != EFI_SUCCESS) { @@ -455,10 +481,8 @@ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size) ret = do_bootefi_exec(handle); out: - if (mem_handle) - efi_delete_handle(mem_handle); - if (file_path) - efi_free_pool(file_path); + efi_delete_handle(mem_handle); + efi_free_pool(file_path); return ret; }