root/arch/sh/kernel/cpu/sh5/switchto.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0
   2  *
   3  * arch/sh/kernel/cpu/sh5/switchto.S
   4  *
   5  * sh64 context switch
   6  *
   7  * Copyright (C) 2004  Richard Curnow
   8 */
   9 
  10         .section .text..SHmedia32,"ax"
  11         .little
  12 
  13         .balign 32
  14 
  15         .type sh64_switch_to,@function
  16         .global sh64_switch_to
  17         .global __sh64_switch_to_end
  18 sh64_switch_to:
  19 
  20 /* Incoming args
  21    r2 - prev
  22    r3 - &prev->thread
  23    r4 - next
  24    r5 - &next->thread
  25 
  26    Outgoing results
  27    r2 - last (=prev) : this just stays in r2 throughout
  28 
  29    Want to create a full (struct pt_regs) on the stack to allow backtracing
  30    functions to work.  However, we only need to populate the callee-save
  31    register slots in this structure; since we're a function our ancestors must
  32    have themselves preserved all caller saved state in the stack.  This saves
  33    some wasted effort since we won't need to look at the values.
  34 
  35    In particular, all caller-save registers are immediately available for
  36    scratch use.
  37 
  38 */
  39 
  40 #define FRAME_SIZE (76*8 + 8)
  41 
  42         movi    FRAME_SIZE, r0
  43         sub.l   r15, r0, r15
  44         ! Do normal-style register save to support backtrace
  45 
  46         st.l    r15,   0, r18   ! save link reg
  47         st.l    r15,   4, r14   ! save fp
  48         add.l   r15, r63, r14   ! setup frame pointer
  49 
  50         ! hopefully this looks normal to the backtrace now.
  51 
  52         addi.l  r15,   8, r1    ! base of pt_regs
  53         addi.l  r1,   24, r0    ! base of pt_regs.regs
  54         addi.l  r0, (63*8), r8  ! base of pt_regs.trregs
  55 
  56         /* Note : to be fixed?
  57            struct pt_regs is really designed for holding the state on entry
  58            to an exception, i.e. pc,sr,regs etc.  However, for the context
  59            switch state, some of this is not required.  But the unwinder takes
  60            struct pt_regs * as an arg so we have to build this structure
  61            to allow unwinding switched tasks in show_state() */
  62 
  63         st.q    r0, ( 9*8), r9
  64         st.q    r0, (10*8), r10
  65         st.q    r0, (11*8), r11
  66         st.q    r0, (12*8), r12
  67         st.q    r0, (13*8), r13
  68         st.q    r0, (14*8), r14 ! for unwind, want to look as though we took a trap at
  69         ! the point where the process is left in suspended animation, i.e. current
  70         ! fp here, not the saved one.
  71         st.q    r0, (16*8), r16
  72 
  73         st.q    r0, (24*8), r24
  74         st.q    r0, (25*8), r25
  75         st.q    r0, (26*8), r26
  76         st.q    r0, (27*8), r27
  77         st.q    r0, (28*8), r28
  78         st.q    r0, (29*8), r29
  79         st.q    r0, (30*8), r30
  80         st.q    r0, (31*8), r31
  81         st.q    r0, (32*8), r32
  82         st.q    r0, (33*8), r33
  83         st.q    r0, (34*8), r34
  84         st.q    r0, (35*8), r35
  85 
  86         st.q    r0, (44*8), r44
  87         st.q    r0, (45*8), r45
  88         st.q    r0, (46*8), r46
  89         st.q    r0, (47*8), r47
  90         st.q    r0, (48*8), r48
  91         st.q    r0, (49*8), r49
  92         st.q    r0, (50*8), r50
  93         st.q    r0, (51*8), r51
  94         st.q    r0, (52*8), r52
  95         st.q    r0, (53*8), r53
  96         st.q    r0, (54*8), r54
  97         st.q    r0, (55*8), r55
  98         st.q    r0, (56*8), r56
  99         st.q    r0, (57*8), r57
 100         st.q    r0, (58*8), r58
 101         st.q    r0, (59*8), r59
 102 
 103         ! do this early as pta->gettr has no pipeline forwarding (=> 5 cycle latency)
 104         ! Use a local label to avoid creating a symbol that will confuse the !
 105         ! backtrace
 106         pta     .Lsave_pc, tr0
 107 
 108         gettr   tr5, r45
 109         gettr   tr6, r46
 110         gettr   tr7, r47
 111         st.q    r8, (5*8), r45
 112         st.q    r8, (6*8), r46
 113         st.q    r8, (7*8), r47
 114 
 115         ! Now switch context
 116         gettr   tr0, r9
 117         st.l    r3, 0, r15      ! prev->thread.sp
 118         st.l    r3, 8, r1       ! prev->thread.kregs
 119         st.l    r3, 4, r9       ! prev->thread.pc
 120         st.q    r1, 0, r9       ! save prev->thread.pc into pt_regs->pc
 121 
 122         ! Load PC for next task (init value or save_pc later)
 123         ld.l    r5, 4, r18      ! next->thread.pc
 124         ! Switch stacks
 125         ld.l    r5, 0, r15      ! next->thread.sp
 126         ptabs   r18, tr0
 127 
 128         ! Update current
 129         ld.l    r4, 4, r9       ! next->thread_info (2nd element of next task_struct)
 130         putcon  r9, kcr0        ! current = next->thread_info
 131 
 132         ! go to save_pc for a reschedule, or the initial thread.pc for a new process
 133         blink   tr0, r63
 134 
 135         ! Restore (when we come back to a previously saved task)
 136 .Lsave_pc:
 137         addi.l  r15, 32, r0     ! r0 = next's regs
 138         addi.l  r0, (63*8), r8  ! r8 = next's tr_regs
 139 
 140         ld.q    r8, (5*8), r45
 141         ld.q    r8, (6*8), r46
 142         ld.q    r8, (7*8), r47
 143         ptabs   r45, tr5
 144         ptabs   r46, tr6
 145         ptabs   r47, tr7
 146 
 147         ld.q    r0, ( 9*8), r9
 148         ld.q    r0, (10*8), r10
 149         ld.q    r0, (11*8), r11
 150         ld.q    r0, (12*8), r12
 151         ld.q    r0, (13*8), r13
 152         ld.q    r0, (14*8), r14
 153         ld.q    r0, (16*8), r16
 154 
 155         ld.q    r0, (24*8), r24
 156         ld.q    r0, (25*8), r25
 157         ld.q    r0, (26*8), r26
 158         ld.q    r0, (27*8), r27
 159         ld.q    r0, (28*8), r28
 160         ld.q    r0, (29*8), r29
 161         ld.q    r0, (30*8), r30
 162         ld.q    r0, (31*8), r31
 163         ld.q    r0, (32*8), r32
 164         ld.q    r0, (33*8), r33
 165         ld.q    r0, (34*8), r34
 166         ld.q    r0, (35*8), r35
 167 
 168         ld.q    r0, (44*8), r44
 169         ld.q    r0, (45*8), r45
 170         ld.q    r0, (46*8), r46
 171         ld.q    r0, (47*8), r47
 172         ld.q    r0, (48*8), r48
 173         ld.q    r0, (49*8), r49
 174         ld.q    r0, (50*8), r50
 175         ld.q    r0, (51*8), r51
 176         ld.q    r0, (52*8), r52
 177         ld.q    r0, (53*8), r53
 178         ld.q    r0, (54*8), r54
 179         ld.q    r0, (55*8), r55
 180         ld.q    r0, (56*8), r56
 181         ld.q    r0, (57*8), r57
 182         ld.q    r0, (58*8), r58
 183         ld.q    r0, (59*8), r59
 184 
 185         ! epilogue
 186         ld.l    r15, 0, r18
 187         ld.l    r15, 4, r14
 188         ptabs   r18, tr0
 189         movi    FRAME_SIZE, r0
 190         add     r15, r0, r15
 191         blink   tr0, r63
 192 __sh64_switch_to_end:
 193 .LFE1:
 194         .size   sh64_switch_to,.LFE1-sh64_switch_to
 195 

/* [<][>][^][v][top][bottom][index][help] */