PowerPC exceptions: various comments

Till Straumann strauman at slac.stanford.edu
Thu Mar 13 19:53:26 UTC 2008


Hi Thomas.

I implemented (and commited) a fix for problem #1 and invite you (and 
others)
to comment. The algorithm is now as follows:

A) first instruction of 'classic' asynchronous exception ('interrupt') 
sets 'lock' variable:

async_vector_address:
    stw r1, ppc_exc_lock_std at sdarel(r13)
    ...

    increment _Thread_Dispatch_disable_level
    ...
    dispatch 'C' - handler

    decrement _Thread_Dispatch_disable_level

B) a critical interrupt handler does the following when decrementing
   the dispatch-disable level (translated into C code); the code
   marked /****/ has been added:

   if ( --_Thread_Dispatch_disable_level == 0 ) {

      if (    ppc_exc_lock_std == 0 /* lower-priority lock variable not 
set */
/*****/   &&  *CSRR0 != opcode_of( 'stw r1, 
ppc_exc_lock_std at sdarel(r13)' ) {
          if ( thread_dispatch_necessary )
             _Thread_Dispatch();
      }
   }

   IMO this should catch the pathological case where a critical
   interrupt happens just after a non-critical one has loaded
   the PC with the 'async_vector_address' but before the 'stw r1, ...'
   instruction had a chance to execute.
   The critical handler finds 'ppc_exc_lock_std' is still zero
   but it now also checks the opcode stored at the interrupted
   PC address (found in the CSRR0 register). If that opcode
   matches 'stw r1, ppc_exc_lock_std at sdarel(r13)' then the critical
   handler 'knows' that a non-critical IRQ is already under way
   and defers thread-dispatching. The opcode in question is
   unique and not present anywhere else in the code; in particular,
   it is impossible for the compiler to generate this very instruction
   from C-code.


Problem #2 is governed by the 'new-exception handling' API. (My 'middleware'
does not try to change that API.) It seems to me that the routines
declared in 'raw_exceptions.h' need a vector table in RAM.

However, all normal prologues defined by the middleware (except for the
603 TGPR prologue) are only 16 bytes hence in principle you could
have a reasonably small table in RAM (but unfortunately, the API forces
you to have a copy attached to the configuration table).


RFC
-- Till



Thomas Doerfler wrote:
> Hello Till,
>
> we are currently adapting RTEMS to a MPC55xx microcontroller with a 
> e200z6 CPU core. We are pleased to see, that you have significantly 
> cleaned up the PPC exception code and you also already have done lots 
> of stuff to support the e500 core, which is very similar to the e200.
>
> All in all I agree, that your modifications simplify the use of the 
> PPC vectoring scheme.
>
> But we have some topics that should be discussed.
>
> 1. Critical Interrupts
> =======================
> My colleague Sebastian has tripped over the synchronization you try to 
> achieve between non-critical and critical interrupts. As far as I 
> understand, you try to detect the situation, that a critical interrupt 
> interrupts the prolog code of a non-critical interrupt. For this 
> purpose, you write the content of r1 to the "lock_bits" flag as the 
> first opcode in the non-critical interrupt prolog.
>
> Unfortunately this will not work reliable. I have discussed the issue 
> with one of my Freescale contact persons, and he told me that entering 
> the non-critical interrupt and executing the first opcode is NOT 
> atomic. So there is still a chance, that
>
> - the CPU has saved PC/MSR into SRR0/1
>
> - the CPU has modified PC/MSR to execute the non-critical interrupt 
> prolog
>
> - A critical interrupt is raised
>
> - the CPU saves PC/MSR into CSRR0/1 and enters the critical interrupt 
> handler
>
> - the critical interrupt handler may issue a thread dispatch when 
> leaving, and therefore delay the previously raised non-critical 
> interrupt.
>
> As far as I can see, we should postulate, that critical interrupts are 
> NOT allowed to dispatch tasks. Do you see hard requirements that stand 
> against this?
>
> 2. Interrupt Prolog Placement in ROM
> ====================================
>
> Our target will have 128KByte(!) of internal RAM. In some 
> applications, this will be the only RAM available, and therefore I am 
> looking for ways to place the exception prologue code in ROM/Flash 
> (that's where the rest of the code is located anyway).
>
> What I have seen in the current code gives me the impression that the 
> prologue code is more or less statically initialized. When the current 
> CPU type has been detected, the corresponding prologue snippets are 
> copied to the proper vector locations and it is not intended that the 
> prologue code is replaced when e.g. a debugger agent is attached. 
> Instead, the agent would connect to the high level handler. Did I get 
> this right?
>
> So my idea would be to alternatively make the macro assembler 
> duplicate the prologues in proper flavour, quite similar to the 
> "xxx_vector_categories" tables in raw_exception.c. Many other changes 
> would be required then (e.g. the relationship between the prologue 
> address and the vector number will become different again), but it is 
> at least worth the effort for the MPC55xx, and maybe it would even 
> make sense for the "big" PPCs, because copying the code to the vector 
> range is not really necessary in all situations.
>
> Before we got further into the details of these plans, I would like to 
> get your opinion on the whole direction. Be assured, that we would NOT 
> add conditional assembly and we would NOT copy/paste/modify relevant 
> code :-)
>
> wkr,
> Thomas.
>
>
>
>





More information about the users mailing list