summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h
diff options
context:
space:
mode:
authorTill Straumann <strauman@slac.stanford.edu>2008-07-10 21:31:06 +0000
committerTill Straumann <strauman@slac.stanford.edu>2008-07-10 21:31:06 +0000
commit8bac4851a68eb074fbdaa3b9be634b3bc4a7ba38 (patch)
tree08f7bcf7e7cc06884ad6d832b22df897b9db8d08 /c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h
parent2008-07-10 Till Straumann <strauman@slac.stanford.edu> (diff)
downloadrtems-8bac4851a68eb074fbdaa3b9be634b3bc4a7ba38.tar.bz2
2008-07-10 Till Straumann <strauman@slac.stanford.edu>
* new-exceptions/bspsupport/ppc_exc_asm_macros.S, new-exceptions/bspsupport/ppc_exc_bspsupp.h, new-exceptions/bspsupport/ppc_exc_hdl.c, new-exceptions/bspsupport/vectors_init.c: fixed and enabled stack-switching algorithm which figures out if we already run on the ISR stack rather than relying on the _ISR_Nest_level. Added 'ppc_exc_crit_always_enabled' variable which defines the semantics of critical interrupts. Added a test to TEST_LOCK_crit so that calling ppc_exc_wrapup() (and possibly the dispatcher) is always skipped if the BSP/user wants to leave critical interrupts always enabled (at the expense of having no OS support). changed TEST_LOCK_mchk so that asynchronous machine-check handlers never call ppc_exc_wrapup() (and the dispatcher). We don't want to disable MSR_ME ever (to avoid checkstops) and hence asynchronous MEs must not use OS services anyways. added and commented new variables 'ppc_exc_intr_stack_size' 'ppc_exc_crit_always_enabled'.
Diffstat (limited to 'c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h')
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h48
1 files changed, 41 insertions, 7 deletions
diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h
index e176735f77..4f66d91e54 100644
--- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h
+++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h
@@ -84,18 +84,21 @@
* priority exceptions (HPE) (by disabling
* them while the stack is switched).
*/
-#if 0
+#if 1
.macro SWITCH_STACK RA RB FLVR
mfspr \RB, SPRG1
cmplw cr0, r1, \RB
bgt do_r1_reload_\FLVR
lwz \RA, ppc_exc_intr_stack_size@sdarel(r13)
- subf \RB, \RB, \RA
+ subf \RB, \RA, \RB
cmplw cr0, r1, \RB
bge no_r1_reload_\FLVR
do_r1_reload_\FLVR:
mfspr r1, SPRG1
no_r1_reload_\FLVR:
+ lwz \RA, _ISR_Nest_level@sdarel(r13)
+ addi \RA, \RA, 1
+ stw \RA, _ISR_Nest_level@sdarel(r13)
.endm
#else
.macro SWITCH_STACK RA RB FLVR
@@ -269,7 +272,7 @@ ppc_exc_min_prolog_sync_\_NAME:
* ON EXIT: cr4 is set (indicates no lower-priority locks are engaged)
*
*/
- .macro TEST_LOCK_std _SRR0
+ .macro TEST_LOCK_std _SRR0 _FLVR
/* 'std' is lowest level, i.e., can not be locked -> EQ(cr4) = 1 */
creqv EQ(cr4), EQ(cr4), EQ(cr4)
.endm
@@ -285,10 +288,16 @@ ppc_exc_min_prolog_sync_\_NAME:
* critical-exception wrapper has to check 'std' lock:
*
* Return cr4 = ( ppc_std_lock == 0
- * && * _SRR0 != <write std lock instruction> )
+ * && * _SRR0 != <write std lock instruction>
+ * && ppc_exc_crit_always_enabled == 0 )
*
*/
- .macro TEST_LOCK_crit _SRR0
+ .macro TEST_LOCK_crit _SRR0 _FLVR
+ /* Are critical exceptions always enabled ? */
+ lwz r4, ppc_exc_crit_always_enabled@sdarel(r13)
+ cmpwi cr4, r4, 0
+ bne cr4, TEST_LOCK_crit_done_\_FLVR
+
/* STD interrupt could have been interrupted before
* executing the 1st instruction which sets the lock;
* check this case by looking at the opcode present
@@ -311,8 +320,10 @@ ppc_exc_min_prolog_sync_\_NAME:
* && ppc_exc_lock_std == 0 )
*/
crandc EQ(cr4), EQ(cr0), EQ(cr4)
+TEST_LOCK_crit_done_\_FLVR:
.endm
+#if 0
/*
**********************************************************************
* MACRO: TEST_LOCK_mchk
@@ -328,7 +339,7 @@ ppc_exc_min_prolog_sync_\_NAME:
* && ppc_std_lock == 0
* && ppc_crit_lock == 0 )
*/
- .macro TEST_LOCK_mchk _SRR0
+ .macro TEST_LOCK_mchk _SRR0 _FLVR
TEST_1ST_OPCODE_mchk _REG=r4 _SRR0=\_SRR0
/* cr4 set if 1st opcode matches writing either lock */
@@ -343,6 +354,29 @@ ppc_exc_min_prolog_sync_\_NAME:
*/
crandc EQ(cr4), EQ(cr0), EQ(cr4)
.endm
+#else
+/*
+ **********************************************************************
+ * MACRO: TEST_LOCK_mchk
+ **********************************************************************
+ *
+ * USES: cr4
+ * ON EXIT: cr4 is cleared.
+ *
+ * We never want to disable machine-check exceptions to avoid
+ * a checkstop. This means that we cannot use enabling/disabling
+ * this type of exception for protection of critical OS data structures.
+ * Therefore, calling OS primitives from a machine-check handler
+ * is ILLEGAL. Since machine-checks can happen anytime it is not
+ * legal to perform a context switch (since the exception could
+ * hit a IRQ protected section of code).
+ * We simply let this test return 0 so that ppc_exc_wrapup is
+ * never called after handling a machine-check.
+ */
+ .macro TEST_LOCK_mchk _SRR0 _FLVR
+ crxor EQ(cr4), EQ(cr4), EQ(cr4)
+ .endm
+#endif
/*
@@ -409,7 +443,7 @@ wrap_no_save_r14_\_FLVR:
stw r5, ppc_exc_lock_\_PRI@sdarel(r13)
/* test lower-priority locks; result in (non-volatile) cr4 */
- TEST_LOCK_\_PRI _SRR0=\_SRR0
+ TEST_LOCK_\_PRI _SRR0=\_SRR0 _FLVR=\_FLVR
/* Peform stack switch if necessary */
SWITCH_STACK RA=r4 RB=r5 FLVR=\_FLVR