X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fimage-fdt.c;h=3002948b6b0e219f25a31ce40125ec92ce46e6df;hb=515f613253cf0a892c3a321770ab927fa3d925cf;hp=25103ba3b5d9debdd254631b47e78705a0a0b925;hpb=81f077f40f80eb431bfec88c9fe2a7da3efa8e5f;p=oweals%2Fu-boot.git diff --git a/common/image-fdt.c b/common/image-fdt.c index 25103ba3b5..3002948b6b 100644 --- a/common/image-fdt.c +++ b/common/image-fdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2013, Google Inc. * @@ -5,22 +6,27 @@ * * (C) Copyright 2000-2006 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ */ #include #include +#include +#include #include #include +#include #include #include #include +#include #ifndef CONFIG_SYS_FDT_PAD #define CONFIG_SYS_FDT_PAD 0x3000 #endif +/* adding a ramdisk needs 0x44 bytes in version 2008.10 */ +#define FDT_RAMDISK_OVERHEAD 0x80 + DECLARE_GLOBAL_DATA_PTR; static void fdt_error(const char *msg) @@ -30,7 +36,7 @@ static void fdt_error(const char *msg) puts(" - must RESET the board to recover.\n"); } -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) static const image_header_t *image_get_fdt(ulong fdt_addr) { const image_header_t *fdt_hdr = map_sysmem(fdt_addr, 0); @@ -65,30 +71,66 @@ static const image_header_t *image_get_fdt(ulong fdt_addr) } #endif +static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr, + uint64_t size) +{ + long ret; + + ret = lmb_reserve(lmb, addr, size); + if (ret >= 0) { + debug(" reserving fdt memory region: addr=%llx size=%llx\n", + (unsigned long long)addr, (unsigned long long)size); + } else { + puts("ERROR: reserving fdt memory region failed "); + printf("(addr=%llx size=%llx)\n", + (unsigned long long)addr, (unsigned long long)size); + } +} + /** - * boot_fdt_add_mem_rsv_regions - Mark the memreserve sections as unusable + * boot_fdt_add_mem_rsv_regions - Mark the memreserve and reserved-memory + * sections as unusable * @lmb: pointer to lmb handle, will be used for memory mgmt * @fdt_blob: pointer to fdt blob base address * - * Adds the memreserve regions in the dtb to the lmb block. Adding the - * memreserve regions prevents u-boot from using them to store the initrd - * or the fdt blob. + * Adds the and reserved-memorymemreserve regions in the dtb to the lmb block. + * Adding the memreserve regions prevents u-boot from using them to store the + * initrd or the fdt blob. */ void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) { uint64_t addr, size; - int i, total; + int i, total, ret; + int nodeoffset, subnode; + struct fdt_resource res; if (fdt_check_header(fdt_blob) != 0) return; + /* process memreserve sections */ total = fdt_num_mem_rsv(fdt_blob); for (i = 0; i < total; i++) { if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0) continue; - printf(" reserving fdt memory region: addr=%llx size=%llx\n", - (unsigned long long)addr, (unsigned long long)size); - lmb_reserve(lmb, addr, size); + boot_fdt_reserve_region(lmb, addr, size); + } + + /* process reserved-memory */ + nodeoffset = fdt_subnode_offset(fdt_blob, 0, "reserved-memory"); + if (nodeoffset >= 0) { + subnode = fdt_first_subnode(fdt_blob, nodeoffset); + while (subnode >= 0) { + /* check if this subnode has a reg property */ + ret = fdt_get_resource(fdt_blob, subnode, "reg", 0, + &res); + if (!ret && fdtdec_get_is_enabled(fdt_blob, subnode)) { + addr = res.start; + size = res.end - res.start + 1; + boot_fdt_reserve_region(lmb, addr, size); + } + + subnode = fdt_next_subnode(fdt_blob, subnode); + } } } @@ -191,7 +233,8 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size) *of_flat_tree = of_start; *of_size = of_len; - set_working_fdt_addr((ulong)*of_flat_tree); + if (CONFIG_IS_ENABLED(CMD_FDT)) + set_working_fdt_addr(map_to_sysmem(*of_flat_tree)); return 0; error: @@ -223,11 +266,12 @@ error: int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch, bootm_headers_t *images, char **of_flat_tree, ulong *of_size) { -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) const image_header_t *fdt_hdr; ulong load, load_end; ulong image_start, image_data, image_end; #endif + ulong img_addr; ulong fdt_addr; char *fdt_blob = NULL; void *buf; @@ -238,11 +282,14 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch, int fdt_noffset; #endif const char *select = NULL; - int ok_no_fdt = 0; *of_flat_tree = NULL; *of_size = 0; + img_addr = (argc == 0) ? image_load_addr : + simple_strtoul(argv[0], NULL, 16); + buf = map_sysmem(img_addr, 0); + if (argc > 2) select = argv[2]; if (select || genimg_has_config(images)) { @@ -259,7 +306,7 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch, else if (images->fit_uname_os) default_addr = (ulong)images->fit_hdr_os; else - default_addr = load_addr; + default_addr = image_load_addr; if (fit_parse_conf(select, default_addr, &fdt_addr, &fit_uname_config)) { @@ -301,7 +348,7 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch, */ buf = map_sysmem(fdt_addr, 0); switch (genimg_get_format(buf)) { -#if defined(CONFIG_IMAGE_FORMAT_LEGACY) +#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: /* verify fdt_addr points to a valid image header */ printf("## Flattened Device Tree from Legacy Image at %08lx\n", @@ -413,6 +460,30 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch, debug("## No Flattened Device Tree\n"); goto no_fdt; } +#ifdef CONFIG_ANDROID_BOOT_IMAGE + } else if (genimg_get_format(buf) == IMAGE_FORMAT_ANDROID) { + struct andr_img_hdr *hdr = buf; + ulong fdt_data, fdt_len; + + if (!android_image_get_second(hdr, &fdt_data, &fdt_len) && + !fdt_check_header((char *)fdt_data)) { + fdt_blob = (char *)fdt_data; + if (fdt_totalsize(fdt_blob) != fdt_len) + goto error; + + debug("## Using FDT in Android image second area\n"); + } else { + fdt_addr = env_get_hex("fdtaddr", 0); + if (!fdt_addr) + goto no_fdt; + + fdt_blob = map_sysmem(fdt_addr, 0); + if (fdt_check_header(fdt_blob)) + goto no_fdt; + + debug("## Using FDT at ${fdtaddr}=Ox%lx\n", fdt_addr); + } +#endif } else { debug("## No Flattened Device Tree\n"); goto no_fdt; @@ -426,14 +497,9 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch, return 0; no_fdt: - ok_no_fdt = 1; + debug("Continuing to boot without FDT\n"); + return 0; error: - *of_flat_tree = NULL; - *of_size = 0; - if (!select && ok_no_fdt) { - debug("Continuing to boot without FDT\n"); - return 0; - } return 1; } @@ -498,6 +564,13 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob, } } + fdt_ret = optee_copy_fdt_nodes(gd->fdt_blob, blob); + if (fdt_ret) { + printf("ERROR: transfer of optee nodes to new fdt failed: %s\n", + fdt_strerror(fdt_ret)); + goto err; + } + /* Delete the old LMB reservation */ if (lmb) lmb_free(lmb, (phys_addr_t)(u32)(uintptr_t)blob,