Changeset 6a1b9e4 in rtems


Ignore:
Timestamp:
Nov 22, 2016, 9:13:27 AM (4 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
5, master
Children:
8fd465e
Parents:
c09db57
git-author:
Sebastian Huber <sebastian.huber@…> (11/22/16 09:13:27)
git-committer:
Sebastian Huber <sebastian.huber@…> (11/28/16 15:08:43)
Message:

sparc: Optimize _ISR_Handler()

Use _Thread_Do_dispatch() instead of _Thread_Dispatch(). Restore the
PSR[EF] state of the interrupted context via new system call
syscall_irqdis_fp in case floating-point support is enabled.

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/erc32/startup/spurious.c

    rc09db57 r6a1b9e4  
    165165        (( trap >= 0x70 ) && ( trap <= 0x83 )) ||
    166166        ( trap == 0x80 + SPARC_SWTRAP_IRQDIS ) ||
     167#if SPARC_HAS_FPU == 1
     168        ( trap == 0x80 + SPARC_SWTRAP_IRQDIS_FP ) ||
     169#endif
    167170        ( trap == 0x80 + SPARC_SWTRAP_IRQEN ))
    168171      continue;
  • c/src/lib/libbsp/sparc/leon2/startup/spurious.c

    rc09db57 r6a1b9e4  
    152152        (( trap >= 0x70 ) && ( trap <= 0x83 )) ||
    153153        ( trap == 0x80 + SPARC_SWTRAP_IRQDIS ) ||
     154#if SPARC_HAS_FPU == 1
     155        ( trap == 0x80 + SPARC_SWTRAP_IRQDIS_FP ) ||
     156#endif
    154157        ( trap == 0x80 + SPARC_SWTRAP_IRQEN ))
    155158      continue;
  • c/src/lib/libbsp/sparc/leon3/startup/spurious.c

    rc09db57 r6a1b9e4  
    157157        (( trap >= 0x70 ) && ( trap <= 0x83 )) ||
    158158        ( trap == 0x80 + SPARC_SWTRAP_IRQDIS ) ||
     159#if SPARC_HAS_FPU == 1
     160        ( trap == 0x80 + SPARC_SWTRAP_IRQDIS_FP ) ||
     161#endif
    159162        ( trap == 0x80 + SPARC_SWTRAP_IRQEN ))
    160163      continue;
  • c/src/lib/libbsp/sparc/shared/irq_asm.S

    rc09db57 r6a1b9e4  
    88 *  On-Line Applications Research Corporation (OAR).
    99 *
    10  *  Copyright (c) 2014-2015 embedded brains GmbH
     10 *  Copyright (c) 2014, 2016 embedded brains GmbH
    1111 *
    1212 *  The license and distribution terms for this file may be
     
    546546#if defined(RTEMS_PROFILING)
    547547         mov     %o5, %l3               ! save interrupt entry instant
     548#else
     549         nop                            ! delay slot
     550#endif
     551
     552#if SPARC_HAS_FPU == 1
     553        mov      %l0, %g1               ! PSR[EF] value of interrupted context
     554        ta       SPARC_SWTRAP_IRQDIS_FP ! **** DISABLE INTERRUPTS ****
     555#else
     556        ta       SPARC_SWTRAP_IRQDIS    ! **** DISABLE INTERRUPTS ****
     557#endif
     558
     559#if defined(RTEMS_PROFILING)
    548560        cmp      %l7, 0
    549561        bne      profiling_not_outer_most_exit
    550562         nop
    551         ta       SPARC_SWTRAP_IRQDIS    ! Call interrupt disable trap handler
    552563        call     %l4, 0                 ! Call _SPARC_Counter.counter_read
    553          nop
     564         mov     %g1, %l4               ! Save previous interrupt status
    554565        mov      %o0, %o2               ! o2 = 3rd arg = interrupt exit instant
    555566        mov      %l3, %o1               ! o1 = 2nd arg = interrupt entry instant
     
    557568         mov     %g6, %o0               ! o0 = 1st arg = per-CPU control
    558569profiling_not_outer_most_exit:
    559 #else
    560          nop                            ! delay slot
    561 #endif
    562 
    563         /*
    564          *  Redisable traps so we can finish up the interrupt processing.
    565          *  This is a VERY conservative place to do this.
    566          *
    567          *  NOTE: %l0 has the PSR which was in place when we took the trap.
    568          */
    569 
    570         mov      %l0, %psr             ! **** DISABLE TRAPS ****
    571         nop; nop; nop
     570#endif
    572571
    573572        /*
     
    576575         *  Register usage for this section:
    577576         *
    578          *    l6 = _Thread_Dispatch_disable_level value
    579          *    l7 = _ISR_Nest_level value
    580          */
    581 
     577         *    o2 = g6->dispatch_necessary value
     578         *    o3 = g6->isr_dispatch_disable value
     579         *    l6 = g6->thread_dispatch_disable_level value
     580         *    l7 = g6->isr_nest_level value
     581         */
     582
     583        ldub     [%g6 + PER_CPU_DISPATCH_NEEDED], %o2
     584        ld       [%g6 + PER_CPU_ISR_DISPATCH_DISABLE], %o3
    582585        st       %l7, [%g6 + PER_CPU_ISR_NEST_LEVEL]
    583 
    584586        sub      %l6, 1, %l6
    585587        st       %l6, [%g6 + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
    586588
    587589        /*
    588          *  If dispatching is disabled (includes nested interrupt case),
    589          *  then do a "simple" exit.
    590          */
    591 
    592         orcc     %l6, %g0, %g0   ! Is dispatching disabled?
    593         bnz      simple_return   ! Yes, then do a "simple" exit
    594         nop
    595 
    596         ! Are we dispatching from a previous ISR in the interrupted thread?
    597         ld       [%g6 + PER_CPU_ISR_DISPATCH_DISABLE], %l7
    598         orcc     %l7, %g0, %g0   ! Is this thread already doing an ISR?
    599         bnz      simple_return   ! Yes, then do a "simple" exit
    600         nop
    601 
    602 
    603         /*
    604          *  If a context switch is necessary, then do fudge stack to
    605          *  return to the interrupt dispatcher.
    606          */
    607 
    608         ldub     [%g6 + PER_CPU_DISPATCH_NEEDED], %l6
    609 
    610         orcc     %l6, %g0, %g0   ! Is thread switch necessary?
    611         bz       simple_return   ! no, then do a simple return
    612         nop
    613 
    614         /*
    615          *  Invoke interrupt dispatcher.
    616          */
    617 
    618         ! Set ISR dispatch nesting prevention flag
    619         mov      1,%l6
     590         * Thread dispatching is necessary and allowed if and only if
     591         *   g6->dispatch_necessary == 1 and
     592         *   g6->isr_dispatch_disable == 0 and
     593         *   g6->thread_dispatch_disable_level == 0.
     594         *
     595         * Otherwise, continue with the simple return.
     596         */
     597        xor      %o2, 1, %o2
     598        or       %o2, %l6, %o2
     599        orcc     %o2, %o3, %o2
     600        bnz      simple_return
     601
     602        /*
     603         * Switch back on the interrupted tasks stack and add enough room to
     604         * invoke the dispatcher.  Doing this in the delay slot causes no harm,
     605         * since the stack pointer (%sp) is not used in the simple return path.
     606         */
     607         sub     %fp, SPARC_MINIMUM_STACK_FRAME_SIZE, %sp
     608
     609isr_dispatch:
     610
     611        /* Set ISR dispatch disable and thread dispatch disable level to one */
     612        mov      1, %l6
     613        st       %l6, [%g6 + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
    620614        st       %l6, [%g6 + PER_CPU_ISR_DISPATCH_DISABLE]
    621615
    622         /*
    623          *  The following subtract should get us back on the interrupted
    624          *  tasks stack and add enough room to invoke the dispatcher.
    625          *  When we enable traps, we are mostly back in the context
    626          *  of the task and subsequent interrupts can operate normally.
    627          */
    628 
    629         sub      %fp, SPARC_MINIMUM_STACK_FRAME_SIZE, %sp
    630 
    631         or      %l0, SPARC_PSR_ET_MASK, %l7    ! l7 = PSR with ET=1
    632         mov     %l7, %psr                      !  **** ENABLE TRAPS ****
    633         nop
    634         nop
    635         nop
    636 isr_dispatch:
     616        /* Call _Thread_Do_dispatch(), this function will enable interrupts */
     617
     618        mov      0, %o1                 ! ISR level for _Thread_Do_dispatch()
    637619
    638620#if SPARC_HAS_FPU == 1 && defined(SPARC_USE_SAFE_FP_SUPPORT)
     
    665647        std     %f28, [%sp + FP_FRAME_OFFSET_F28_F29]
    666648        std     %f30, [%sp + FP_FRAME_OFFSET_F3O_F31]
    667         call    SYM(_Thread_Dispatch), 0
    668          st     %fsr, [%sp + FP_FRAME_OFFSET_FSR]
     649        st      %fsr, [%sp + FP_FRAME_OFFSET_FSR]
     650        call    SYM(_Thread_Do_dispatch), 0
     651         mov    %g6, %o0
    669652
    670653        /*
     
    695678#endif
    696679
    697         call    SYM(_Thread_Dispatch), 0
    698          nop
     680        call    SYM(_Thread_Do_dispatch), 0
     681         mov    %g6, %o0
    699682
    700683#if SPARC_HAS_FPU == 1 && defined(SPARC_USE_SAFE_FP_SUPPORT)
     
    702685#endif
    703686
    704         /*
    705          *  We invoked _Thread_Dispatch in a state similar to the interrupted
    706          *  task.  In order to safely be able to tinker with the register
    707          *  windows and get the task back to its pre-interrupt state,
    708          *  we need to disable interrupts disabled so we can safely tinker
    709          *  with the register windowing.  In particular, the CWP in the PSR
    710          *  is fragile during this period. (See PR578.)
    711          */
    712         ta      SPARC_SWTRAP_IRQDIS  ! syscall (disable interrupts)
     687        ta       SPARC_SWTRAP_IRQDIS ! **** DISABLE INTERRUPTS ****
    713688
    714689        /*
    715690         *  While we had ISR dispatching disabled in this thread,
    716          *  did we miss anything.  If so, then we need to do another
    717          *  _Thread_Dispatch before leaving this ISR Dispatch context.
     691         *  did we miss anything?  If so, then we need to do another
     692         *  _Thread_Do_dispatch() before leaving this ISR dispatch context.
    718693         */
    719694        ldub    [%g6 + PER_CPU_DISPATCH_NEEDED], %l7
    720695
    721         orcc    %l7, %g0, %g0        ! Is thread switch necesary?
    722         bne,a   isr_dispatch         ! Yes, then invoke the dispatcher.
    723                                      ! g1 = Old PSR PIL returned from IRQDis
    724         ta      SPARC_SWTRAP_IRQEN   ! syscall (enable interrupts to same level)
    725 
    726         ! No, then clear out and return
    727 
    728         ! Zero out ISR stack nesting prevention flag
     696        orcc    %l7, %g0, %g0        ! Is a thread dispatch necessary?
     697        bne     isr_dispatch         ! Yes, then invoke the dispatcher again.
     698         mov    0, %o1               ! ISR level for _Thread_Do_dispatch()
     699
     700        /*
     701         * No, then set the ISR dispatch disable flag to zero and continue with
     702         * the simple return.
     703         */
    729704        st       %g0, [%g6 + PER_CPU_ISR_DISPATCH_DISABLE]
    730705
  • c/src/lib/libbsp/sparc/shared/start/start.S

    rc09db57 r6a1b9e4  
    208208  IRQDIS_TRAP(SYM(syscall_irqdis));             ! 89 IRQ Disable syscall trap
    209209  IRQEN_TRAP(SYM(syscall_irqen));               ! 8A IRQ Enable syscall trap
    210 
     210#if SPARC_HAS_FPU == 1
     211  IRQDIS_TRAP(SYM(syscall_irqdis_fp));          ! 8B IRQ disable
     212                                                ! and set PSR[EF] syscall trap
     213#else
    211214  SOFT_TRAP;                                    ! 8B
     215#endif
    212216  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 8C - 8F
     217
    213218  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 90 - 93
    214219  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 94 - 97
  • c/src/lib/libcpu/sparc/syscall/syscall.S

    rc09db57 r6a1b9e4  
    9696         rett   %l2 + 4
    9797
     98#if SPARC_HAS_FPU == 1
     99        /*
     100         *  system call - Interrupt disable and set PSR[EF] according to caller
     101         *                specified %g1
     102         *
     103         *  On entry:
     104         *
     105         *    g1 = the desired PSR[EF] value (from caller)
     106         *    l0 = psr (from trap table)
     107         *    l1 = pc
     108         *    l2 = npc
     109         *    l3 = psr | SPARC_PSR_PIL_MASK
     110         *
     111         *  On exit:
     112         *    g1 = old psr (to user)
     113         */
     114
     115.align 32                               ! Align to 32-byte cache-line
     116        PUBLIC(syscall_irqdis_fp)
     117
     118SYM(syscall_irqdis_fp):
     119        /*
     120         * We cannot use an intermediate value for operations with the PSR[EF]
     121         * bit since they use a 13-bit sign extension and PSR[EF] is bit 12.
     122         */
     123        sethi   %hi(SPARC_PSR_EF_MASK), %l4
     124
     125        andn    %l3, %l4, %l3                   ! Clear PSR[EF]
     126        and     %g1, %l4, %g1                   ! Select PSR[EF] only from %g1
     127        or      %l3, %g1, %l3                   ! Set PSR[EF] according to %g1
     128        mov     %l3, %psr                       ! Set PSR. Write delay 3 instr
     129        or      %l0, SPARC_PSR_ET_MASK, %g1     ! return old PSR with ET=1
     130        nop                                     ! PSR write delay
     131        jmp     %l2                             ! Return to after TA 9.
     132         rett   %l2 + 4
     133#endif
     134
    98135#if defined(RTEMS_PARAVIRT)
    99136
  • cpukit/score/cpu/sparc/rtems/score/sparc.h

    rc09db57 r6a1b9e4  
    154154#define SPARC_SWTRAP_IRQDIS 9
    155155#define SPARC_SWTRAP_IRQEN 10
     156#if SPARC_HAS_FPU == 1
     157#define SPARC_SWTRAP_IRQDIS_FP 11
     158#endif
    156159
    157160#ifndef ASM
Note: See TracChangeset for help on using the changeset viewer.