#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>
#endif
static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr,
- uint64_t size)
+ uint64_t size, enum lmb_flags flags)
{
long ret;
- ret = lmb_reserve(lmb, addr, size);
+ ret = lmb_reserve_flags(lmb, addr, size, flags);
if (ret >= 0) {
- debug(" reserving fdt memory region: addr=%llx size=%llx\n",
- (unsigned long long)addr, (unsigned long long)size);
+ 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 */
ret = fdt_get_resource(fdt_blob, subnode, "reg", 0,
&res);
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 */
*of_size = 0;
img_addr = (argc == 0) ? image_load_addr :
- simple_strtoul(argv[0], NULL, 16);
+ hextoul(argv[0], NULL);
buf = map_sysmem(img_addr, 0);
if (argc > 2)
} else
#endif
{
- fdt_addr = simple_strtoul(select, NULL, 16);
+ fdt_addr = hextoul(select, NULL);
debug("* fdt: cmdline image address = 0x%08lx\n",
fdt_addr);
}
*/
#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) &&
- !fdt_check_header((char *)fdt_data)) {
+ 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;
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) {
}
}
- 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,