[U-Boot] initcall revisited - A new idea to discuss

Graeme Russ graeme.russ at gmail.com
Fri Jan 6 05:59:48 CET 2012


Hi Simon,

On Fri, Jan 6, 2012 at 3:30 PM, Simon Glass <sjg at chromium.org> wrote:
> Hi Graham,
>
> On Thu, Jan 5, 2012 at 2:18 PM, Graeme Russ <graeme.russ at gmail.com> wrote:
>> Hi Wolfgang,
>>
>> On Wed, Jan 4, 2012 at 1:44 AM, Wolfgang Denk <wd at denx.de> wrote:
>>> Dear Graeme,
>>>
>>> In message <4F02DA64.60502 at gmail.com> you wrote:
>>>>
>>

[snip]

>>>
>>> One thing comes to mind: it would be nice if we can find a way that
>>> the INIT_FUNC definitions behave similar to "weak" functions - if an
>>> init_func can be redefined / overwritten / modified by board specific
>>> code we eventually have a very nice way to get rid of the related
>>> #ifdef's.
>>
>> I have a thought on this. How about a SKIP_INIT macro. Here's the idea
>> using SDRAM as an example:
>>
>> At the arch level you may have
>>
>> INIT_FUNC(sdram_init, f, "sdram", "console","")
>
> Gosh this email took a few readings :-)
>
> Can we get rid of the 'f' parameter? If we invent a prerequisite
> called 'relocated' or something like that, to act as a barrier, then
> maybe the order can be defined just like any other function which
> depends on being before or after something?

Well I kind of like see that a particular init function is explicitly a
pre- or post- relocation function. But yes, having barrier pre-requisites
would achieve the same effect.

>> so sdram_init sets the "sdram" requisite and must be done after all
>> "console" requisites have been completed.
>>
>> Now if a SoC or board has an init that must be done before SDRAM:
>>
>> INIT_FUNC(pre_sdram_init, f, "pre_sdram", "", "sdram")
>>
>> So this sets the pre_sdram requisite, requires no other initialisation
>> before running and must happen before and "sdram" init functions are run
>>
>> Now lets say the Soc or board has a unique sdram init function that
>> overrides the arch's sdram init. We could just use weak functions and
>> allow the SoC or board to override sdram_init. But what if the SoC or
>> board has additional pre-requisite (or post-requisite) init requirements?
>>
>> So in the SoC or board file:
>>
>> SKIP_INIT(sdram)
>> INIT_FUNC(board_sdram_init, f, "board_sdram","pre_sdram,vreg,console", "")
>>
>> Using "board_sdram" versus "sdram_init" is cricital:
>>
>> The init sequence build tool will first create the entire init sequence
>> including the functions marked as "sdram" and "board_sdram". But after
>> building the arrays, it will strip out all the functions marked as "sdram"
>> init functions. The reason the entire list has to be build first is so the
>> functions that rely on "sdram" can be added without unmet prerequisite
>> errors.
>>
>> Of course, if you use SKIP_INIT(foo), you need to make sure that any
>> replacement INIT_FUNC will do everything foo did to make your board work.
>>
>> Interestingly, this allows the following:
>>
>> INIT_FUNC(calc_relocation, fr, "calc_reloc", "sdram", "")
>> INIT_FUNC(copy_uboot_to_ram, fr, "copy_to_ram", "calc_relocation", "")
>> INIT_FUNC(do_elf_reloc_adjusments, fr, "elf_reloc", "copy_to_ram", "")
>> INIT_FUNC(clear_bss, fr, "clear_bss", "calc_reloc", "")
>>
>> #ifdef CONFIG_SYS_SKIP_RELOCATION
>> SKIP_INIT(calc_reloc)
>> SKIP_INIT(copy_to_ram)
>> SKIP_INIT(elf_reloc)
>> #endif
>>
>> So if CONFIG_SYS_SKIP_RELOCATION is defined, relocation is not performed,
>> but clear_bss still is
>>
>
> I wonder what happens when you skip something - does it substitute for
> any pre/post-requisites that the skipped item had? Or would that be
> illegal?

SKIP_INIT(foo) simply removes all 'foo' init functions from the list
_after_ the list has been created - If this breaks dependencies that's
your problem ;). It is up to you as the 'skipper' to make sure that you
add init functions to allow things to still work

> I can see plenty of opportunity for confusion, but if the tool is
> friendly enough, then this could solve a lot of the override problems.
> In your particular example it feels like it would be easier to just
> make the INIT_FUNC conditional on an config using #ifdef (horror!), or
> perhaps yet another parameter(!)

The idea behind this all is that we do not know today what we will need
tomorrow. Our biggest issue right now is that if a board needs to tweak
the init sequence, it needs to touch arch/foo/board.c and hence introduces
the potential to break working boards.

With this proposal, if a board wants to entirely re-write the init
sequence, it can add a whole bunch of SKIP_INIT(blah) and then add it's
own INIT_FUNC(init_func, "myboard_bar"...) and nobody else will be the
wiser as to what is going on. The problem the is if the arch adds a new
init step, it may not be covered by the skip list by that board - tough,
lesson learn't for being so esoteric ;)

> Or we could just put those relocation functions in their own file and
> have it omitted from the build by the Makefile in the case where
> CONFIG_SYS_SKIP_RELOCATION is defined.

Exactly. My example was a poor practical example, but it demonstrated a
point. Obviously, clear_bss() does not belong with the relocation code

> And if we want wanting to replace a generic function with a
> board-specific one, why not just something like:
>
> INIT_OVERRIDE(new_func, old_func)

In such circumstances, we still have weak functions. I see no reason to
not keep on using weak functions for init functions that have well defined
override scenarios (cache initialisation is a prime example, so is timer
initialisation)

> Anyway, it sounds very promising.

Yes, it's a lot better than my original proposal :)

Regards,

Graeme


More information about the U-Boot mailing list