#include <common.h>
#include <fdt_support.h>
#include <fdtdec.h>
+#include <env.h>
#include <errno.h>
#include <image.h>
+#include <lmb.h>
+#include <log.h>
+#include <malloc.h>
+#include <asm/global_data.h>
#include <linux/libfdt.h>
#include <mapmem.h>
#include <asm/io.h>
+#include <tee/optee.h>
#ifndef CONFIG_SYS_FDT_PAD
#define CONFIG_SYS_FDT_PAD 0x3000
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);
#endif
static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr,
- uint64_t size)
+ uint64_t size, enum lmb_flags flags)
{
- int ret;
+ long ret;
- ret = lmb_reserve(lmb, addr, size);
- if (!ret) {
- debug(" reserving fdt memory region: addr=%llx size=%llx\n",
- (unsigned long long)addr, (unsigned long long)size);
+ ret = lmb_reserve_flags(lmb, addr, size, flags);
+ if (ret >= 0) {
+ debug(" reserving fdt memory region: addr=%llx size=%llx flags=%x\n",
+ (unsigned long long)addr,
+ (unsigned long long)size, flags);
} else {
puts("ERROR: reserving fdt memory region failed ");
- printf("(addr=%llx size=%llx)\n",
- (unsigned long long)addr, (unsigned long long)size);
+ printf("(addr=%llx size=%llx flags=%x)\n",
+ (unsigned long long)addr,
+ (unsigned long long)size, flags);
}
}
int i, total, ret;
int nodeoffset, subnode;
struct fdt_resource res;
+ enum lmb_flags flags;
if (fdt_check_header(fdt_blob) != 0)
return;
for (i = 0; i < total; i++) {
if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0)
continue;
- boot_fdt_reserve_region(lmb, addr, size);
+ boot_fdt_reserve_region(lmb, addr, size, LMB_NONE);
}
/* process reserved-memory */
/* check if this subnode has a reg property */
ret = fdt_get_resource(fdt_blob, subnode, "reg", 0,
&res);
- if (!ret) {
+ if (!ret && fdtdec_get_is_enabled(fdt_blob, subnode)) {
+ flags = LMB_NONE;
+ if (fdtdec_get_bool(fdt_blob, subnode,
+ "no-map"))
+ flags = LMB_NOMAP;
addr = res.start;
size = res.end - res.start + 1;
- boot_fdt_reserve_region(lmb, addr, size);
+ boot_fdt_reserve_region(lmb, addr, size, flags);
}
subnode = fdt_next_subnode(fdt_blob, subnode);
/* If fdt_high is set use it to select the relocation address */
fdt_high = env_get("fdt_high");
if (fdt_high) {
- void *desired_addr = (void *)simple_strtoul(fdt_high, NULL, 16);
+ void *desired_addr = (void *)hextoul(fdt_high, NULL);
if (((ulong) desired_addr) == ~0UL) {
/* All ones means use fdt in place */
* 1, if fdt image is found but corrupted
* of_flat_tree and of_size are set to 0 if no fdt exists
*/
-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)
+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;
int fdt_noffset;
#endif
const char *select = NULL;
- int ok_no_fdt = 0;
*of_flat_tree = NULL;
*of_size = 0;
- img_addr = simple_strtoul(argv[0], NULL, 16);
+ img_addr = (argc == 0) ? image_load_addr :
+ hextoul(argv[0], NULL);
buf = map_sysmem(img_addr, 0);
if (argc > 2)
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)) {
} else
#endif
{
- fdt_addr = simple_strtoul(select, NULL, 16);
+ fdt_addr = hextoul(select, NULL);
debug("* fdt: cmdline image address = 0x%08lx\n",
fdt_addr);
}
*/
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",
*/
#if CONFIG_IS_ENABLED(FIT)
/* check FDT blob vs FIT blob */
- if (fit_check_format(buf)) {
+ if (!fit_check_format(buf, IMAGE_SIZE_INVAL)) {
ulong load, len;
fdt_noffset = boot_get_fdt_fit(images,
&fit_uname_config,
arch, &load, &len);
+ if (fdt_noffset < 0)
+ goto error;
+
images->fit_hdr_fdt = map_sysmem(fdt_addr, 0);
images->fit_uname_fdt = fit_uname_fdt;
images->fit_noffset_fdt = fdt_noffset;
break;
default:
puts("ERROR: Did not find a cmdline Flattened Device Tree\n");
- goto no_fdt;
+ goto error;
}
printf(" Booting using the fdt blob at %#08lx\n", fdt_addr);
#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;
+ ulong fdt_data, fdt_len;
+ u32 fdt_size, dtb_idx;
+ /*
+ * Firstly check if this android boot image has dtb field.
+ */
+ dtb_idx = (u32)env_get_ulong("adtb_idx", 10, 0);
+ if (android_image_get_dtb_by_index((ulong)hdr, dtb_idx, &fdt_addr, &fdt_size)) {
+ fdt_blob = (char *)map_sysmem(fdt_addr, 0);
+ if (fdt_check_header(fdt_blob))
+ goto no_fdt;
- if (android_image_get_second(hdr, &fdt_data, &fdt_len) != 0)
- goto no_fdt;
+ debug("## Using FDT in Android image dtb area with idx %u\n", dtb_idx);
+ } else 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;
- fdt_blob = (char *)fdt_data;
- if (fdt_check_header(fdt_blob) != 0)
- goto no_fdt;
+ debug("## Using FDT in Android image second area\n");
+ } else {
+ fdt_addr = env_get_hex("fdtaddr", 0);
+ if (!fdt_addr)
+ goto no_fdt;
- if (fdt_totalsize(fdt_blob) != fdt_len)
- goto error;
+ fdt_blob = map_sysmem(fdt_addr, 0);
+ if (fdt_check_header(fdt_blob))
+ goto no_fdt;
- debug("## Using FDT found in Android image second area\n");
+ debug("## Using FDT at ${fdtaddr}=Ox%lx\n", fdt_addr);
+ }
#endif
} else {
debug("## No Flattened Device Tree\n");
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;
}
printf("ERROR: arch-specific fdt fixup failed\n");
goto err;
}
+
+ fdt_ret = optee_copy_fdt_nodes(blob);
+ if (fdt_ret) {
+ printf("ERROR: transfer of optee nodes to new fdt failed: %s\n",
+ fdt_strerror(fdt_ret));
+ goto err;
+ }
+
/* Update ethernet nodes */
fdt_fixup_ethernet(blob);
+#if CONFIG_IS_ENABLED(CMD_PSTORE)
+ /* Append PStore configuration */
+ fdt_fixup_pstore(blob);
+#endif
if (IMAGE_OF_BOARD_SETUP) {
- fdt_ret = ft_board_setup(blob, gd->bd);
- if (fdt_ret) {
- printf("ERROR: board-specific fdt fixup failed: %s\n",
- fdt_strerror(fdt_ret));
- goto err;
+ const char *skip_board_fixup;
+
+ skip_board_fixup = env_get("skip_board_fixup");
+ if (skip_board_fixup && ((int)simple_strtol(skip_board_fixup, NULL, 10) == 1)) {
+ printf("skip board fdt fixup\n");
+ } else {
+ fdt_ret = ft_board_setup(blob, gd->bd);
+ if (fdt_ret) {
+ printf("ERROR: board-specific fdt fixup failed: %s\n",
+ fdt_strerror(fdt_ret));
+ goto err;
+ }
}
}
if (IMAGE_OF_SYSTEM_SETUP) {