Update #2751.
---
 .../bspsupport/ppc_exc_async_normal.S              | 78 ++++++++++++++++------
 c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S  |  8 ++-
 cpukit/score/cpu/powerpc/cpu.c                     |  1 +
 cpukit/score/cpu/powerpc/rtems/score/cpu.h         |  6 +-
 4 files changed, 71 insertions(+), 22 deletions(-)

diff --git 
a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S 
b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S
index c6cbdce..4c9d8aa 100644
--- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S
+++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2011, 2016 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -283,10 +283,12 @@ ppc_exc_wrap_async_normal:
        bl      bsp_interrupt_dispatch
 #endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */
 
-       /* Load ISR nest level and thread dispatch disable level */
+       /* Load some per-CPU variables */
        GET_SELF_CPU_CONTROL    SELF_CPU_REGISTER
+       lbz     SCRATCH_0_REGISTER, PER_CPU_DISPATCH_NEEDED(SELF_CPU_REGISTER)
+       lwz     SCRATCH_1_REGISTER, 
PER_CPU_ISR_DISPATCH_DISABLE(SELF_CPU_REGISTER)
+       lwz     SCRATCH_2_REGISTER, 
PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL(SELF_CPU_REGISTER)
        lwz     ISR_NEST_REGISTER, PER_CPU_ISR_NEST_LEVEL(SELF_CPU_REGISTER)
-       lwz     DISPATCH_LEVEL_REGISTER, 
PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL(SELF_CPU_REGISTER)
 
        /*
         * Switch back to original stack (FRAME_REGISTER == r1 if we are still
@@ -295,36 +297,74 @@ ppc_exc_wrap_async_normal:
        mr      r1, FRAME_REGISTER
        lwz     FRAME_REGISTER, FRAME_OFFSET(r1)
 
-       /* Decrement ISR nest level and thread dispatch disable level */
+       /* Decrement levels and determine thread dispatch state */
+       xori    SCRATCH_0_REGISTER, SCRATCH_0_REGISTER, 1
+       or      SCRATCH_0_REGISTER, SCRATCH_0_REGISTER, SCRATCH_1_REGISTER
+       subi    DISPATCH_LEVEL_REGISTER, SCRATCH_2_REGISTER, 1
+       or.     SCRATCH_0_REGISTER, SCRATCH_0_REGISTER, DISPATCH_LEVEL_REGISTER
 #ifdef RTEMS_PROFILING
+       cmpwi   cr2, SCRATCH_0_REGISTER, 0
        subic.  ISR_NEST_REGISTER, ISR_NEST_REGISTER, 1
-       subi    DISPATCH_LEVEL_REGISTER, DISPATCH_LEVEL_REGISTER, 1
-       cmpwi   cr2, DISPATCH_LEVEL_REGISTER, 0
-#else /* RTEMS_PROFILING */
+#else
        subi    ISR_NEST_REGISTER, ISR_NEST_REGISTER, 1
-       subic.  DISPATCH_LEVEL_REGISTER, DISPATCH_LEVEL_REGISTER, 1
-#endif /* RTEMS_PROFILING */
-       stw     ISR_NEST_REGISTER, PER_CPU_ISR_NEST_LEVEL(SELF_CPU_REGISTER)
+#endif
+
+       /* Store thread dispatch disable and ISR nest levels */
        stw     DISPATCH_LEVEL_REGISTER, 
PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL(SELF_CPU_REGISTER)
+       stw     ISR_NEST_REGISTER, PER_CPU_ISR_NEST_LEVEL(SELF_CPU_REGISTER)
 
 #ifdef RTEMS_PROFILING
        /* Store profiling data if necessary */
-       bne     profiling_done
+       bne     .Lprofiling_done
        mr      r3, SELF_CPU_REGISTER
        mr      r4, ENTRY_INSTANT_REGISTER
        GET_TIME_BASE   r5
        bl      _Profiling_Outer_most_interrupt_entry_and_exit
