
Hi,
On Fri, Jan 06, 2012 at 10:29:48, Graeme Russ wrote:
Hi Simon,
On Fri, Jan 6, 2012 at 3:30 PM, Simon Glass sjg@chromium.org wrote:
Hi Graham,
On Thu, Jan 5, 2012 at 2:18 PM, Graeme Russ graeme.russ@gmail.com wrote:
Hi Wolfgang,
On Wed, Jan 4, 2012 at 1:44 AM, Wolfgang Denk wd@denx.de wrote:
Dear Graeme,
In message 4F02DA64.60502@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
Won't this lead to lots of code duplication across all boards, archs. So, tomorrow someone else will send a patch removing duplicate and merging it to a common place.
Why don't start it in 1st place.
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 ;)
So, every board, even under same arch, needs to define its own *complete-set* of INIT_CALL api's. I am dreaming about a lot of MB getting added to u-boot src.
Just a thought. Why don't split it to ARCH_INIT, BOARD_INIT,.
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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Regards, Gururaja