summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2017-05-22 11:05:30 (GMT)
committerTom Rini <trini@konsulko.com>2017-06-05 18:13:06 (GMT)
commit25e7dc6a6a798451973b2a3d7c02edc3658b270d (patch)
tree539affa59aa67cc86112c2159edf6ff4aaa3e83a /common
parentff00226e0b55d08c55fca843ff9c4819b247e08c (diff)
downloadu-boot-25e7dc6a6a798451973b2a3d7c02edc3658b270d.tar.xz
bootstage: Support relocating boostage data
Some boards cannot access pre-relocation data after relocation. Reserve space for this and copy it during preparation for relocation. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/board_f.c34
-rw-r--r--common/bootstage.c5
2 files changed, 39 insertions, 0 deletions
diff --git a/common/board_f.c b/common/board_f.c
index 783c51a..14abb42 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -491,6 +491,20 @@ static int reserve_fdt(void)
return 0;
}
+static int reserve_bootstage(void)
+{
+#ifdef CONFIG_BOOTSTAGE
+ int size = bootstage_get_size();
+
+ gd->start_addr_sp -= size;
+ gd->new_bootstage = map_sysmem(gd->start_addr_sp, size);
+ debug("Reserving %#x Bytes for bootstage at: %08lx\n", size,
+ gd->start_addr_sp);
+#endif
+
+ return 0;
+}
+
int arch_reserve_stacks(void)
{
return 0;
@@ -605,6 +619,24 @@ static int reloc_fdt(void)
return 0;
}
+static int reloc_bootstage(void)
+{
+#ifdef CONFIG_BOOTSTAGE
+ if (gd->flags & GD_FLG_SKIP_RELOC)
+ return 0;
+ if (gd->new_bootstage) {
+ int size = bootstage_get_size();
+
+ debug("Copying bootstage from %p to %p, size %x\n",
+ gd->bootstage, gd->new_bootstage, size);
+ memcpy(gd->new_bootstage, gd->bootstage, size);
+ gd->bootstage = gd->new_bootstage;
+ }
+#endif
+
+ return 0;
+}
+
static int setup_reloc(void)
{
if (gd->flags & GD_FLG_SKIP_RELOC) {
@@ -828,6 +860,7 @@ static const init_fnc_t init_sequence_f[] = {
setup_machine,
reserve_global_data,
reserve_fdt,
+ reserve_bootstage,
reserve_arch,
reserve_stacks,
dram_init_banksize,
@@ -849,6 +882,7 @@ static const init_fnc_t init_sequence_f[] = {
#endif
INIT_FUNC_WATCHDOG_RESET
reloc_fdt,
+ reloc_bootstage,
setup_reloc,
#if defined(CONFIG_X86) || defined(CONFIG_ARC)
copy_uboot_to_ram,
diff --git a/common/bootstage.c b/common/bootstage.c
index 32f4e8b..a6705af 100644
--- a/common/bootstage.c
+++ b/common/bootstage.c
@@ -484,6 +484,11 @@ int bootstage_unstash(void *base, int size)
return 0;
}
+int bootstage_get_size(void)
+{
+ return sizeof(struct bootstage_data);
+}
+
int bootstage_init(bool first)
{
struct bootstage_data *data;