-profiling_done:
+       GET_SELF_CPU_CONTROL    SELF_CPU_REGISTER
+.Lprofiling_done:
 #endif /* RTEMS_PROFILING */
 
-       /* Call thread dispatcher if necessary */
+       /*
+        * Check thread dispatch necessary, ISR dispatch disable and thread
+        * dispatch disable level.
+        */
 #ifdef RTEMS_PROFILING
-       bne     cr2, thread_dispatching_done
-#else /* RTEMS_PROFILING */
-       bne     thread_dispatching_done
-#endif /* RTEMS_PROFILING */
-       bl      _Thread_Dispatch
-thread_dispatching_done:
+       bne     cr2, .Lthread_dispatch_done
+#else
+       bne     .Lthread_dispatch_done
+#endif
+
+       /* Thread dispatch */
+.Ldo_thread_dispatch:
+
+       /* Set ISR dispatch disable and thread dispatch disable level to one */
+       li      SCRATCH_0_REGISTER, 1
+       stw     SCRATCH_0_REGISTER, 
PER_CPU_ISR_DISPATCH_DISABLE(SELF_CPU_REGISTER)
+       stw     SCRATCH_0_REGISTER, 
PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL(SELF_CPU_REGISTER)
+
+       /* Call _Thread_Do_dispatch(), this function will enable interrupts */
+       mr      r3, SELF_CPU_REGISTER
+       mfmsr   r4
+       ori     r4, r4, MSR_EE
+       bl      _Thread_Do_dispatch
+
+       /* Disable interrupts */
+       wrteei  0
+
+#ifdef RTEMS_SMP
+       GET_SELF_CPU_CONTROL    SELF_CPU_REGISTER
+#endif
+
+       /* Check if we have to do the thread dispatch again */
+       lbz     SCRATCH_0_REGISTER, PER_CPU_DISPATCH_NEEDED(SELF_CPU_REGISTER)
+       cmpwi   SCRATCH_0_REGISTER, 0
+       bne     .Ldo_thread_dispatch
+
+       /* We are done with thread dispatching */
+       li      SCRATCH_0_REGISTER, 0
+       stw     SCRATCH_0_REGISTER, 
PER_CPU_ISR_DISPATCH_DISABLE(SELF_CPU_REGISTER)
+
+.Lthread_dispatch_done:
 
 #ifdef PPC_MULTILIB_ALTIVEC
        /* Restore volatile AltiVec context */
diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S 
b/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S
index e5b4fcd..a1ec64b 100644
--- a/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S
+++ b/c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S
@@ -265,9 +265,11 @@ PROC (_CPU_Context_switch):
 
        /* Save context to r3 */
 
+       GET_SELF_CPU_CONTROL    r12
        mfmsr   r6
        mflr    r7
        mfcr    r8
+       lwz     r11, PER_CPU_ISR_DISPATCH_DISABLE(r12)
 
        /*
         * We have to clear the reservation of the executing thread.  See also
@@ -335,6 +337,7 @@ PROC (_CPU_Context_switch):
        PPC_GPR_STORE   r31, PPC_CONTEXT_OFFSET_GPR31(r3)
 
        stw     r2, PPC_CONTEXT_OFFSET_GPR2(r3)
+       stw     r11, PPC_CONTEXT_OFFSET_ISR_DISPATCH_DISABLE(r3)
 
 #ifdef PPC_MULTILIB_ALTIVEC
        li      r9, PPC_CONTEXT_OFFSET_V20
@@ -409,7 +412,6 @@ PROC (_CPU_Context_switch):
         */
        msync
 
-       GET_SELF_CPU_CONTROL    r12
        addi    r1, r12, PER_CPU_INTERRUPT_FRAME_AREA + CPU_INTERRUPT_FRAME_SIZE
        li      r6, 0
        stw     r6, PPC_CONTEXT_OFFSET_IS_EXECUTING(r3)
