Changeset 7c0bd74 in rtems


Ignore:
Timestamp:
Apr 22, 2014, 8:15:39 AM (5 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
8365ad1
Parents:
3fe1e43
git-author:
Sebastian Huber <sebastian.huber@…> (04/22/14 08:15:39)
git-committer:
Sebastian Huber <sebastian.huber@…> (04/28/14 07:26:19)
Message:

sparc: Add _CPU_Get_current_per_CPU_control()

Use register g6 for the per-CPU control of the current processor. The
register g6 is reserved for the operating system by the SPARC ABI. On
Linux register g6 is used for a similar purpose with the same method
since 1996.

The register g6 must be initialized during system startup and then must
remain unchanged.

Since the per-CPU control is used in all critical sections of the
operating system, this is a performance optimization for the operating
system core procedures. An additional benefit is that the low-level
context switch and interrupt processing code is now identical on non-SMP
and SMP configurations.

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/shared/irq_asm.S

    r3fe1e43 r7c0bd74  
    2323#include <rtems/score/percpu.h>
    2424#include <bspopts.h>
    25 
    26 .macro GET_SELF_CPU_CONTROL REG, TMP
    27         sethi    %hi(_Per_CPU_Information), \REG
    28         add      \REG, %lo(_Per_CPU_Information), \REG
    29 
    30 #if defined( RTEMS_SMP )
    31 #if BSP_LEON3_SMP
    32         /* LEON3 SMP support */
    33         rd       %asr17, \TMP
    34         srl      \TMP, LEON3_ASR17_PROCESSOR_INDEX_SHIFT, \TMP
    35 #else
    36         mov      0, \TMP
    37 #endif
    38         sll      \TMP, PER_CPU_CONTROL_SIZE_LOG2, \TMP
    39         add      \REG, \TMP, \REG
    40 #endif /* defined( RTEMS_SMP ) */
    41 .endm
    4225
    4326/*
     
    5437SYM(_CPU_Context_switch):
    5538        st      %g5, [%o0 + G5_OFFSET]       ! save the global registers
    56         std     %g6, [%o0 + G6_OFFSET]
     39        st      %g7, [%o0 + G7_OFFSET]
    5740
    5841        std     %l0, [%o0 + L0_OFFSET]       ! save the local registers
     
    6851        std     %o6, [%o0 + O6_SP_OFFSET]    ! save the output registers
    6952
    70         ! o3 = self per-CPU control
    71         GET_SELF_CPU_CONTROL %o3, %o4
    72 
    7353        ! load the ISR stack nesting prevention flag
    74         ld      [%o3 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE], %o4
     54        ld      [%g6 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE], %o4
    7555        ! save it a bit later so we do not waste a couple of cycles
    7656
     
    8565         *    o1 = context to restore
    8666         *    o2 = psr
    87          *    o3 = self per-CPU control
    8867         */
    8968
     
    186165
    187166        ld      [%o1 + G5_OFFSET], %g5        ! restore the global registers
    188         ldd     [%o1 + G6_OFFSET], %g6
     167        ld      [%o1 + G7_OFFSET], %g7
    189168
    190169        ! Load thread specific ISR dispatch prevention flag
     
    198177
    199178        ! Now restore thread specific ISR dispatch prevention flag
    200         st      %o2, [%o3 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE]
     179        st      %o2, [%g6 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE]
    201180
    202181        ldd     [%o1 + I0_OFFSET], %i0        ! restore the input registers
     
    224203        save    %sp, -CPU_MINIMUM_STACK_FRAME_SIZE, %sp
    225204        rd      %psr, %o2
    226         GET_SELF_CPU_CONTROL %o3, %o4
    227205        ba      SYM(_CPU_Context_restore_heir)
    228206        mov     %i0, %o1                      ! in the delay slot
     
    353331        std     %g2, [%sp + ISF_G2_OFFSET]     ! save g2, g3
    354332        std     %l4, [%sp + ISF_G4_OFFSET]     ! save g4, g5 -- see above
    355         std     %g6, [%sp + ISF_G6_OFFSET]     ! save g6, g7
     333        st      %g7, [%sp + ISF_G7_OFFSET]     ! save g7
    356334
    357335        std     %i0, [%sp + ISF_I0_OFFSET]     ! save i0, i1
     
    371349         *  Register usage for this section:
    372350         *
    373          *    l5 = per cpu info pointer
    374351         *    l6 = _Thread_Dispatch_disable_level value
    375352         *    l7 = _ISR_Nest_level value
    376353         *
    377          *  NOTE: It is assumed that l5 - l7 will be preserved until the ISR
     354         *  NOTE: It is assumed that l6 - l7 will be preserved until the ISR
    378355         *        nest and thread dispatch disable levels are unnested.
    379356         */
    380357
    381         GET_SELF_CPU_CONTROL %l5, %l7
    382 
    383         ld       [%l5 + PER_CPU_ISR_NEST_LEVEL], %l7
    384         ld       [%l5 + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL], %l6
     358        ld       [%g6 + PER_CPU_ISR_NEST_LEVEL], %l7
     359        ld       [%g6 + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL], %l6
    385360
    386361        add      %l7, 1, %l7
    387         st       %l7, [%l5 + PER_CPU_ISR_NEST_LEVEL]
     362        st       %l7, [%g6 + PER_CPU_ISR_NEST_LEVEL]
    388363
    389364        add      %l6, 1, %l6
    390         st       %l6, [%l5 + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
     365        st       %l6, [%g6 + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
    391366
    392367        /*
     
    406381#endif
    407382
    408         ld       [%l5 + PER_CPU_INTERRUPT_STACK_HIGH], %sp
     383        ld       [%g6 + PER_CPU_INTERRUPT_STACK_HIGH], %sp
    409384
    410385dont_switch_stacks:
     
    469444        mov      %l3, %o1               ! o1 = 2nd arg = interrupt entry instant
    470445        call     SYM(_Profiling_Outer_most_interrupt_entry_and_exit), 0
    471          mov     %l5, %o0               ! o0 = 1st arg = per-CPU control
     446         mov     %g6, %o0               ! o0 = 1st arg = per-CPU control
    472447profiling_not_outer_most_exit:
    473448#else
     
    490465         *  Register usage for this section:
    491466         *
    492          *    l5 = per cpu info pointer
    493467         *    l6 = _Thread_Dispatch_disable_level value
    494468         *    l7 = _ISR_Nest_level value
    495469         */
    496470
    497         st       %l7, [%l5 + PER_CPU_ISR_NEST_LEVEL]
     471        st       %l7, [%g6 + PER_CPU_ISR_NEST_LEVEL]
    498472
    499473        sub      %l6, 1, %l6
    500         st       %l6, [%l5 + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
     474        st       %l6, [%g6 + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL]
    501475
    502476        /*
     
    510484
    511485        ! Are we dispatching from a previous ISR in the interrupted thread?
    512         ld       [%l5 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE], %l7
     486        ld       [%g6 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE], %l7
    513487        orcc     %l7, %g0, %g0   ! Is this thread already doing an ISR?
    514488        bnz      simple_return   ! Yes, then do a "simple" exit
     
    521495         */
    522496
    523         ldub     [%l5 + PER_CPU_DISPATCH_NEEDED], %l6
     497        ldub     [%g6 + PER_CPU_DISPATCH_NEEDED], %l6
    524498
    525499        orcc     %l6, %g0, %g0   ! Is thread switch necessary?
     
    533507        ! Set ISR dispatch nesting prevention flag
    534508        mov      1,%l6
    535         st       %l6, [%l5 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE]
     509        st       %l6, [%g6 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE]
    536510
    537511        /*
     
    570544         */
    571545
    572         GET_SELF_CPU_CONTROL %l5, %l7
    573 
    574         ldub     [%l5 + PER_CPU_DISPATCH_NEEDED], %l7
     546        ldub     [%g6 + PER_CPU_DISPATCH_NEEDED], %l7
    575547
    576548        orcc     %l7, %g0, %g0    ! Is thread switch necesary?
     
    588560
    589561        ! Zero out ISR stack nesting prevention flag
    590         st       %g0, [%l5 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE]
     562        st       %g0, [%g6 + SPARC_PER_CPU_ISR_DISPATCH_DISABLE]
    591563
    592564        /*
     
    620592        ldd     [%fp + ISF_G2_OFFSET], %g2    ! restore g2, g3
    621593        ldd     [%fp + ISF_G4_OFFSET], %g4    ! restore g4, g5
    622         ldd     [%fp + ISF_G6_OFFSET], %g6    ! restore g6, g7
     594        ld      [%fp + ISF_G7_OFFSET], %g7    ! restore g7
    623595
    624596        ldd     [%fp + ISF_I0_OFFSET], %i0    ! restore i0, i1
  • c/src/lib/libbsp/sparc/shared/start/start.S

    r3fe1e43 r7c0bd74  
    223223        nop
    224224
     225        sethi   %hi(_Per_CPU_Information), %g6 ! get per-CPU control
     226        add     %g6, %lo(_Per_CPU_Information), %g6
     227
    225228#if defined(START_LEON3_ENABLE_SMP)
    226229        rd      %asr17, %o0             ! get CPU identifier
     
    231234         nop
    232235
    233         sethi   %hi(_Per_CPU_Information), %o1 ! get per-CPU control
    234         add     %o1, %lo(_Per_CPU_Information), %o1
    235         sll     %o0, PER_CPU_CONTROL_SIZE_LOG2, %o2
    236         add     %o1, %o2, %o1
    237 
    238         ld      [%o1 + PER_CPU_INTERRUPT_STACK_HIGH], %sp ! set stack pointer
     236        sll     %o0, PER_CPU_CONTROL_SIZE_LOG2, %l0
     237        add     %g6, %l0, %g6
     238
     239        ld      [%g6 + PER_CPU_INTERRUPT_STACK_HIGH], %sp ! set stack pointer
    239240        sub     %sp, 4, %sp             ! stack starts at end of area - 4
    240241        andn    %sp, 0x0f, %sp          ! align stack on 16-byte boundary
     
    248249#endif
    249250
    250         set     (SYM(rdb_start)), %g6   ! End of RAM
    251         st      %sp, [%g6]
     251        set     (SYM(rdb_start)), %g5   ! End of RAM
     252        st      %sp, [%g5]
    252253        sub     %sp, 4, %sp             ! stack starts at end of RAM - 4
    253254        andn    %sp, 0x0f, %sp          ! align stack on 16-byte boundary
     
    301302        set     SYM(RAM_SIZE), %l2
    302303        add     %l1, %l2, %sp
    303         st      %sp, [%g6]
    304 
    305 
    306         set     SYM(CLOCK_SPEED), %g6   ! Use 14 MHz in simulator
     304        st      %sp, [%g5]
     305
     306
     307        set     SYM(CLOCK_SPEED), %g5   ! Use 14 MHz in simulator
    307308        set     14, %g1
    308         st      %g1, [%g6]
     309        st      %g1, [%g5]
    309310
    3103112:
     
    333334
    334335copy_data:
    335         ldd   [ %g2 ], %g6
    336         std   %g6 , [ %g3 ]             ! copy this double word
     336        ldd   [ %g2 ], %g5
     337        std   %g5 , [ %g3 ]             ! copy this double word
    337338        add   %g3, 8, %g3               ! bump the destination pointer
    338339        add   %g2, 8, %g2               ! bump the source pointer
  • cpukit/score/cpu/sparc/cpu.c

    r3fe1e43 r7c0bd74  
    3737
    3838SPARC_ASSERT_OFFSET(g5, G5);
    39 SPARC_ASSERT_OFFSET(g6, G6);
    4039SPARC_ASSERT_OFFSET(g7, G7);
    4140
  • cpukit/score/cpu/sparc/rtems/score/cpu.h

    r3fe1e43 r7c0bd74  
    409409 * volatile registers by default.  So they are treated like volatile registers
    410410 * in RTEMS as well.
     411 *
     412 * The register g6 contains the per-CPU control of the current processor.  It
     413 * is an invariant of the processor context.  This register must not be saved
     414 * and restored during context switches or interrupt services.
    411415 */
    412416typedef struct {
    413   /** This will contain reserved space for alignment. */
    414   uint32_t   reserved_for_alignment;
    415417  /** This will contain the contents of the g5 register. */
    416418  uint32_t   g5;
    417   /** This will contain the contents of the g6 register. */
    418   uint32_t   g6;
    419419  /** This will contain the contents of the g7 register. */
    420420  uint32_t   g7;
     
    491491
    492492/** This macro defines an offset into the context for use in assembly. */
    493 #define G5_OFFSET    0x04
    494 /** This macro defines an offset into the context for use in assembly. */
    495 #define G6_OFFSET    0x08
    496 /** This macro defines an offset into the context for use in assembly. */
    497 #define G7_OFFSET    0x0C
    498 
    499 /** This macro defines an offset into the context for use in assembly. */
    500 #define L0_OFFSET    0x10
    501 /** This macro defines an offset into the context for use in assembly. */
    502 #define L1_OFFSET    0x14
    503 /** This macro defines an offset into the context for use in assembly. */
    504 #define L2_OFFSET    0x18
    505 /** This macro defines an offset into the context for use in assembly. */
    506 #define L3_OFFSET    0x1C
    507 /** This macro defines an offset into the context for use in assembly. */
    508 #define L4_OFFSET    0x20
    509 /** This macro defines an offset into the context for use in assembly. */
    510 #define L5_OFFSET    0x24
    511 /** This macro defines an offset into the context for use in assembly. */
    512 #define L6_OFFSET    0x28
    513 /** This macro defines an offset into the context for use in assembly. */
    514 #define L7_OFFSET    0x2C
    515 
    516 /** This macro defines an offset into the context for use in assembly. */
    517 #define I0_OFFSET    0x30
    518 /** This macro defines an offset into the context for use in assembly. */
    519 #define I1_OFFSET    0x34
    520 /** This macro defines an offset into the context for use in assembly. */
    521 #define I2_OFFSET    0x38
    522 /** This macro defines an offset into the context for use in assembly. */
    523 #define I3_OFFSET    0x3C
    524 /** This macro defines an offset into the context for use in assembly. */
    525 #define I4_OFFSET    0x40
    526 /** This macro defines an offset into the context for use in assembly. */
    527 #define I5_OFFSET    0x44
    528 /** This macro defines an offset into the context for use in assembly. */
    529 #define I6_FP_OFFSET 0x48
    530 /** This macro defines an offset into the context for use in assembly. */
    531 #define I7_OFFSET    0x4C
    532 
    533 /** This macro defines an offset into the context for use in assembly. */
    534 #define O6_SP_OFFSET 0x50
    535 /** This macro defines an offset into the context for use in assembly. */
    536 #define O7_OFFSET    0x54
    537 
    538 /** This macro defines an offset into the context for use in assembly. */
    539 #define PSR_OFFSET   0x58
    540 /** This macro defines an offset into the context for use in assembly. */
    541 #define ISR_DISPATCH_DISABLE_STACK_OFFSET 0x5C
     493#define G5_OFFSET    0x00
     494/** This macro defines an offset into the context for use in assembly. */
     495#define G7_OFFSET    0x04
     496
     497/** This macro defines an offset into the context for use in assembly. */
     498#define L0_OFFSET    0x08
     499/** This macro defines an offset into the context for use in assembly. */
     500#define L1_OFFSET    0x0C
     501/** This macro defines an offset into the context for use in assembly. */
     502#define L2_OFFSET    0x10
     503/** This macro defines an offset into the context for use in assembly. */
     504#define L3_OFFSET    0x14
     505/** This macro defines an offset into the context for use in assembly. */
     506#define L4_OFFSET    0x18
     507/** This macro defines an offset into the context for use in assembly. */
     508#define L5_OFFSET    0x1C
     509/** This macro defines an offset into the context for use in assembly. */
     510#define L6_OFFSET    0x20
     511/** This macro defines an offset into the context for use in assembly. */
     512#define L7_OFFSET    0x24
     513
     514/** This macro defines an offset into the context for use in assembly. */
     515#define I0_OFFSET    0x28
     516/** This macro defines an offset into the context for use in assembly. */
     517#define I1_OFFSET    0x2C
     518/** This macro defines an offset into the context for use in assembly. */
     519#define I2_OFFSET    0x30
     520/** This macro defines an offset into the context for use in assembly. */
     521#define I3_OFFSET    0x34
     522/** This macro defines an offset into the context for use in assembly. */
     523#define I4_OFFSET    0x38
     524/** This macro defines an offset into the context for use in assembly. */
     525#define I5_OFFSET    0x3C
     526/** This macro defines an offset into the context for use in assembly. */
     527#define I6_FP_OFFSET 0x40
     528/** This macro defines an offset into the context for use in assembly. */
     529#define I7_OFFSET    0x44
     530
     531/** This macro defines an offset into the context for use in assembly. */
     532#define O6_SP_OFFSET 0x48
     533/** This macro defines an offset into the context for use in assembly. */
     534#define O7_OFFSET    0x4C
     535
     536/** This macro defines an offset into the context for use in assembly. */
     537#define PSR_OFFSET   0x50
     538/** This macro defines an offset into the context for use in assembly. */
     539#define ISR_DISPATCH_DISABLE_STACK_OFFSET 0x54
    542540
    543541/** This defines the size of the context area for use in assembly. */
     
    662660  /** This is the offset of the g5 register on an ISF. */
    663661  uint32_t                 g5;
    664   /** This is the offset of the g6 register on an ISF. */
    665   uint32_t                 g6;
     662  /** This is the offset is reserved for alignment on an ISF. */
     663  uint32_t                 reserved_for_alignment;
    666664  /** This is the offset of the g7 register on an ISF. */
    667665  uint32_t                 g7;
     
    713711#define ISF_G5_OFFSET          CPU_MINIMUM_STACK_FRAME_SIZE + 0x1c
    714712/** This macro defines an offset into the ISF for use in assembly. */
    715 #define ISF_G6_OFFSET          CPU_MINIMUM_STACK_FRAME_SIZE + 0x20
    716 /** This macro defines an offset into the ISF for use in assembly. */
    717713#define ISF_G7_OFFSET          CPU_MINIMUM_STACK_FRAME_SIZE + 0x24
    718714/** This macro defines an offset into the ISF for use in assembly. */
     
    11571153) RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
    11581154
     1155/**
     1156 * @brief The pointer to the current per-CPU control is available via register
     1157 * g6.
     1158 */
     1159register struct Per_CPU_Control *_SPARC_Per_CPU_current asm( "g6" );
     1160
     1161#define _CPU_Get_current_per_CPU_control() ( _SPARC_Per_CPU_current )
     1162
    11591163#if defined(RTEMS_SMP)
    11601164  uint32_t _CPU_SMP_Initialize( void );
  • doc/cpu_supplement/sparc.t

    r3fe1e43 r7c0bd74  
    402402RTEMS as well.
    403403
     404The register g6 is reserved for the operating system and contains the address
     405of the per-CPU control block of the current processor.  This register is
     406initialized during system start and then remains unchanged.  It is not
     407saved/restored by the context switch or interrupt processing code.
     408
    404409The register g7 is reserved for the operating system and contains the thread
    405410pointer used for thread-local storage (TLS) as mandated by the SPARC ABI.
Note: See TracChangeset for help on using the changeset viewer.