Changeset 78cac9b in rtems


Ignore:
Timestamp:
Nov 16, 2015, 1:13:28 PM (4 years ago)
Author:
Daniel Cederman <cederman@…>
Branches:
master
Children:
836803f
Parents:
06ef76e3
git-author:
Daniel Cederman <cederman@…> (11/16/15 13:13:28)
git-committer:
Sebastian Huber <sebastian.huber@…> (11/16/15 13:48:54)
Message:

sparc: Fix context switch on SMP

We must not load registers (e.g. PSR) from the heir context area before
the heir stopped execution.

With this patch the write to PSR is divided into two steps. We first update
the current window pointer and then we restore the status registers and
enable traps. This allows us to move the first write to PSR to be before
the write to WIM, as there is now no risk that we get an interrupt where
the CWP and WIM would be inconsistent. We only need to make sure that we
do not use any of the non-global registers or instructions that affects
CWP for three instructions after the write.

In the earlier code the non-global %o1 register was used right after the
write to PSR, which required the use of three nop:s.

Files:
2 edited

Legend:

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

    r06ef76e3 r78cac9b  
    128128         */
    129129
    130         ld      [%o1 + PSR_OFFSET], %g1       ! g1 = saved psr
    131 
    132130        and     %o2, SPARC_PSR_CWP_MASK, %g3  ! g3 = CWP
    133                                               ! g1 = psr w/o cwp
    134         andn    %g1, SPARC_PSR_ET_MASK | SPARC_PSR_CWP_MASK, %g1
    135         or      %g1, %g3, %g1                 ! g1 = heirs psr
    136         mov     %g1, %psr                     ! restore status register and
    137                                               ! **** DISABLE TRAPS ****
     131        andn    %o2, SPARC_PSR_ET_MASK, %g1   ! g1 = psr with traps disabled
     132        mov     %g1, %psr                     ! **** DISABLE TRAPS ****
    138133        mov     %wim, %g2                     ! g2 = wim
    139134        mov     1, %g4
     
    174169done_flushing:
    175170
    176         add     %g3, 1, %g3                   ! calculate desired WIM
    177         and     %g3, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g3
     171        ! Wait three instructions after the write to PSR before using
     172        ! non-global registers or instructions affecting the CWP
     173        mov     %g1, %psr                     ! restore cwp
     174        add     %g3, 1, %g2                   ! calculate desired WIM
     175        and     %g2, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g2
    178176        mov     1, %g4
    179         sll     %g4, %g3, %g4                 ! g4 = new WIM
     177        sll     %g4, %g2, %g4                 ! g4 = new WIM
    180178        mov     %g4, %wim
    181 
    182         or      %g1, SPARC_PSR_ET_MASK, %g1
    183         mov     %g1, %psr                     ! **** ENABLE TRAPS ****
    184                                               !   and restore CWP
    185         nop
    186         nop
    187         nop
    188179
    189180#if defined(RTEMS_SMP)
     
    202193        ! The next load is in a delay slot, which is all right
    203194#endif
     195
     196        ld      [%o1 + PSR_OFFSET], %g1       ! g1 = heir psr with traps enabled
     197        andn    %g1, SPARC_PSR_CWP_MASK, %g1  ! g1 = heir psr w/o cwp
     198        or      %g1, %g3, %g1                 ! g1 = heir psr with cwp
     199        mov     %g1, %psr                     ! restore status register and
     200                                              ! **** ENABLE TRAPS ****
    204201
    205202        ld      [%o1 + G5_OFFSET], %g5        ! restore the global registers
  • cpukit/score/cpu/sparc/cpu.c

    r06ef76e3 r78cac9b  
    357357    tmp_psr &= ~SPARC_PSR_EF_MASK;      /* disabled by default */
    358358
     359    /* _CPU_Context_restore_heir() relies on this */
     360    _Assert( ( tmp_psr & SPARC_PSR_ET_MASK ) != 0 );
     361
    359362#if (SPARC_HAS_FPU == 1)
    360363    /*
Note: See TracChangeset for help on using the changeset viewer.