Changeset a32835a3 in rtems


Ignore:
Timestamp:
May 10, 2007, 6:40:49 PM (13 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
45d406f8
Parents:
93c2b41
Message:

2007-05-10 Joel Sherrill <joel.sherrill@…>

PR 1237/rtems

  • cpu.c, cpu_asm.S, rtems/score/cpu.h: Add logic to prevent stack creep when interrupts occur at a sufficient rate that the interrupted thread never gets to clean its stack. This patch ensures that an interrupted thread will not nest ISR dispatches on its stack.
Location:
cpukit/score/cpu/sparc
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • cpukit/score/cpu/sparc/ChangeLog

    r93c2b41 ra32835a3  
     12007-05-10      Joel Sherrill <joel.sherrill@OARcorp.com>
     2
     3        PR 1237/rtems
     4        * cpu.c, cpu_asm.S, rtems/score/cpu.h: Add logic to prevent stack creep
     5        when interrupts occur at a sufficient rate that the interrupted
     6        thread never gets to clean its stack. This patch ensures that an
     7        interrupted thread will not nest ISR dispatches on its stack.
     8
    192007-05-09      Ralf Corsépius <ralf.corsepius@rtems.org>
    210
  • cpukit/score/cpu/sparc/cpu.c

    r93c2b41 ra32835a3  
    7272
    7373  _CPU_Table = *cpu_table;
     74
     75  /*
     76   *  Since no tasks have been created yet and no interrupts have occurred,
     77   *  there is no way that the currently executing thread can have an
     78   *  _ISR_Dispatch stack frame on its stack.
     79   */
     80  _CPU_ISR_Dispatch_disable = 0;
    7481}
    7582
     
    328335#endif
    329336    the_context->psr = tmp_psr;
    330 }
     337
     338  /*
     339   *  Since THIS thread is being created, there is no way that THIS
     340   *  thread can have an _ISR_Dispatch stack frame on its stack.
     341   */
     342    the_context->isr_dispatch_disable = 0;
     343}
  • cpukit/score/cpu/sparc/cpu_asm.S

    r93c2b41 ra32835a3  
    144144        std     %g6, [%o0 + G6_OFFSET]
    145145
     146        ! load the address of the ISR stack nesting prevention flag
     147        sethi    %hi(SYM(_CPU_ISR_Dispatch_disable)), %g2
     148        ld       [%g2 + %lo(SYM(_CPU_ISR_Dispatch_disable))], %g2
     149        ! save it a bit later so we do not waste a couple of cycles
     150
    146151        std     %l0, [%o0 + L0_OFFSET]       ! save the local registers
    147152        std     %l2, [%o0 + L2_OFFSET]
    148153        std     %l4, [%o0 + L4_OFFSET]
    149154        std     %l6, [%o0 + L6_OFFSET]
     155
     156        ! Now actually save ISR stack nesting prevention flag
     157        st       %g2, [%o0 + ISR_DISPATCH_DISABLE_STACK_OFFSET]
    150158
    151159        std     %i0, [%o0 + I0_OFFSET]       ! save the input registers
     
    271279        ldd     [%o1 + G6_OFFSET], %g6
    272280
     281        ! Load thread specific ISR dispatch prevention flag
     282        ld      [%o1 + ISR_DISPATCH_DISABLE_STACK_OFFSET], %o2
     283        sethi    %hi(SYM(_CPU_ISR_Dispatch_disable)), %o3
     284        ! Store it to memory later to use the cycles
     285
    273286        ldd     [%o1 + L0_OFFSET], %l0        ! restore the local registers
    274287        ldd     [%o1 + L2_OFFSET], %l2
    275288        ldd     [%o1 + L4_OFFSET], %l4
    276289        ldd     [%o1 + L6_OFFSET], %l6
     290
     291        ! Now restore thread specific ISR dispatch prevention flag
     292        st       %o2,[%o3 + %lo(SYM(_CPU_ISR_Dispatch_disable))]
    277293
    278294        ldd     [%o1 + I0_OFFSET], %i0        ! restore the output registers
     
    634650        orcc     %l6, %g0, %g0   ! Is dispatching disabled?
    635651        bnz      simple_return   ! Yes, then do a "simple" exit
    636         nop                      ! delay slot
     652        ! NOTE: Use the delay slot
     653        sethi    %hi(SYM(_CPU_ISR_Dispatch_disable)), %l6
     654
     655        ! Are we dispatching from a previous ISR in the interrupted thread?
     656        ld       [%l6 + %lo(SYM(_CPU_ISR_Dispatch_disable))], %l7
     657        orcc     %l7, %g0, %g0   ! Is this thread already doing an ISR?
     658        bnz      simple_return   ! Yes, then do a "simple" exit
     659        ! NOTE: Use the delay slot
     660        sethi    %hi(SYM(_Context_Switch_necessary)), %l4
     661       
    637662
    638663        /*
     
    641666         */
    642667
    643         sethi    %hi(SYM(_Context_Switch_necessary)), %l4
    644668        ld       [%l4 + %lo(SYM(_Context_Switch_necessary))], %l5
    645669
    646670        orcc     %l5, %g0, %g0   ! Is thread switch necessary?
    647671        bnz      SYM(_ISR_Dispatch) ! yes, then invoke the dispatcher
    648         nop                      ! delay slot
     672        ! NOTE: Use the delay slot
     673        sethi    %hi(SYM(_ISR_Signals_to_thread_executing)), %l6
    649674
    650675        /*
     
    653678         */
    654679
    655         sethi    %hi(SYM(_ISR_Signals_to_thread_executing)), %l6
    656680        ld       [%l6 + %lo(SYM(_ISR_Signals_to_thread_executing))], %l7
    657681
     
    670694        PUBLIC(_ISR_Dispatch)
    671695SYM(_ISR_Dispatch):
     696        ! Set ISR dispatch nesting prevention flag
     697        mov      1,%l6
     698        sethi    %hi(SYM(_CPU_ISR_Dispatch_disable)), %l5
     699        st       %l6,[%l5 + %lo(SYM(_CPU_ISR_Dispatch_disable))]
    672700
    673701        /*
     
    685713        nop
    686714        nop
    687 
     715isr_dispatch:
    688716        call    SYM(_Thread_Dispatch), 0
    689717        nop
     
    701729
    702730        /*
     731         *  While we had ISR dispatching disabled in this thread,
     732         *  did we miss anything.  If so, then we need to do another
     733         *  _Thread_Dispatch before leaving this ISR Dispatch context.
     734         */
     735
     736        sethi    %hi(SYM(_Context_Switch_necessary)), %l4
     737        ld       [%l4 + %lo(SYM(_Context_Switch_necessary))], %l5
     738
     739        ! NOTE: Use some of delay slot to start loading this
     740        sethi    %hi(SYM(_ISR_Signals_to_thread_executing)), %l6
     741        ld       [%l6 + %lo(SYM(_ISR_Signals_to_thread_executing))], %l7
     742
     743        orcc     %l5, %g0, %g0   ! Is thread switch necessary?
     744        bnz      dispatchAgain   ! yes, then invoke the dispatcher AGAIN
     745        ! NOTE: Use the delay slot to catch the orcc below
     746
     747        /*
     748         *  Finally, check to see if signals were sent to the currently
     749         *  executing task.  If so, we need to invoke the interrupt dispatcher.
     750         */
     751
     752        ! NOTE: Delay slots above were used to perform the load AND
     753        !       this orcc falls into the delay slot for bnz above
     754        orcc     %l7, %g0, %g0   ! Were signals sent to the currently
     755                                 !   executing thread?
     756        bz       allow_nest_again ! No, then clear out and return
     757        ! NOTE: use the delay slot from the bz to load 3 into %g1
     758
     759        ! Yes, then invoke the dispatcher
     760dispatchAgain:
     761        mov     3,%g1                           ! syscall (enable interrupts)
     762        ta      0                               ! syscall (enable interrupts)
     763        ba      isr_dispatch
     764        nop
     765
     766allow_nest_again:
     767
     768        ! Zero out ISR stack nesting prevention flag
     769        sethi    %hi(SYM(_CPU_ISR_Dispatch_disable)), %l5
     770        st       %g0,[%l5 + %lo(SYM(_CPU_ISR_Dispatch_disable))]
     771
     772        /*
    703773         *  The CWP in place at this point may be different from
    704774         *  that which was in effect at the beginning of the ISR if we
  • cpukit/score/cpu/sparc/rtems/score/cpu.h

    r93c2b41 ra32835a3  
    334334
    335335    uint32_t   psr;
     336    uint32_t   isr_dispatch_disable;
    336337} Context_Control;
    337338
     
    379380
    380381#define PSR_OFFSET   0x80
    381 
    382 #define CONTEXT_CONTROL_SIZE 0x84
     382#define ISR_DISPATCH_DISABLE_STACK_OFFSET 0x84
     383
     384#define CONTEXT_CONTROL_SIZE 0x88
    383385
    384386/*
     
    554556
    555557/*
     558 *  This flag is context switched with each thread.  It indicates
     559 *  that THIS thread has an _ISR_Dispatch stack frame on its stack.
     560 *  By using this flag, we can avoid nesting more interrupt dispatching
     561 *  attempts on a previously interrupted thread's stack.
     562 */
     563
     564SCORE_EXTERN volatile uint32_t _CPU_ISR_Dispatch_disable;
     565
     566/*
    556567 *  The following type defines an entry in the SPARC's trap table.
    557568 *
Note: See TracChangeset for help on using the changeset viewer.