Ticket #2082: 0001-Move-enabling-of-other-traps-after-the-stack-switch.patch

File 0001-Move-enabling-of-other-traps-after-the-stack-switch.patch, 6.2 KB (added by Pierre Willenbrock, on 11/30/12 at 12:56:56)

Fix nested interrupts on non-smp systems

  • c/src/lib/libbsp/sparc/shared/irq_asm.S

    From f568bacda924f9906aa7099d53eb00f90631f961 Mon Sep 17 00:00:00 2001
    From: Pierre Willenbrock <Pierre.Willenbrock@dfki.de>
    Date: Tue, 27 Nov 2012 18:36:27 +0100
    Subject: [PATCH] Move enabling of other traps after the stack switch
    ---
     c/src/lib/libbsp/sparc/shared/irq_asm.S |  155 ++++++++++++++++---------------
     1 file changed, 78 insertions(+), 77 deletions(-)
    
    diff --git a/c/src/lib/libbsp/sparc/shared/irq_asm.S b/c/src/lib/libbsp/sparc/shared/irq_asm.S
    index 6725597..909e1a8 100644
    a b save_isf: 
    177177
    178178        mov     %sp, %o1                       ! 2nd arg to ISR Handler
    179179
     180        PUBLIC(_ISR_PER_CPU)
     181SYM(_ISR_PER_CPU):
     182
     183#if defined(RTEMS_SMP)
     184        sethi    %hi(_Per_CPU_Information_p), %l5
     185        add      %l5, %lo(_Per_CPU_Information_p), %l5
     186    #if BSP_LEON3_SMP
     187        /* LEON3 SMP support */
     188        rd      %asr17, %l7
     189        srl     %l7, 28, %l7    /* CPU number is upper 4 bits so shift */
     190        sll     %l7, 2, %l7     /* l7 = offset */
     191        add     %l5, %l7, %l5
     192    #endif
     193        ld       [%l5], %l5     /* l5 = pointer to per CPU */
     194
     195        /*
     196         *  On multi-core system, we need to use SMP safe versions
     197         *  of ISR and Thread Dispatch critical sections.
     198         *
     199         *  _ISR_SMP_Enter returns the interrupt nest level.  If we are
     200         *  outermost interrupt, then we need to switch stacks.
     201         */
     202        call    SYM(_ISR_SMP_Enter), 0
     203         mov      %sp, %fp              ! delay slot
     204        cmp     %o0, 0
     205#else
     206        /*
     207         *  On single core system, we can directly use variables.
     208         *
     209         *  Increment ISR nest level and Thread dispatch disable level.
     210         *
     211         *  Register usage for this section:
     212         *
     213         *    l4 = _Thread_Dispatch_disable_level pointer
     214         *    l5 = _ISR_Nest_level pointer
     215         *    l6 = _Thread_Dispatch_disable_level value
     216         *    l7 = _ISR_Nest_level value
     217         *
     218         *  NOTE: It is assumed that l4 - l7 will be preserved until the ISR
     219         *        nest and thread dispatch disable levels are unnested.
     220         */
     221        sethi    %hi(SYM(_Thread_Dispatch_disable_level)), %l4
     222        ld       [%l4 + %lo(SYM(_Thread_Dispatch_disable_level))], %l6
     223
     224        sethi    %hi(_Per_CPU_Information), %l5
     225        add      %l5, %lo(_Per_CPU_Information), %l5
     226
     227        ld       [%l5 + PER_CPU_ISR_NEST_LEVEL], %l7
     228
     229        add      %l6, 1, %l6
     230        st       %l6, [%l4 + %lo(SYM(_Thread_Dispatch_disable_level))]
     231
     232        add      %l7, 1, %l7
     233        st       %l7, [%l5 + PER_CPU_ISR_NEST_LEVEL]
     234
     235        /*
     236         *  If ISR nest level was zero (now 1), then switch stack.
     237         */
     238        mov      %sp, %fp
     239        subcc    %l7, 1, %l7             ! outermost interrupt handler?
     240#endif
     241
     242        /*
     243         *  Do we need to switch to the interrupt stack?
     244         */
     245        beq,a    dont_switch_stacks      ! No, then do not switch stacks
     246         ld      [%l5 + PER_CPU_INTERRUPT_STACK_HIGH], %sp
     247
     248dont_switch_stacks:
     249        /*
     250         *  Make sure we have a place on the stack for the window overflow
     251         *  trap handler to write into.  At this point it is safe to
     252         *  enable traps again.
     253         */
     254
     255        sub      %sp, CPU_MINIMUM_STACK_FRAME_SIZE, %sp
     256
     257
    180258        /*
    181259         *  Check if we have an external interrupt (trap 0x11 - 0x1f). If so,
    182260         *  set the PIL in the %psr to mask off interrupts with lower priority.
    pil_fixed: 
    267345        wr       %g5, SPARC_PSR_ET_MASK, %psr ! **** ENABLE TRAPS ****
    268346dont_fix_pil2:
    269347
    270         PUBLIC(_ISR_PER_CPU)
    271 SYM(_ISR_PER_CPU):
    272 
    273 #if defined(RTEMS_SMP)
    274         sethi    %hi(_Per_CPU_Information_p), %l5
    275         add      %l5, %lo(_Per_CPU_Information_p), %l5
    276     #if BSP_LEON3_SMP
    277         /* LEON3 SMP support */
    278         rd      %asr17, %l7
    279         srl     %l7, 28, %l7    /* CPU number is upper 4 bits so shift */
    280         sll     %l7, 2, %l7     /* l7 = offset */
    281         add     %l5, %l7, %l5
    282     #endif
    283         ld       [%l5], %l5     /* l5 = pointer to per CPU */
    284 
    285         /*
    286          *  On multi-core system, we need to use SMP safe versions
    287          *  of ISR and Thread Dispatch critical sections.
    288          *
    289          *  _ISR_SMP_Enter returns the interrupt nest level.  If we are
    290          *  outermost interrupt, then we need to switch stacks.
    291          */
    292         call    SYM(_ISR_SMP_Enter), 0
    293          mov      %sp, %fp              ! delay slot
    294         cmp     %o0, 0
    295 #else
    296         /*
    297          *  On single core system, we can directly use variables.
    298          *
    299          *  Increment ISR nest level and Thread dispatch disable level.
    300          *
    301          *  Register usage for this section:
    302          *
    303          *    l4 = _Thread_Dispatch_disable_level pointer
    304          *    l5 = _ISR_Nest_level pointer
    305          *    l6 = _Thread_Dispatch_disable_level value
    306          *    l7 = _ISR_Nest_level value
    307          *
    308          *  NOTE: It is assumed that l4 - l7 will be preserved until the ISR
    309          *        nest and thread dispatch disable levels are unnested.
    310          */
    311         sethi    %hi(SYM(_Thread_Dispatch_disable_level)), %l4
    312         ld       [%l4 + %lo(SYM(_Thread_Dispatch_disable_level))], %l6
    313 
    314         sethi    %hi(_Per_CPU_Information), %l5
    315         add      %l5, %lo(_Per_CPU_Information), %l5
    316 
    317         ld       [%l5 + PER_CPU_ISR_NEST_LEVEL], %l7
    318 
    319         add      %l6, 1, %l6
    320         st       %l6, [%l4 + %lo(SYM(_Thread_Dispatch_disable_level))]
    321 
    322         add      %l7, 1, %l7
    323         st       %l7, [%l5 + PER_CPU_ISR_NEST_LEVEL]
    324 
    325         /*
    326          *  If ISR nest level was zero (now 1), then switch stack.
    327          */
    328         mov      %sp, %fp
    329         subcc    %l7, 1, %l7             ! outermost interrupt handler?
    330 #endif
    331 
    332         /*
    333          *  Do we need to switch to the interrupt stack?
    334          */
    335         beq,a    dont_switch_stacks      ! No, then do not switch stacks
    336          ld      [%l5 + PER_CPU_INTERRUPT_STACK_HIGH], %sp
    337 
    338 dont_switch_stacks:
    339         /*
    340          *  Make sure we have a place on the stack for the window overflow
    341          *  trap handler to write into.  At this point it is safe to
    342          *  enable traps again.
    343          */
    344 
    345         sub      %sp, CPU_MINIMUM_STACK_FRAME_SIZE, %sp
    346 
    347348        /*
    348349         *  Vector to user's handler.
    349350         *