summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2011-06-29 17:13:54 -0700
committerSimon Glass <sjg@chromium.org>2011-08-29 10:39:45 -0700
commit98d36524cd5008d7d55adefc306bba7cb9c2cf5a (patch)
treec80a3bb28ec1d11b250ccc97b4e099cca517a2eb /arch
parentef2578b4e43353d17a1ae56060c9ebdfea1ab682 (diff)
fdt: Implement fdt relocation
The fdt blob needs to be relocated as part of the general relocation effort. BUG=chromium-os:17075 TEST=Build and boot U-Boot with CONFIG_OF_EMBED and CONFIG_OF_SEPARATE with DEBUG on in arch/arm/lib/board.c. Check that FDT is relocated correctly in the CONFIG_OF_SEPARATE case. Also check with and without CONFIG_SYS_SKIP_ARM_RELOCATION. Change-Id: I06b52132d6cc4e15bb99227650432d2184bc19ec Reviewed-on: http://gerrit.chromium.org/gerrit/3477 Tested-by: Simon Glass <sjg@chromium.org> Reviewed-by: Stefan Reinauer <reinauer@google.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/lib/board.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 2f34677e873..c3dcbba1ee9 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -271,6 +271,8 @@ void board_init_f (ulong bootflag)
init_fnc_t **init_fnc_ptr;
gd_t *id;
ulong addr, addr_sp;
+ void *new_fdt = NULL;
+ size_t fdt_size = 0;
#ifdef CONFIG_OF_EMBED
extern u8 _binary_dt_dtb_start[];
#endif
@@ -404,6 +406,22 @@ void board_init_f (ulong bootflag)
debug ("Reserving %zu Bytes for Global Data at: %08lx\n",
sizeof (gd_t), addr_sp);
+#ifdef CONFIG_OF_SEPARATE
+ /*
+ * If the device tree is sitting immediate above our image then we
+ * must relocate it. If it is embedded in the data section, then it
+ * will be relocated with other data.
+ */
+ if (gd->blob) {
+ fdt_size = ALIGN(fdt_totalsize(gd->blob) + 0x1000, 32);
+
+ addr_sp -= fdt_size;
+ new_fdt = (void *)addr_sp;
+ debug ("Reserving %zu Bytes for FDT at: %08lx\n",
+ fdt_size, addr_sp);
+ }
+#endif
+
/* setup stackpointer for exeptions */
gd->irq_sp = addr_sp;
#ifdef CONFIG_USE_IRQ
@@ -435,11 +453,16 @@ void board_init_f (ulong bootflag)
#ifdef CONFIG_SYS_SKIP_ARM_RELOCATION
addr = _TEXT_BASE;
+ debug("Code relocation disabled by CONFIG_SYS_SKIP_ARM_RELOCATION\n");
#endif
gd->relocaddr = addr;
gd->start_addr_sp = addr_sp;
gd->reloc_off = addr - _TEXT_BASE;
debug ("relocation Offset is: %08lx\n", gd->reloc_off);
+ if (new_fdt) {
+ memcpy(new_fdt, gd->blob, fdt_size);
+ gd->blob = new_fdt;
+ }
memcpy (id, (void *)gd, sizeof (gd_t));
relocate_code (addr_sp, id, addr);