[U-Boot] passing info from SPL to U-Boot
Simon Glass
sjg at chromium.org
Thu Mar 14 10:02:29 UTC 2019
Hi Heiko,
On Tue, 12 Mar 2019 at 02:50, Heiko Schocher <hs at 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.
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.
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?
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.
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.
Regards,
Simon
More information about the U-Boot
mailing list