bootstage: Support relocating boostage data
authorSimon Glass <sjg@chromium.org>
Mon, 22 May 2017 11:05:30 +0000 (05:05 -0600)
committerTom Rini <trini@konsulko.com>
Mon, 5 Jun 2017 18:13:06 +0000 (14:13 -0400)
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>
common/board_f.c
common/bootstage.c
include/asm-generic/global_data.h
include/bootstage.h

index 783c51a..14abb42 100644 (file)
@@ -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,
index 32f4e8b..a6705af 100644 (file)
@@ -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;
index 8b3229e..fb90be9 100644 (file)
@@ -112,6 +112,7 @@ typedef struct global_data {
 #endif
 #ifdef CONFIG_BOOTSTAGE
        struct bootstage_data *bootstage;       /* Bootstage information */
+       struct bootstage_data *new_bootstage;   /* Relocated bootstage info */
 #endif
 } gd_t;
 #endif
index 41bd617..8607e88 100644 (file)
@@ -331,6 +331,13 @@ int bootstage_stash(void *base, int size);
  */
 int bootstage_unstash(void *base, int size);
 
+/**
+ * bootstage_get_size() - Get the size of the bootstage data
+ *
+ * @return size of boostage data in bytes
+ */
+int bootstage_get_size(void);
+
 /**
  * bootstage_init() - Prepare bootstage for use
  *
@@ -400,6 +407,11 @@ static inline int bootstage_unstash(void *base, int size)
        return 0;       /* Pretend to succeed */
 }
 
+static inline int bootstage_get_size(void)
+{
+       return 0;
+}
+
 static inline int bootstage_init(bool first)
 {
        return 0;