forked from Imagelibrary/rtems
2008-07-16 Till Straumann <strauman@slac.stanford.edu>
* new-exceptions/bspsupport/ppc_exc_asm_macros.h: Added a test to TEST_LOCK_crit so that a context switch is always prevented if MSR_CE is not set in the interrupt mask. (Support mode where the user wants to leave MSR_CE always enabled but abstains from calling OS primitives from the exception handler.)
This commit is contained in:
@@ -1,3 +1,12 @@
|
|||||||
|
2008-07-16 Till Straumann <strauman@slac.stanford.edu>
|
||||||
|
|
||||||
|
* new-exceptions/bspsupport/ppc_exc_asm_macros.h: Added
|
||||||
|
a test to TEST_LOCK_crit so that a context switch is
|
||||||
|
always prevented if MSR_CE is not set in the interrupt mask.
|
||||||
|
(Support mode where the user wants to leave MSR_CE always enabled
|
||||||
|
but abstains from calling OS primitives from the exception
|
||||||
|
handler.)
|
||||||
|
|
||||||
2008-07-16 Till Straumann <strauman@slac.stanford.edu>
|
2008-07-16 Till Straumann <strauman@slac.stanford.edu>
|
||||||
|
|
||||||
* shared/include/powerpc-utility.h: Added
|
* shared/include/powerpc-utility.h: Added
|
||||||
|
|||||||
@@ -140,9 +140,9 @@ ppc_exc_min_prolog_sync_\_NAME:
|
|||||||
* MACRO: TEST_1ST_OPCODE_crit
|
* MACRO: TEST_1ST_OPCODE_crit
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
*
|
*
|
||||||
* USES: REG, CR_LOCK
|
* USES: REG, cr0
|
||||||
* ON EXIT: REG available (contains *pc - STW_R1_R13(0)),
|
* ON EXIT: REG available (contains *pc - STW_R1_R13(0)),
|
||||||
* return value in CR_LOCK.
|
* return value in cr0.
|
||||||
*
|
*
|
||||||
* test opcode interrupted by critical (asynchronous) exception; set CR_LOCK if
|
* test opcode interrupted by critical (asynchronous) exception; set CR_LOCK if
|
||||||
*
|
*
|
||||||
@@ -161,7 +161,7 @@ ppc_exc_min_prolog_sync_\_NAME:
|
|||||||
* if what's left compares against the 'ppc_exc_lock_std@sdarel'
|
* if what's left compares against the 'ppc_exc_lock_std@sdarel'
|
||||||
* address offset then we have a match...
|
* address offset then we have a match...
|
||||||
*/
|
*/
|
||||||
cmpli CR_LOCK, \_REG, ppc_exc_lock_std@sdarel
|
cmplwi cr0, \_REG, ppc_exc_lock_std@sdarel
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@@ -190,11 +190,19 @@ ppc_exc_min_prolog_sync_\_NAME:
|
|||||||
*
|
*
|
||||||
* critical-exception wrapper has to check 'std' lock:
|
* critical-exception wrapper has to check 'std' lock:
|
||||||
*
|
*
|
||||||
* Return CR_LOCK = ( ppc_lock_std == 0
|
* Return CR_LOCK = ( (interrupt_mask & MSR_CE) != 0
|
||||||
|
&& ppc_lock_std == 0
|
||||||
* && * SRR0 != <write std lock instruction> )
|
* && * SRR0 != <write std lock instruction> )
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
.macro TEST_LOCK_crit _FLVR
|
.macro TEST_LOCK_crit _FLVR
|
||||||
|
/* If MSR_CE is not in the IRQ mask then we must never allow
|
||||||
|
* thread-dispatching!
|
||||||
|
*/
|
||||||
|
GET_INTERRUPT_MASK mask=SCRATCH_REGISTER_1
|
||||||
|
/* EQ(cr0) = ((interrupt_mask & MSR_CE) == 0) */
|
||||||
|
andis. SCRATCH_REGISTER_1, SCRATCH_REGISTER_1, MSR_CE@h
|
||||||
|
beq TEST_LOCK_crit_done_\_FLVR
|
||||||
|
|
||||||
/* STD interrupt could have been interrupted before executing the 1st
|
/* STD interrupt could have been interrupted before executing the 1st
|
||||||
* instruction which sets the lock; check this case by looking at the
|
* instruction which sets the lock; check this case by looking at the
|
||||||
@@ -202,7 +210,7 @@ ppc_exc_min_prolog_sync_\_NAME:
|
|||||||
*/
|
*/
|
||||||
TEST_1ST_OPCODE_crit _REG=SCRATCH_REGISTER_0
|
TEST_1ST_OPCODE_crit _REG=SCRATCH_REGISTER_0
|
||||||
/*
|
/*
|
||||||
* At this point CR_LOCK is set if
|
* At this point cr0 is set if
|
||||||
*
|
*
|
||||||
* *(PC) == 'stw r1, ppc_exc_lock_std@sdarel(r13)'
|
* *(PC) == 'stw r1, ppc_exc_lock_std@sdarel(r13)'
|
||||||
*
|
*
|
||||||
@@ -210,13 +218,21 @@ ppc_exc_min_prolog_sync_\_NAME:
|
|||||||
|
|
||||||
/* check lock */
|
/* check lock */
|
||||||
lwz SCRATCH_REGISTER_1, ppc_exc_lock_std@sdarel(r13)
|
lwz SCRATCH_REGISTER_1, ppc_exc_lock_std@sdarel(r13)
|
||||||
cmpli cr0, SCRATCH_REGISTER_1, 0
|
cmplwi CR_LOCK, SCRATCH_REGISTER_1, 0
|
||||||
/*
|
|
||||||
|
/* set EQ(CR_LOCK) to result */
|
||||||
|
TEST_LOCK_crit_done_\_FLVR:
|
||||||
|
/* If we end up here because the interrupt mask did not contain
|
||||||
|
* MSR_CE then cr0 is set and therefore the value of CR_LOCK
|
||||||
|
* does not matter since x && !1 == 0:
|
||||||
*
|
*
|
||||||
* CR_LOCK = ( *pc != <write std lock instruction>
|
* if ( (interrupt_mask & MSR_CE) == 0 ) {
|
||||||
* && ppc_exc_lock_std == 0 )
|
* EQ(CR_LOCK) = EQ(CR_LOCK) && ! ((interrupt_mask & MSR_CE) == 0)
|
||||||
|
* } else {
|
||||||
|
* EQ(CR_LOCK) = (ppc_exc_lock_std == 0) && ! (*pc == <write std lock instruction>)
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
crandc EQ(CR_LOCK), EQ(cr0), EQ(CR_LOCK)
|
crandc EQ(CR_LOCK), EQ(CR_LOCK), EQ(cr0)
|
||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user