[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