diff mbox

[U-Boot,09/15] bootstage: Support relocating boostage data

Message ID 20170522110536.6231-10-sjg@chromium.org
State Accepted
Commit 25e7dc6a6a798451973b2a3d7c02edc3658b270d
Delegated to: Tom Rini
Headers show

Commit Message

Simon Glass May 22, 2017, 11:05 a.m. UTC
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                  | 34 ++++++++++++++++++++++++++++++++++
 common/bootstage.c                |  5 +++++
 include/asm-generic/global_data.h |  1 +
 include/bootstage.h               | 12 ++++++++++++
 4 files changed, 52 insertions(+)

Comments

Tom Rini June 6, 2017, 12:21 a.m. UTC | #1
On Mon, May 22, 2017 at 05:05:30AM -0600, Simon Glass wrote:

> 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>

Applied to u-boot/master, thanks!
diff mbox

Patch

diff --git a/common/board_f.c b/common/board_f.c
index a4f8627ddf..96949eba3c 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -488,6 +488,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;
@@ -602,6 +616,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) {
@@ -825,6 +857,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,
@@ -846,6 +879,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;