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