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.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.