From 8bee2d251afb61c203aa94877cf5077731822ed5 Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Mon, 13 Nov 2017 18:55:03 -0700
Subject: [PATCH] binman: Add binman symbol support to SPL

Allow SPL to access binman symbols and use this to get the address of
U-Boot. This falls back to CONFIG_SYS_TEXT_BASE if the binman symbol
is not available.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
 common/spl/spl.c     | 16 ++++++++++++++--
 include/binman_sym.h | 13 +++++++++++++
 include/spl.h        | 11 +++++++++++
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/common/spl/spl.c b/common/spl/spl.c
index 3bb20c7822..76c1963611 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -8,6 +8,7 @@
  */
 
 #include <common.h>
+#include <binman_sym.h>
 #include <dm.h>
 #include <spl.h>
 #include <asm/u-boot.h>
@@ -32,6 +33,9 @@ DECLARE_GLOBAL_DATA_PTR;
 
 u32 *boot_params_ptr = NULL;
 
+/* See spl.h for information about this */
+binman_sym_declare(ulong, u_boot_any, pos);
+
 /* Define board data structure */
 static bd_t bdata __attribute__ ((section(".data")));
 
@@ -120,9 +124,17 @@ __weak void spl_board_prepare_for_boot(void)
 
 void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
 {
+	ulong u_boot_pos = binman_sym(ulong, u_boot_any, pos);
+
 	spl_image->size = CONFIG_SYS_MONITOR_LEN;
-	spl_image->entry_point = CONFIG_SYS_UBOOT_START;
-	spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
+	if (u_boot_pos != BINMAN_SYM_MISSING) {
+		/* biman does not support separate entry addresses at present */
+		spl_image->entry_point = u_boot_pos;
+		spl_image->load_addr = u_boot_pos;
+	} else {
+		spl_image->entry_point = CONFIG_SYS_UBOOT_START;
+		spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
+	}
 	spl_image->os = IH_OS_U_BOOT;
 	spl_image->name = "U-Boot";
 }
diff --git a/include/binman_sym.h b/include/binman_sym.h
index 3999b26d8d..87d03d5294 100644
--- a/include/binman_sym.h
+++ b/include/binman_sym.h
@@ -37,6 +37,17 @@
 	_type binman_symname(_entry_name, _prop_name) \
 		__attribute__((aligned(4), unused, section(".binman_sym")))
 
+/**
+ * binman_sym_extern() - Declare a extern symbol that will be used at run-time
+ *
+ * @_type: Type f the symbol (e.g. unsigned long)
+ * @entry_name: Name of the entry to look for (e.g. 'u_boot_spl')
+ * @_prop_name: Property value to get from that entry (e.g. 'pos')
+ */
+#define binman_sym_extern(_type, _entry_name, _prop_name) \
+	extern _type binman_symname(_entry_name, _prop_name) \
+		__attribute__((aligned(4), unused, section(".binman_sym")))
+
 /**
  * binman_sym_declare_optional() - Declare an optional symbol
  *
@@ -73,6 +84,8 @@
 
 #define binman_sym_declare_optional(_type, _entry_name, _prop_name)
 
+#define binman_sym_extern(_type, _entry_name, _prop_name)
+
 #define binman_sym(_type, _entry_name, _prop_name) BINMAN_SYM_MISSING
 
 #endif /* BINMAN */
diff --git a/include/spl.h b/include/spl.h
index 308ce7b563..c14448b8fc 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -7,6 +7,8 @@
 #ifndef	_SPL_H_
 #define	_SPL_H_
 
+#include <binman_sym.h>
+
 /* Platform-specific defines */
 #include <linux/compiler.h>
 #include <asm/spl.h>
@@ -51,6 +53,15 @@ struct spl_load_info {
 		      void *buf);
 };
 
+/*
+ * We need to know the position of U-Boot in memory so we can jump to it. We
+ * allow any U-Boot binary to be used (u-boot.bin, u-boot-nodtb.bin,
+ * u-boot.img), hence the '_any'. These is no checking here that the correct
+ * image is found. For * example if u-boot.img is used we don't check that
+ * spl_parse_image_header() can parse a valid header.
+ */
+binman_sym_extern(ulong, u_boot_any, pos);
+
 /**
  * spl_load_simple_fit() - Loads a fit image from a device.
  * @spl_image:	Image description to set up
-- 
2.39.5