@@ -471,6 +473,7 @@ restore_context:
        PPC_GPR_LOAD    r31, PPC_CONTEXT_OFFSET_GPR31(r5)
 
        lwz     r2, PPC_CONTEXT_OFFSET_GPR2(r5)
+       lwz     r11, PPC_CONTEXT_OFFSET_ISR_DISPATCH_DISABLE(r5)
 
 #ifdef PPC_MULTILIB_ALTIVEC
        li      r9, PPC_CONTEXT_OFFSET_V20
@@ -525,6 +528,7 @@ restore_context:
        mtcr    r8
        mtlr    r7
        mtmsr   r6
+       stw     r11, PER_CPU_ISR_DISPATCH_DISABLE(r12)
 
 #ifdef BSP_USE_SYNC_IN_CONTEXT_SWITCH
        isync
@@ -537,6 +541,8 @@ PROC (_CPU_Context_restore):
        /* Align to a cache line */
        clrrwi  r5, r3, PPC_DEFAULT_CACHE_LINE_POWER
 
+       GET_SELF_CPU_CONTROL    r12
+
 #if defined(__ALTIVEC__) && !defined(PPC_MULTILIB_ALTIVEC)
        li      r3, 0
 #endif
diff --git a/cpukit/score/cpu/powerpc/cpu.c b/cpukit/score/cpu/powerpc/cpu.c
index fafc9a6..9d653f7 100644
--- a/cpukit/score/cpu/powerpc/cpu.c
+++ b/cpukit/score/cpu/powerpc/cpu.c
@@ -53,6 +53,7 @@ PPC_ASSERT_OFFSET(gpr29, GPR29);
 PPC_ASSERT_OFFSET(gpr30, GPR30);
 PPC_ASSERT_OFFSET(gpr31, GPR31);
 PPC_ASSERT_OFFSET(gpr2, GPR2);
+PPC_ASSERT_OFFSET(isr_dispatch_disable, ISR_DISPATCH_DISABLE);
 
 #ifdef RTEMS_SMP
   PPC_ASSERT_OFFSET(is_executing, IS_EXECUTING);
diff --git a/cpukit/score/cpu/powerpc/rtems/score/cpu.h 
b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
index dc42d99..0c8abae 100644
--- a/cpukit/score/cpu/powerpc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
@@ -25,7 +25,7 @@
  *
  *  Copyright (c) 2001 Surrey Satellite Technology Limited (SSTL).
  *
- *  Copyright (c) 2010-2013 embedded brains GmbH.
+ *  Copyright (c) 2010, 2016 embedded brains GmbH.
  *
  *  The license and distribution terms for this file may be
  *  found in the file LICENSE in this distribution or at
@@ -236,8 +236,8 @@ typedef struct {
   PPC_GPR_TYPE gpr30;
   PPC_GPR_TYPE gpr31;
   uint32_t gpr2;
+  uint32_t isr_dispatch_disable;
   #if defined(PPC_MULTILIB_ALTIVEC)
-    uint32_t reserved_for_alignment;
     uint8_t v20[16];
     uint8_t v21[16];
     uint8_t v22[16];
@@ -361,6 +361,8 @@ static inline ppc_context *ppc_get_context( const 
Context_Control *context )
 #define PPC_CONTEXT_OFFSET_GPR30 PPC_CONTEXT_GPR_OFFSET( 30 )
 #define PPC_CONTEXT_OFFSET_GPR31 PPC_CONTEXT_GPR_OFFSET( 31 )
 #define PPC_CONTEXT_OFFSET_GPR2 PPC_CONTEXT_GPR_OFFSET( 32 )
+#define PPC_CONTEXT_OFFSET_ISR_DISPATCH_DISABLE \
+  ( PPC_CONTEXT_GPR_OFFSET( 32 ) + 4 )
 
 #ifdef PPC_MULTILIB_ALTIVEC
   #define PPC_CONTEXT_OFFSET_V( v ) \
-- 
1.8.4.5

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to