Hello Simon,
Am 14.03.2019 um 11:02 schrieb Simon Glass:
Hi Heiko,
On Tue, 12 Mar 2019 at 02:50, Heiko Schocher <h...@denx.de> wrote:
Hello Simon, Tom,
Am 12.03.2019 um 09:21 schrieb Heiko Schocher:
Hello Simon, Tom,
I am just stumbeld on an am437x basd board over the problem to pass
the bootmode from SPL to U-Boot. On am437x the bootmode info get
overwritten from SPL stack, and I need this info in U-Boot.
Hack would be to move SPL stack to another address, but we loose
than 0xa000 size for stack ... I do not want to go this way..
I thought gd info is passed from SPL to U-Boot, but this is not the case!
Looking into
...
75 bic r0, r0, #7 /* 8-byte alignment for ABI compliance */
76 mov sp, r0
77 bl board_init_f_alloc_reserve
78 mov sp, r0
79 /* set up gd here, outside any C code */
80 mov r9, r0
81 bl board_init_f_init_reserve
and common/init/board_init.c:
99 void board_init_f_init_reserve(ulong base)
100 {
101 struct global_data *gd_ptr;
102
103 /*
104 * clear GD entirely and set it up.
105 * Use gd_ptr, as gd may not be properly set yet.
106 */
107
108 gd_ptr = (struct global_data *)base;
109 /* zero the area */
110 memset(gd_ptr, '\0', sizeof(*gd));
111 /* set GD unless architecture did it already */
112 #if !defined(CONFIG_ARM)
113 arch_setup_gd(gd_ptr);
114 #endif
gd is always initialized with zeros, no chance for passing infos from
SPL to U-Boot...
I really thought, that gd_t was intentionally designed for passing data
between different U-Boot states, but looking into gd_t definiton in
include/asm-generic/global_data.h it is a big ifdef mess and not useable
as an "API" between TPL/SPL and U-Boot ...
I thought also, that SPL detects for example ramsize and than passes
this info to U-Boot ...
But Ok, I found "common/init/handoff.c" which seems now the way to go, but:
./common/board_f.c
281 static int setup_spl_handoff(void)
282 {
283 #if CONFIG_IS_ENABLED(HANDOFF)
284 gd->spl_handoff = bloblist_find(BLOBLISTT_SPL_HANDOFF,
285 sizeof(struct spl_handoff));
286 debug("Found SPL hand-off info %p\n", gd->spl_handoff);
287 #endif
288
289 return 0;
290 }
There is gd->spl_handoff used ... how could this work at least on arm,
if gd is set to zeros on init ?
Do I miss something obvious?
Sorry for being so stupid, with:
common/board_f.c
853 #ifdef CONFIG_BLOBLIST
854 bloblist_init,
855 #endif
856 setup_spl_handoff,
and common/bloblist.c
216 int bloblist_init(void)
217 {
218 bool expected;
219 int ret = -ENOENT;
220
221 /**
222 * Wed expect to find an existing bloblist in the first phase of
U-Boot
223 * that runs
224 */
225 expected = !u_boot_first_phase();
226 if (expected)
227 ret = bloblist_check(CONFIG_BLOBLIST_ADDR,
228 CONFIG_BLOBLIST_SIZE);
gd->spl_handoff gets setup through bloblist_find() ...
But beside sandbox there is no current user currently, or?
$ grep -lr BLOBLIST_ADDR .
./test/bloblist.c
./include/bloblist.h
./common/bloblist.c
./common/Kconfig
./board/sandbox/README.sandbox
$
Yes that's right, it is not used outside sandbox, although there are
patches to use it on x86.
Thanks for clarifying!
I think it is a reasonable idea to allow the gd region to pass from
TPL -> SPL -> U-Boot. But we'll need to remove use of
CONFIG_IS_ENABLED(), or put shared things at the beginning of the
structure.
I thought about putting interchangeable things at the beginning
of gd_t.
The big advantage of a bloblist is, that you only need to parse it
and you know, what values are really setup from the previous stage.
Passing structs is not ideal, but small ... but may error prone?
Can we always be sure, previous stage sets up all info in gd_t
next stage expects?
We need the concept of 'am I the first thing to run'. This is
implemented in bloblist as u_boot_first_phase() - see spl.h. If this
is true, we must set up the data structure. If false we must find one
set up by a previous phase and use it. Bloblist handles this, but
perhaps gd could as well?
Yes, this could be used.
Also consider the scenario where there is a read-only TPL programmed
in manufacture that never changes, and a read-write SPL + U-Boot that
can be upgraded in the field. In this case they may eventually end up
being built with different versions of U-Boot. The bloblist structure
is intended to handle this by at least checking that the size matches.
Just experimenting with:
diff --git a/common/init/board_init.c b/common/init/board_init.c
index 526fee35ff..bdb4b6364d 100644
--- a/common/init/board_init.c
+++ b/common/init/board_init.c
@@ -96,9 +96,10 @@ ulong board_init_f_alloc_reserve(ulong top)
* (seemingly useless) incrementation causes no code increase.
*/
-void board_init_f_init_reserve(ulong base)
+void board_init_f_init_reserve(ulong base, ulong oldgd)
{
struct global_data *gd_ptr;
+ struct global_data *gd_ptr_old;
/*
* clear GD entirely and set it up.
@@ -106,8 +107,22 @@ void board_init_f_init_reserve(ulong base)
*/
gd_ptr = (struct global_data *)base;
- /* zero the area */
- memset(gd_ptr, '\0', sizeof(*gd));
+ gd_ptr_old = (struct global_data *)oldgd;
+ if (u_boot_first_phase() ||
+ oldgd == 0 ||
+ !(((gd_ptr->magic == UBOOT_GD_MAGIC) &&
+ (gd_ptr->gd_size == sizeof(struct global_data))))) {
+ /* setup gd, zero the area ... */
+ memset(gd_ptr, '\0', sizeof(*gd));
+ /* ... and set magic and size information */
+ gd_ptr->magic = UBOOT_GD_MAGIC;
+ gd_ptr->gd_size = sizeof(struct global_data);
+ } else {
+ /*
+ * in case we get an already initialised gd_pointer
+ * use the info from already existing oldgd.
+ */
+ }
/* set GD unless architecture did it already */
#if !defined(CONFIG_ARM)
arch_setup_gd(gd_ptr);
diff --git a/include/asm-generic/global_data.h
b/include/asm-generic/global_data.h
index 78dcf40bff..3a5063dbe1 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -23,8 +23,11 @@
#include <membuff.h>
#include <linux/list.h>
+#define UBOOT_GD_MAGIC 0x19730517
typedef struct global_data {
bd_t *bd;
+ unsigned long magic;
+ int gd_size;
unsigned long flags;
unsigned int baudrate;
unsigned long cpu_clk; /* CPU clock in Hz! */
(after moving u_boot_first_phase() to include/common.h)
But it is WIP, nothing functional yet...
Related, I feel that we should figure out how to use registers to pass
addresses from SPL to U-Boot. On ARM we could use r0 to pass the value
of gd, perhaps.
Perhaps, yes.
bye,
Heiko
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52 Fax: +49-8142-66989-80 Email: h...@denx.de
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot