Powerpc IRQ handling breaks strict EABI compliance

Till Straumann strauman at SLAC.Stanford.EDU
Wed Feb 12 20:26:30 UTC 2003


gregory.menke at gsfc.nasa.gov wrote:
> till writes:
>  > Joel Sherrill wrote:
>  > 
>  > >
>  > >Till Straumann wrote:
>  > >
>  > >>Joel Sherrill wrote:
>  > >>
>  > >>>Sergei Organov wrote:
>  > >>>
>  > >>>>Till Straumann <strauman at SLAC.Stanford.EDU> writes:
>  > >>>>
>  > >>>>>OK, I fixed the motorola/shared BSP to not clobber R2/R13 anymore.
>  > >>>>>However, the question remains:
>  > >>>>>
>  > >>>>> - who is responsible for the setup (calling __eabi()) ?
>  > >>>>>   RTEMS or application code?
>  > >>>>>
>  > >>>>It's main() that when compiled with corresponding gcc switches automatically
>  > >>>>invokes __eabi(). It basically only setups R2/R13. BTW, R13 is being used even
>  > >>>>without EABI -- R13 usage is part of SYSV ABI which EABI is derived from.
>  > >>>>
>  > >>>>This brings another interesting problem. In older days of RTEMS the 'main' was
>  > >>>>part of RTEMS, not the part of application code, so it was invoked very early
>  > >>>>and thus all RTEMS/BSP initialization went after __eabi() has been called.
>  > >>>>AFAIK, now situation is different and __eabi() will be invoked too late. It
>  > >>>>means that RTEMS startup code should invoke __eabi() (or setup R13/R2 itself)
>  > >>>>for things to work correctly as C startup/initialization code compiled for
>  > >>>>SYSV ABI/EABI will already rely on correct values in R2/R13.
>  > >>>>
>  > >>>
>  > >>>RTEMS now ensures that the first thread to execute invokes the
>  > >>>appropriate
>  > >>>routine for that gcc target to run global constructors.  The
>  > >>>powerpc-rtems
>  > >>>gcc target is noted as being an init/fini target so it will call
>  > >>>_init().
>  > >>>
>  > >>>
>  > >>OK, I saw that bsp_specs have been updated to include crtbegin/crtend.
>  > >>However, how do you prevent from initialization happening twice if
>  > >>the user uses 'main'?
>  > >>
>  > >
>  > >My memory is that the __init functions have a boolean variable that
>  > >say they have been executed already.
>  > >
>  > 
>  > I disassembled some code and it doesn't look like there is such a flag. 
>  > __eabi() implements
>  > such a guard, however and so does gcc's 'main' header (on architectures 
>  > who don't have
>  > ..init/.fini sections) before calling __init(). (I still could be wrong...)
>  > 
> 
> The interlock can be seen in _Thread_Handler at about line 111,
> score/cpu/threadhandler.c, rtems-ss-20030128
> 
> As implemented, the init task calls the constructors just before
> jumping to userspace.  Once init has called _init_fini, the flag skips
> future invocations for all tasks created later on.

Yes, but on PPC this behavior is still wrong (the _Thread_Handler should
invoke __eabi(), not __init9) on PPC-eabi):

a) __eabi() does other initialization before calling __init()
b) if the user (e.g. by means of providing a 'main' [who
    implicitely calls __eabi()]) later calls __eabi(), __init()
    will still be executed twice, because __init() has no guarding
    flag and __eabi() doesn't care about the one private to the
    _Thread_Handler

-- Till

> 
> The interlock logic seems a little tortured, but I imagine there is or
> was a reason for it...
> 
> __USE_MAIN__ can be made to work, init_fini seems the more current
> approach.
> 
> Gregm
> 






More information about the users mailing list