[U-Boot] OMAP (4) boot_params
Michael Cashwell
mboards at prograde.net
Wed Apr 3 00:39:17 CEST 2013
Greetings,
I've been fighting with SPL passing not boot_params properly to u-boot on OMAP4. There are many layers to this onion but I've tracked the bulk of the problem down to the following issues.
--- SPL ---
arch/arm/cpu/armv7/omap-common/hwinit-common.c sets a pointer to the SPL's &boot_params correctly (cpu_init_crit->lowlevel_init->s_init) but the definition of that pointer in common/spl/spl.c:
u32 *boot_params_ptr = NULL;
puts it into the spl bss section (in SDRAM) which is cleared long after cpu_init_crit(). Making that:
u32 *boot_params_ptr __attribute__ ((section(".data")));
allows the pointer to be in SPL data section (SRAM) and still have its value by the time image_entry() is called. But common/spl/spl.c is not omap-specific so changes there are a concern.
Next, image_entry() is called with the argument being indirected an extra time:
u32 boot_params_ptr_addr = (u32)&boot_params_ptr;
image_entry((u32 *)boot_params_ptr_addr);
That extra level of indirection is never dealt with (on ARM anyway) and it ends up passing junk to u-boot. I've tested replacing those lines with:
image_entry((u32 *)boot_params_ptr);
and that passes a correct address in r0 to lowlevel_init.S in u-boot.
--- u-boot ---
lowlevel_init.S only deals with pointers for boot_params. It does not *copy* the content of the boot_params struct. With the fixes above we get to u-boot with *the address in SRAM* of the SPL's boot_params struct stored in the first word of u-boot's boot_params struct. Here's logging showing what I have working to this point:
U-Boot SPL 2013.04-rc1-00386-g1d3dea1-dirty (Apr 02 2013 - 17:21:36)
OMAP4460 ES1.1
boot_params_ptr @40309a5c = 40309918
OMAP SD/MMC: 0
image entry point: 0xBF800000
U-Boot 2013.04-rc1-00386-g1d3dea1-dirty (Apr 02 2013 - 17:21:36)
<<< a debug %p print of & boot_params in board_mmc_init said bffdbf10 >>>
# md 0xbffdbf10 4
bffdbf10: 40309918 00000000 00000000 bffd297c
<<< 40309918 is the expected SPL &boot_params in SRAM as noted above >>>
# md 40309918 5
40309918: 4030d204 00000000 00000005 00000001
40309928: 00000001
That maps to the expected (omap_bootdevice == 5 being salient for me):
struct omap_boot_parameters {
char *boot_message;
unsigned int mem_boot_descriptor;
unsigned char omap_bootdevice;
unsigned char reset_reason;
unsigned char ch_flags;
};
That leaves me at an impasse. If we expect to have a struct in both contexts then something must copy its contents. That's not currently done.
Or we could have a struct in SPL but a *struct in u-boot. But that mixes the . and -> access syntax and there may be source that's agnostic to being in the SPL or u-boot.
The last idea I had was to make the SPL struct hidden and only use a pointer for access. That means both SPL and u-boot source could use the -> syntax.
The only places where I see this are:
./arch/arm/cpu/armv7/omap-common/boot-common.c: return (u32) (boot_params.omap_bootdevice);
./arch/arm/include/asm/arch-omap4/sys_proto.h:extern struct omap_boot_parameters boot_params;
./arch/arm/include/asm/arch-omap4/sys_proto.h: if ((boot_params.ch_flags) & (CH_FLAGS_CHSETTINGS))
./arch/arm/include/asm/arch-omap5/sys_proto.h:extern struct omap_boot_parameters boot_params;
./arch/arm/include/asm/arch-omap5/sys_proto.h: if ((boot_params.ch_flags) & (CH_FLAGS_CHSETTINGS))
but I have no OMAP5 to test against. And I'm a little surprised that OMAP3 isn't in evidence here.
This has me wrapped around the axle so many times I need guidance regarding what's "the right way" to fix this.
Pointers welcome. (pun intended.)
-Mike Cashwell
More information about the U-Boot
mailing list