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