[PATCH 4/5 v2] SPARC: Fatal_halt use source and exit codes

Daniel Hellstrom daniel at gaisler.com
Fri Jul 4 08:49:55 UTC 2014


On 07/03/2014 04:55 PM, Joel Sherrill wrote:
> I am wondering if I don't have a vision for what this
> series of patches is trying to accomplish in whole.
* make exit-code propagate to debugger/hypervisor. I though this would be nice for other architectures as well.
* make SMP fatal exit work
* instead of using BSP specific reset on LEON3, rely on RTEMS and SPARC to stop execution
* fix bad behaviour of SPARC fatal halt, always spinning.

>
> And I am hung up on not wanting BSP references in
> score. So I would like an elegant solution.
I understand that, however some part of me still thinks that halting is very BSP specific. What makes me a bit confused is that there is just one halt approach, there is no difference between reset, 
reboot, halt and power-down. I remember Win95 or Linux, when you type halt it does not reboot or power-down the machine, since you can see the last terminal shutdown message and push the power-down 
button yourself ;)

> How does tweaking the bsp_reset() method not
> address all of this? It is invoked along the _Terminate()
> path already.
>
> As an aside, should the _Internal_errors_What_happened
> structure be filled in earlier in _Terminate? How about
> just after disabling interrupts?
That is one of the problems I faced.
  * bsp_reset() does not have any arguments of what gone wrong
  * _Internal_errors_What_happened is not modified until after bsp_reset()
  * _Internal_errors_What_happened can not be updated before bsp_reset() on SMP since it will be written by all CPUs
  * The exit codes of CPUs are different. If one CPU finds a problem, signals to the others to shut down, their IPI handler will call fatal handler with another exit code. Now the BSP in the fatal 
extions can look at the exit codes to determine which CPU requested the fatal exit and handle them differently. The BSP makes sure that only one CPU ends up in the


>
> On 7/3/2014 2:29 AM, Daniel Hellstrom wrote:
>> PATCHv2: BSP_fatal_halt renamed to _BSP_Fatal_halt
>>
>> The Fatal_halt handler now have two options, either halt
>> as before or enter system error state to return to
>> debugger or simulator. The exit-code is now also
>> propagated to the debugger which is very useful for
>> testing.
>>
>> The CPU_Fatal_halt handler was split up into two, since
>> the only the LEON3 support the CPU power down.
>>
>> The LEON3 halt now uses the power-down instruction to save
>> CPU power. This doesn't stop a potential watch-dog timer
>> from expiring.
>> ---
>>   c/src/lib/libbsp/sparc/erc32/Makefile.am           |    1 +
>>   c/src/lib/libbsp/sparc/erc32/configure.ac          |    5 +++
>>   c/src/lib/libbsp/sparc/leon2/Makefile.am           |    1 +
>>   c/src/lib/libbsp/sparc/leon2/configure.ac          |    5 +++
>>   c/src/lib/libbsp/sparc/leon3/Makefile.am           |    1 +
>>   c/src/lib/libbsp/sparc/leon3/configure.ac          |    5 +++
>>   .../libbsp/sparc/leon3/startup/bsp_fatal_halt.c    |   36 ++++++++++++++++++
>>   .../libbsp/sparc/shared/startup/bsp_fatal_halt.c   |   38 ++++++++++++++++++++
>>   cpukit/score/cpu/sparc/rtems/score/cpu.h           |   12 ++----
>>   9 files changed, 96 insertions(+), 8 deletions(-)
>>   create mode 100644 c/src/lib/libbsp/sparc/leon3/startup/bsp_fatal_halt.c
>>   create mode 100644 c/src/lib/libbsp/sparc/shared/startup/bsp_fatal_halt.c
>>
>> diff --git a/c/src/lib/libbsp/sparc/erc32/Makefile.am b/c/src/lib/libbsp/sparc/erc32/Makefile.am
>> index b9f1c53..00e398b 100644
>> --- a/c/src/lib/libbsp/sparc/erc32/Makefile.am
>> +++ b/c/src/lib/libbsp/sparc/erc32/Makefile.am
>> @@ -46,6 +46,7 @@ libbsp_a_SOURCES += startup/bspidle.c
>>   libbsp_a_SOURCES += startup/bspdelay.c
>>   libbsp_a_SOURCES += ../../sparc/shared/startup/early_malloc.c
>>   libbsp_a_SOURCES += ../../sparc/shared/startup/bsp_fatal_exit.c
>> +libbsp_a_SOURCES += ../../sparc/shared/startup/bsp_fatal_halt.c
>>   # ISR Handler
>>   libbsp_a_SOURCES += ../../sparc/shared/cpu.c
>>   libbsp_a_SOURCES += ../../sparc/shared/irq_asm.S
>> diff --git a/c/src/lib/libbsp/sparc/erc32/configure.ac b/c/src/lib/libbsp/sparc/erc32/configure.ac
>> index 4cbfb7e..bb5174a 100644
>> --- a/c/src/lib/libbsp/sparc/erc32/configure.ac
>> +++ b/c/src/lib/libbsp/sparc/erc32/configure.ac
>> @@ -43,6 +43,11 @@ RTEMS_BSPOPTS_HELP([ENABLE_SIS_QUIRKS],
>>    BSP will be enabled.  In particular, SIS requires special
>>    initialization not used on real ERC32 hardware.])
>>   
>> +RTEMS_BSPOPTS_SET([BSP_HALT_AT_FATAL_EXIT],[*],[])
>> +RTEMS_BSPOPTS_HELP([BSP_HALT_AT_FATAL_EXIT],
>> +[If defined, CPU is spinning on fatal exit. Otherwise generate system
>> + error which will hand over to debugger, simulator, etc.])
>> +
> Why would anyone want the CPU to go into a spin?
This was the previous behaviour of SPARC CPU_fatal_halt(), the only reason for that as I could come up with would be that the watchdog timer expires and causes a hard reset. I wanted to preserve the 
current behaviour, I change quite much in the patch series anyway.

>>   RTEMS_BSP_CLEANUP_OPTIONS(0,1,1)
>>   
>>   # Explicitly list all Makefiles here
>> diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am
>> index 3f8edf4..ac6f327 100644
>> --- a/c/src/lib/libbsp/sparc/leon2/Makefile.am
>> +++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am
>> @@ -61,6 +61,7 @@ libbsp_a_SOURCES += ../../shared/bspinit.c
>>   libbsp_a_SOURCES += startup/bspdelay.c
>>   libbsp_a_SOURCES += ../../sparc/shared/startup/early_malloc.c
>>   libbsp_a_SOURCES += ../../sparc/shared/startup/bsp_fatal_exit.c
>> +libbsp_a_SOURCES += ../../sparc/shared/startup/bsp_fatal_halt.c
>>   
>>   # ISR Handler
>>   libbsp_a_SOURCES += ../../sparc/shared/cpu.c
>> diff --git a/c/src/lib/libbsp/sparc/leon2/configure.ac b/c/src/lib/libbsp/sparc/leon2/configure.ac
>> index 610a049..1975a10 100644
>> --- a/c/src/lib/libbsp/sparc/leon2/configure.ac
>> +++ b/c/src/lib/libbsp/sparc/leon2/configure.ac
>> @@ -36,6 +36,11 @@ RTEMS_BSPOPTS_HELP([SIMSPARC_FAST_IDLE],
>>    time spent in the idle task is minimized.  This significantly reduces
>>    the wall time required to execute the RTEMS test suites.])
>>   
>> +RTEMS_BSPOPTS_SET([BSP_HALT_AT_FATAL_EXIT],[*],[])
>> +RTEMS_BSPOPTS_HELP([BSP_HALT_AT_FATAL_EXIT],
>> +[If defined, CPU is spinning on fatal exit. Otherwise generate system
>> + error which will hand over to debugger, simulator, etc.])
>> +
>>   RTEMS_BSP_CLEANUP_OPTIONS(0, 1, 1)
>>   
>>   # Explicitly list all Makefiles here
>> diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am
>> index 54c9f22..d1f07a7 100644
>> --- a/c/src/lib/libbsp/sparc/leon3/Makefile.am
>> +++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am
>> @@ -42,6 +42,7 @@ libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
>>   libbsp_a_SOURCES += startup/bspreset.c
>>   libbsp_a_SOURCES += startup/cpucounter.c
>>   libbsp_a_SOURCES += ../../sparc/shared/startup/bsp_fatal_exit.c
>> +libbsp_a_SOURCES += startup/bsp_fatal_halt.c
>>   
>>   # ISR Handler
>>   libbsp_a_SOURCES += ../../sparc/shared/cpu.c
>> diff --git a/c/src/lib/libbsp/sparc/leon3/configure.ac b/c/src/lib/libbsp/sparc/leon3/configure.ac
>> index 3fe1e48..206a662 100644
>> --- a/c/src/lib/libbsp/sparc/leon3/configure.ac
>> +++ b/c/src/lib/libbsp/sparc/leon3/configure.ac
>> @@ -38,6 +38,11 @@ RTEMS_BSPOPTS_HELP([BSP_LEON3_SMP],
>>   [Always defined when on a LEON3 to enable the LEON3 support for
>>    determining the CPU core number in an SMP configuration.])
>>   
>> +RTEMS_BSPOPTS_SET([BSP_HALT_AT_FATAL_EXIT],[*],[])
>> +RTEMS_BSPOPTS_HELP([BSP_HALT_AT_FATAL_EXIT],
>> +[If defined, CPU is powered down on fatal exit. Otherwise generate system
>> + error which will hand over to debugger, simulator, etc.])
>> +
>>   RTEMS_BSP_CLEANUP_OPTIONS(0, 1, 1)
>>   RTEMS_BSP_LINKCMDS
>>   
>> diff --git a/c/src/lib/libbsp/sparc/leon3/startup/bsp_fatal_halt.c b/c/src/lib/libbsp/sparc/leon3/startup/bsp_fatal_halt.c
>> new file mode 100644
>> index 0000000..4350faf
>> --- /dev/null
>> +++ b/c/src/lib/libbsp/sparc/leon3/startup/bsp_fatal_halt.c
>> @@ -0,0 +1,36 @@
>> +/**
>> + * @file
>> + * @ingroup sparc_leon3
>> + * @brief LEON3 BSP Fatal_halt handler.
>> + *
>> + *  COPYRIGHT (c) 2014.
>> + *  Aeroflex Gaisler AB.
>> + *
>> + *  The license and distribution terms for this file may be
>> + *  found in the file LICENSE in this distribution or at
>> + *  http://www.rtems.org/license/LICENSE.
>> + */
>> +
>> +#include <leon.h>
>> +#include <rtems/score/sparc.h>
>> +
>> +#ifdef BSP_HALT_AT_FATAL_EXIT
>> +
>> +/* Power down LEON CPU on fatal error exit */
>> +void _BSP_Fatal_halt(uint32_t source, uint32_t error)
>> +{
>> +  sparc_disable_interrupts();
>> +  leon3_power_down_loop();
>> +}
>> +
>> +#else
>> +
>> +/* return to debugger, simulator, hypervisor or similar by exiting
>> + * with an error code. g1=1, g2=FATAL_SOURCE, G3=error-code.
>> + */
>> +void _BSP_Fatal_halt(uint32_t source, uint32_t error)
>> +{
>> +  sparc_syscall_exit(source, error);
>> +}
>> +
>> +#endif
>> diff --git a/c/src/lib/libbsp/sparc/shared/startup/bsp_fatal_halt.c b/c/src/lib/libbsp/sparc/shared/startup/bsp_fatal_halt.c
>> new file mode 100644
>> index 0000000..349db20
>> --- /dev/null
>> +++ b/c/src/lib/libbsp/sparc/shared/startup/bsp_fatal_halt.c
>> @@ -0,0 +1,38 @@
>> +/**
>> + * @file
>> + * @ingroup sparc_bsp
>> + * @brief ERC32/LEON2 BSP Fatal_halt handler.
>> + *
>> + *  COPYRIGHT (c) 2014.
>> + *  Aeroflex Gaisler AB.
>> + *
>> + *  The license and distribution terms for this file may be
>> + *  found in the file LICENSE in this distribution or at
>> + *  http://www.rtems.org/license/LICENSE.
>> + */
>> +
>> +#include <rtems/score/sparc.h>
>> +
>> +#ifdef BSP_HALT_AT_FATAL_EXIT
>> +
>> +/* Spin CPU on fatal error exit */
>> +void _BSP_Fatal_halt(uint32_t source, uint32_t error)
>> +{
>> +  uint32_t level = sparc_disable_interrupts();
>> +
>> +  __asm__ volatile ( "mov  %0, %%g1 " : "=r" (level) : "0" (level) );
>> +
>> +  while (1) ; /* loop forever */
>> +}
>> +
>> +#else
>> +
>> +/* return to debugger, simulator, hypervisor or similar by exiting
>> + * with an error code. g1=1, g2=FATAL_SOURCE, G3=error-code.
>> + */
>> +void _BSP_Fatal_halt(uint32_t source, uint32_t error)
>> +{
>> +  sparc_syscall_exit(source, error);
>> +}
>> +
>> +#endif
>> diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h
>> index 58c843a..0bb1bf5 100644
>> --- a/cpukit/score/cpu/sparc/rtems/score/cpu.h
>> +++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h
>> @@ -1075,19 +1075,15 @@ void _CPU_Context_Initialize(
>>   
>>   /* Fatal Error manager macros */
>>   
>> +extern void _BSP_Fatal_halt(uint32_t source, uint32_t error)
>> +  RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
>> +
> I am really having trouble invoking a BSP specific routine
> out of score/cpu. Can't you do this in the bsp_reset()
> method?
No, the debugger/hypervisor typically reads registers as exit-codes not memory so it has to be done last. I'm not sure how it works on other architectures, can we always rely on memory for getting 
exit-codes? If we would read the exit codes from memory from loader/debugger/hypervisor it would require ELF capability or that the BSP defines which address _Internal_errors_What_happened is to be 
located at I guess

> If not, the leon3 is now a multilib so you can just have a
> leon3 specific version of this macro.
I'm not sure I follow here.


Please see the code below where the SPARC implements an endless spin after disabling interrupt. I substituted that with a power-down instead, as the commit message suggests it does not stop a watchdog 
to expire and reset.
>>   /**
>>    * This routine copies _error into a known place -- typically a stack
>>    * location or a register, optionally disables interrupts, and
>>    * halts/stops the CPU.
>>    */
>> -#define _CPU_Fatal_halt( _source, _error ) \
>> -  do { \
>> -    uint32_t   level; \
>> -    \
>> -    level = sparc_disable_interrupts(); \
>> -    __asm__ volatile ( "mov  %0, %%g1 " : "=r" (level) : "0" (level) ); \
>> -    while (1); /* loop forever */ \
>> -  } while (0)
>> +#define _CPU_Fatal_halt( _source, _error ) _BSP_Fatal_halt( _source, _error )
>>   
>>   /* end of Fatal Error manager macros */
>>   



More information about the devel mailing list