diff options
author | Simon Glass <sjg@chromium.org> | 2017-05-22 14:05:30 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2017-06-05 21:13:06 +0300 |
commit | 25e7dc6a6a798451973b2a3d7c02edc3658b270d (patch) | |
tree | 539affa59aa67cc86112c2159edf6ff4aaa3e83a | |
parent | ff00226e0b55d08c55fca843ff9c4819b247e08c (diff) | |
download | u-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>
-rw-r--r-- | common/board_f.c | 34 | ||||
-rw-r--r-- | common/bootstage.c | 5 | ||||
-rw-r--r-- | include/asm-generic/global_data.h | 1 | ||||
-rw-r--r-- | include/bootstage.h | 12 |
4 files changed, 52 insertions, 0 deletions
diff --git a/common/board_f.c b/common/board_f.c index 783c51a685..14abb42814 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 32f4e8b706..a6705af111 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; diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 8b3229e5b8..fb90be9d3e 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -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 diff --git a/include/bootstage.h b/include/bootstage.h index 41bd61785c..8607e887d8 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -332,6 +332,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 * * @first: true if this is the first time bootstage is set up. This causes it @@ -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; |