Changeset dff1803 in rtems


Ignore:
Timestamp:
12/03/14 10:35:52 (9 years ago)
Author:
Daniel Hellstrom <daniel@…>
Branches:
4.11, 5, master
Children:
adc1dbeb
Parents:
4081032
git-author:
Daniel Hellstrom <daniel@…> (12/03/14 10:35:52)
git-committer:
Daniel Hellstrom <daniel@…> (12/04/14 11:51:11)
Message:

SPARC: optimize IRQ enable & disable

  • Coding style cleanups.
  • Use OS reserved trap 0x89 for IRQ Disable
  • Use OS reserved trap 0x8A for IRQ Enable
  • Add to SPARC CPU supplement documentation

This will result in faster Disable/Enable? code since the
system trap handler does not need to decode which function
the user wants. Besides the IRQ disable/enabled can now
be inline which avoids the caller to take into account that
o0-o7+g1-g4 registers are destroyed by trap handler.

It was also possible to reduce the interrupt trap handler by
five instructions due to this.

Files:
7 edited

Legend:

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

    r4081032 rdff1803  
    1919
    2020#include <bsp.h>
     21#include <rtems/score/cpu.h>
    2122#include <rtems/bspIo.h>
    2223
     
    147148    /*
    148149     *  Skip window overflow, underflow, and flush as well as software
    149      *  trap 0 which we will use as a shutdown. Also avoid trap 0x70 - 0x7f
    150      *  which cannot happen and where some of the space is used to pass
    151      *  paramaters to the program.
     150     *  trap 0,9,10 which we will use as a shutdown, IRQ disable, IRQ enable.
     151     *  Also avoid trap 0x70 - 0x7f which cannot happen and where some of the
     152     *  space is used to pass paramaters to the program.
    152153     */
    153154
    154     if (( trap == 5 || trap == 6 ) ||
     155    if (( trap == 5 ) || ( trap == 6 ) ||
    155156        (( trap >= 0x11 ) && ( trap <= 0x1f )) ||
    156         (( trap >= 0x70 ) && ( trap <= 0x83 )))
     157        (( trap >= 0x70 ) && ( trap <= 0x83 )) ||
     158        ( trap == SPARC_SWTRAP_IRQDIS ) || ( trap == SPARC_SWTRAP_IRQEN ))
    157159      continue;
    158160
  • c/src/lib/libbsp/sparc/shared/irq_asm.S

    r4081032 rdff1803  
    500500        bne      profiling_not_outer_most_exit
    501501         nop
    502         call     SYM(sparc_disable_interrupts), 0
    503          nop
     502        ta       SPARC_SWTRAP_IRQDIS    ! Call interrupt disable trap handler
    504503        ld       [%l4], %o2             ! o2 = 3rd arg = interrupt exit instant
    505504        mov      %l3, %o1               ! o1 = 2nd arg = interrupt entry instant
     
    586585isr_dispatch:
    587586        call    SYM(_Thread_Dispatch), 0
    588         nop
    589 
    590         /*
    591          *  We invoked _Thread_Dispatch in a state similar to the interrupted
    592          *  task.  In order to safely be able to tinker with the register
    593          *  windows and get the task back to its pre-interrupt state,
    594          *  we need to disable interrupts disabled so we can safely tinker
    595          *  with the register windowing.  In particular, the CWP in the PSR
    596          *  is fragile during this period. (See PR578.)
    597          */
    598         mov     2,%g1                           ! syscall (disable interrupts)
    599         ta      0                               ! syscall (disable interrupts)
     587         nop
     588
     589        /*
     590         *  We invoked _Thread_Dispatch in a state similar to the interrupted
     591         *  task.  In order to safely be able to tinker with the register
     592         *  windows and get the task back to its pre-interrupt state,
     593         *  we need to disable interrupts disabled so we can safely tinker
     594         *  with the register windowing.  In particular, the CWP in the PSR
     595         *  is fragile during this period. (See PR578.)
     596         */
     597        ta      SPARC_SWTRAP_IRQDIS  ! syscall (disable interrupts)
    600598
    601599        /*
     
    604602         *  _Thread_Dispatch before leaving this ISR Dispatch context.
    605603         */
    606 
    607         ldub     [%g6 + PER_CPU_DISPATCH_NEEDED], %l7
    608 
    609         orcc     %l7, %g0, %g0    ! Is thread switch necesary?
    610         bz       allow_nest_again ! No, then clear out and return
    611         nop
    612 
    613         ! Yes, then invoke the dispatcher
    614 dispatchAgain:
    615         mov     3,%g1                           ! syscall (enable interrupts)
    616         ta      0                               ! syscall (enable interrupts)
    617         ba      isr_dispatch
    618         nop
    619 
     604        ldub    [%g6 + PER_CPU_DISPATCH_NEEDED], %l7
     605
     606        orcc    %l7, %g0, %g0        ! Is thread switch necesary?
     607        bne,a   isr_dispatch         ! Yes, then invoke the dispatcher.
     608                                     ! g1 = Old PSR PIL returned from IRQDis
     609        ta      SPARC_SWTRAP_IRQEN   ! syscall (enable interrupts to same level)
     610
     611        ! No, then clear out and return
    620612allow_nest_again:
    621613
  • c/src/lib/libbsp/sparc/shared/start/start.S

    r4081032 rdff1803  
    3636 * System call optimized trap table entry
    3737 */
    38 #define SYSCALL_TRAP(_vector, _handler)  \
     38#define IRQDIS_TRAP(_handler)  \
    3939  mov   %psr, %l0 ; \
    4040  sethi %hi(_handler), %l4 ; \
    4141  jmp   %l4+%lo(_handler); \
    42    subcc %g1, 3, %g0; ! prepare for syscall 3 check
     42   or   %l0, 0x0f00, %l3; ! Set PIL=0xf to disable IRQ
     43
     44/*
     45 * System call optimized trap table entry
     46 */
     47#define IRQEN_TRAP(_handler)  \
     48  mov   %psr, %l0 ; \
     49  sethi %hi(_handler), %l4 ; \
     50  jmp   %l4+%lo(_handler); \
     51   andn %l0, 0xf00, %l3; ! Set PIL=0 to Enable IRQ
    4352
    4453/*
     
    184193   */
    185194
    186   SYSCALL_TRAP( 0x80, SYM(syscall) );           ! 80 syscall SW trap
    187   SOFT_TRAP; SOFT_TRAP;                         ! 81 - 82
     195  TRAP( 0x80, SYM(syscall) );                   ! 80 halt syscall SW trap
     196  SOFT_TRAP; SOFT_TRAP;                         ! 81 - 82
    188197  TRAP( 0x83, SYM(window_flush_trap_handler) ); ! 83 flush windows SW trap
    189198
    190199  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 84 - 87
    191   SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 88 - 8B
     200  SOFT_TRAP;                                    ! 88
     201
     202  /*
     203   *  SW Trap 9-15 Reserved for Operating System
     204   * 
     205   *  SPARC_SWTRAP_IRQDIS
     206   *  SPARC_SWTRAP_IRQEN
     207   */
     208  IRQDIS_TRAP(SYM(syscall_irqdis));             ! 89 IRQ Disable syscall trap
     209  IRQEN_TRAP(SYM(syscall_irqen));               ! 8A IRQ Enable syscall trap
     210
     211  SOFT_TRAP;                                    ! 8B
    192212  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 8C - 8F
    193213  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 90 - 93
  • c/src/lib/libcpu/sparc/syscall/syscall.S

    r4081032 rdff1803  
    2020#include "syscall.h"
    2121
    22         .seg    "text"
    23         /*
    24          *  system call
    25         *
    26         *  On entry:
    27         *
    28         *    l0 = psr (from trap table)
    29         *    l1 = pc
    30         *    l2 = npc
    31          *    g1 = system call id
    32         *
    33         *  System Call 1 (exit):
    34         *    g2 = additional exit code 1
    35         *    g3 = additional exit code 2
    36         */
     22        .seg    "text"
     23        /*
     24         *  system call - halt
     25        *
     26        *  On entry:
     27        *
     28        *    l0 = psr (from trap table)
     29        *    l1 = pc
     30        *    l2 = npc
     31         *    g1 = system call id (1)
     32        *
     33        *  System Call 1 (exit):
     34        *    g2 = additional exit code 1
     35        *    g3 = additional exit code 2
     36        */
    3737
    38 .align 32                               ! Align to 32-byte cache-line
    39         PUBLIC(syscall)
     38        PUBLIC(syscall)
    4039
    4140SYM(syscall):
     41        ta      0                       ! syscall 1, halt with %g1,%g2,%g3 info
    4242
    43         ! "subcc, %g1, 3, %g0" done in trap table
    44         bne     2f                      ! syscall 3? enable interrupt
    45          and    %i0, SPARC_PSR_PIL_MASK, %l4
    46         andn    %l0, SPARC_PSR_PIL_MASK, %l5
    47         wr      %l4, %l5, %psr          ! Update PSR according to syscall 3
    48 1:                                      ! leave, with 3 inst PSR-write delay
    49         mov     0, %g1                  ! clear %g1
    50         or      %l0, SPARC_PSR_ET_MASK, %i0     ! return old psr with ET=1. No
    51                                                 ! effect on syscall 3
    52         jmpl    %l2, %g0
    53          rett   %l2 + 4
    54 
    55 2:      or      %l0, 0x0f00, %l4        ! set PIL=15
    56         subcc   %g1, 2, %g0             ! syscall 2? disable interrupts
    57         beq,a   1b                      ! Annul delay-slot for syscall 1
    58          mov    %l4, %psr               ! Update PSR according to Syscall 2
    59         ta      0                       ! syscall 1 (not 2 or 3), halt
    60 
    61         PUBLIC(sparc_disable_interrupts)
    62 
    63 SYM(sparc_disable_interrupts):
    64 
    65         mov     SYS_irqdis, %g1
    66         retl
    67          ta     0
    68 
    69         PUBLIC(sparc_enable_interrupts)
    70 
    71 SYM(sparc_enable_interrupts):
    72 
    73         mov     SYS_irqen, %g1
    74         retl
    75          ta     0
    76 
    77         PUBLIC(sparc_syscall_exit)
     43        PUBLIC(sparc_syscall_exit)
    7844
    7945SYM(sparc_syscall_exit):
     
    8248        mov     %o0, %g2        ! Additional exit code 1
    8349        mov     %o1, %g3        ! Additional exit code 2
    84         ta      0
     50        ta      SPARC_SWTRAP_SYSCALL
     51
     52        /*
     53         *  system call - Interrupt Disable
     54         *
     55         *  On entry:
     56         *
     57         *    l0 = psr (from trap table)
     58         *    l1 = pc
     59         *    l2 = npc
     60         *    l3 = psr | SPARC_PSR_PIL_MASK
     61         *
     62         *  On exit:
     63         *    g1 = old psr (to user)
     64         */
     65
     66.align 32                               ! Align to 32-byte cache-line
     67        PUBLIC(syscall_irqdis)
     68
     69SYM(syscall_irqdis):
     70        mov     %l3, %psr                       ! Set PSR. Write delay 3 instr
     71        or      %l0, SPARC_PSR_ET_MASK, %g1     ! return old PSR with ET=1
     72        nop                                     ! PSR write delay
     73        jmp     %l2                             ! Return to after TA 9.
     74         rett   %l2 + 4
     75
     76        /*
     77         *  system call - Interrupt Enable
     78         *
     79         *  On entry:
     80         *
     81         *    l0 = psr (from trap table)
     82         *    l1 = pc
     83         *    l2 = npc
     84         *    l3 = psr & ~0x0f00
     85         *    g1 = new PIL to write (from user)
     86         */
     87
     88.align 32                               ! Align to 32-byte cache-line
     89        PUBLIC(syscall_irqen)
     90
     91SYM(syscall_irqen):
     92        and     %g1, SPARC_PSR_PIL_MASK, %l4    ! %l4 = (%g1 & 0xf00)
     93        wr      %l3, %l4, %psr                  ! PSR = (PSR & ~0xf00) ^ %l4
     94        nop; nop                                ! PSR write delay;
     95        jmp     %l2                             ! Return to after TA 10.
     96         rett   %l2 + 4
    8597
    8698#if defined(RTEMS_PARAVIRT)
  • c/src/lib/libcpu/sparc/syscall/syscall.h

    r4081032 rdff1803  
    11#define SYS_exit        1
    2 #define SYS_irqdis      2
    3 #define SYS_irqen       3
  • cpukit/score/cpu/sparc/rtems/score/sparc.h

    r4081032 rdff1803  
    150150#define LEON3_ASR17_PROCESSOR_INDEX_SHIFT 28
    151151
     152/* SPARC Software Trap number definitions */
     153#define SPARC_SWTRAP_SYSCALL 0
     154#define SPARC_SWTRAP_IRQDIS 9
     155#define SPARC_SWTRAP_IRQEN 10
     156
    152157#ifndef ASM
    153158
     
    299304 * @return This method returns the entire PSR contents.
    300305 */
    301 uint32_t sparc_disable_interrupts(void);
     306static inline uint32_t sparc_disable_interrupts(void)
     307{
     308  register uint32_t psr __asm__("g1"); /* return value of trap handler */
     309  __asm__ volatile ( "ta %1\n\t" : "=r" (psr) : "i" (SPARC_SWTRAP_IRQDIS));
     310  return psr;
     311}
    302312
    303313/**
     
    308318 * @param[in] psr is the PSR returned by @ref sparc_disable_interrupts.
    309319 */
    310 void sparc_enable_interrupts(uint32_t psr);
     320static inline void sparc_enable_interrupts(uint32_t psr)
     321{
     322  register uint32_t _psr __asm__("g1") = psr; /* input to trap handler */
     323  __asm__ volatile ( "ta %0\n" :: "i" (SPARC_SWTRAP_IRQEN), "r" (_psr));
     324}
    311325
    312326/**
  • doc/cpu_supplement/sparc.t

    r4081032 rdff1803  
    852852interrupts are fully enabled.  Interrupt requests for interrupts
    853853with priorities less than or equal to the current interrupt mask
    854 level are ignored.
     854level are ignored. Level fifteen (15) is a non-maskable interrupt
     855(NMI), which makes it unsuitable for standard usage since it can
     856affect the real-time behaviour by interrupting critical sections
     857and spinlocks. Disabling traps stops also the NMI interrupt from
     858happening. It can however be used for power-down or other
     859critical events.
    855860
    856861Although RTEMS supports 256 interrupt levels, the
     
    860865unpredictable.
    861866
     867Many LEON SPARC v7/v8 systems features an extended interrupt controller
     868which adds an extra step of interrupt decoding to allow handling of
     869interrupt 16-31. When such an extended interrupt is generated the CPU
     870traps into a specific interrupt trap level 1-14 and software reads out from
     871the interrupt controller which extended interrupt source actually caused the
     872interrupt.
     873
    862874@subsection Disabling of Interrupts by RTEMS
    863875
    864876During the execution of directive calls, critical
    865877sections of code may be executed.  When these sections are
    866 encountered, RTEMS disables interrupts to level seven (15)
    867 before the execution of this section and restores them to the
     878encountered, RTEMS disables interrupts to level fifteen (15)
     879before the execution of the section and restores them to the
    868880previous level upon completion of the section.  RTEMS has been
    869 optimized to insure that interrupts are disabled for less than
     881optimized to ensure that interrupts are disabled for less than
    870882RTEMS_MAXIMUM_DISABLE_PERIOD microseconds on a RTEMS_MAXIMUM_DISABLE_PERIOD_MHZ
    871883Mhz ERC32 with zero wait states.
     
    887899sections.  However, ISRs that make no system calls may safely
    888900execute as non-maskable interrupts.
     901
     902Interrupts are disabled or enabled by performing a system call
     903to the Operating System reserved software traps 9
     904(SPARC_SWTRAP_IRQDIS) or 10 (SPARC_SWTRAP_IRQDIS). The trap is
     905generated by the software trap (Ticc) instruction or indirectly
     906by calling sparc_disable_interrupts() or sparc_enable_interrupts()
     907functions. Disabling interrupts return the previous interrupt level
     908(on trap entry) in register G1 and sets PSR.PIL to 15 to disable
     909all maskable interrupts. The interrupt level can be restored by
     910trapping into the enable interrupt handler with G1 containing the
     911new interrupt level.
    889912
    890913@subsection Interrupt Stack
Note: See TracChangeset for help on using the changeset viewer.