[U-Boot] [PATCH 01/21] Define new system_restart() and emergency_restart()
Graeme Russ
graeme.russ at gmail.com
Tue Mar 22 13:05:46 CET 2011
On 21/03/11 23:00, Wolfgang Denk wrote:
> Dear Graeme Russ,
>
> In message <4D8739F6.5040805 at gmail.com> you wrote:
>>
>> I kind of like the idea of different reset sources (CPU exception, hardware
>> failure, user initiated) but agree copying the linux architecture is over
>> the top.
>
> What's the difference as far as do_reset() is concenred? It shall
> just (hard) reset the system, nothing else.
>
>> Is there any reason reset() could not take a 'reason' parameter? It could
>> be a bit-mask with CPU, SOC and arch reserved bits (unhandled exception,
>> user initiated, panic etc) and board specific bits
>
> What for? To perform the intended purpose, no parameter is needed.
>
>> Board or arch specific code could handle different reasons however they
>> please (like logging it in NVRAM prior to restart, gracefully shutting down
>> multiple CPU's, clearing DMA buffers etc)
>
> That would be a layer higher than do_reset() (for example, in
> panic()).
Hmmm, but panic() is defined in lib/vsprintf.c with no possibility for it
to be overridden in any arch or board specific way
>
>> All 'hang', 'panic', 'reset' etc code can be simplified into a single code
>> path (although calling 'reset' to 'hang' is a bit odd)
>
> hang() and reset() are intentionally very different things. A call to
> hang() is supposed to hang (surprise, surprise!) infinitely. It must
> not cause a reset.
As I said, calling reset() to hang is odd :)
>
> panic() is a higher software layer. It probably results in calling
> reset() in the end.
>
Unless CONFIG_PANIC_HANG is defined...
Looking into the code
panic():
- ~130 call sites
- Implemented in lib/vsprintf.c
- Calls do_reset() if CONFIG_PANIC_HANG is not defined
- Calls hang() if CONFIG_PANIC_HANG is defined
hang():
- ~180 call sites using hang() and hang ()
- Implemented in arch\lib\board.c
- ARM, i386, m68k, microblaze, mips, prints "### ERROR ### Please RESET
the board ###\n" and loops
- avr32 prints nothing and loops
- Blackfin can set status LEDs based on #define, prints "### ERROR ###
Please RESET the board ###\n" and triggers a breakpoint if a JTAG debugger
is connected
- nios2 disables interrupts then does the same as ARM et all
- powerpc is similar to ARM et al but also calls show_boot_progress(-30)
- sh - same as ARM et al but prints "Board ERROR\n"
- sparc - if CONFIG_SHOW_BOOT_PROGRESS defined, same as powerpc, else
same as ARM et al
So hang() could easily be weakly implemented in common\ which would allow
arch and board specific overrides
do_reset():
- ~70 call sites
- 39 implemetations
- Implemented all over the place (arch/cpu/, arch/lib, board/)
- Only ARM is in arch/lib which could likely be moved to arch/cpu
- Is U_BOOT_CMD
- m68k has a number of very similar/identical implementations
- Is not weak - Cannot be overridden at the board level
- Ouch, PPC is real ugly:
#if !defined(CONFIG_PCIPPC2) && \
!defined(CONFIG_BAB7xx) && \
!defined(CONFIG_ELPPC) && \
!defined(CONFIG_PPMC7XX)
/* no generic way to do board reset. simply call soft_reset. */
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
...
Boards can thus provide their own do_reset()
- Wow, m68k/cpu/mcf52x2/cpu.c is even uglier - 7 definitions selectable
by #ifdef's
- Because do_reset() is U_BOOT_CMD, practically every call is:
do_reset (NULL, 0, 0, NULL) - do_bootm() does pass it's args onto
do_reset()
- No implementation of do_reset() uses any args anyway
reset():
- does not exist (as far as I can tell)
So, maybe we could replace do_reset() with a weak reset() function defined
in arch/cpu which can be overridden at the board level. All existing calls
to do_reset() can be converted to simply reset()
The U_BOOT_CMD do_reset() would simply call reset()
Could many of the current calls to do_reset() be replaced with calls to
panic()?
I still like the idea of passing a 'reason' to reset() / panic() - Could we
change panic() to:
void panic(u32 reason, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
putc('\n');
va_end(args);
if (reason |= PANIC_FLAG_HANG)
hang(reason);
else
reset(reason);
}
Anywhere in the code that needed to hang has a choice - hang(reason) or
panic(reason | PANIC_FLAG_HANG)
Default implementations of hang() and reset() would just ignore reason.
Board specific code can use reason to do one last boot_progress(), set LED
states etc.
Regards,
Graeme
More information about the U-Boot
mailing list