Path: blob/master/arch/sh/kernel/cpu/sh5/switchto.S
17372 views
/*1* arch/sh/kernel/cpu/sh5/switchto.S2*3* sh64 context switch4*5* Copyright (C) 2004 Richard Curnow6*7* This file is subject to the terms and conditions of the GNU General Public8* License. See the file "COPYING" in the main directory of this archive9* for more details.10*/1112.section .text..SHmedia32,"ax"13.little1415.balign 321617.type sh64_switch_to,@function18.global sh64_switch_to19.global __sh64_switch_to_end20sh64_switch_to:2122/* Incoming args23r2 - prev24r3 - &prev->thread25r4 - next26r5 - &next->thread2728Outgoing results29r2 - last (=prev) : this just stays in r2 throughout3031Want to create a full (struct pt_regs) on the stack to allow backtracing32functions to work. However, we only need to populate the callee-save33register slots in this structure; since we're a function our ancestors must34have themselves preserved all caller saved state in the stack. This saves35some wasted effort since we won't need to look at the values.3637In particular, all caller-save registers are immediately available for38scratch use.3940*/4142#define FRAME_SIZE (76*8 + 8)4344movi FRAME_SIZE, r045sub.l r15, r0, r1546! Do normal-style register save to support backtrace4748st.l r15, 0, r18 ! save link reg49st.l r15, 4, r14 ! save fp50add.l r15, r63, r14 ! setup frame pointer5152! hopefully this looks normal to the backtrace now.5354addi.l r15, 8, r1 ! base of pt_regs55addi.l r1, 24, r0 ! base of pt_regs.regs56addi.l r0, (63*8), r8 ! base of pt_regs.trregs5758/* Note : to be fixed?59struct pt_regs is really designed for holding the state on entry60to an exception, i.e. pc,sr,regs etc. However, for the context61switch state, some of this is not required. But the unwinder takes62struct pt_regs * as an arg so we have to build this structure63to allow unwinding switched tasks in show_state() */6465st.q r0, ( 9*8), r966st.q r0, (10*8), r1067st.q r0, (11*8), r1168st.q r0, (12*8), r1269st.q r0, (13*8), r1370st.q r0, (14*8), r14 ! for unwind, want to look as though we took a trap at71! the point where the process is left in suspended animation, i.e. current72! fp here, not the saved one.73st.q r0, (16*8), r167475st.q r0, (24*8), r2476st.q r0, (25*8), r2577st.q r0, (26*8), r2678st.q r0, (27*8), r2779st.q r0, (28*8), r2880st.q r0, (29*8), r2981st.q r0, (30*8), r3082st.q r0, (31*8), r3183st.q r0, (32*8), r3284st.q r0, (33*8), r3385st.q r0, (34*8), r3486st.q r0, (35*8), r358788st.q r0, (44*8), r4489st.q r0, (45*8), r4590st.q r0, (46*8), r4691st.q r0, (47*8), r4792st.q r0, (48*8), r4893st.q r0, (49*8), r4994st.q r0, (50*8), r5095st.q r0, (51*8), r5196st.q r0, (52*8), r5297st.q r0, (53*8), r5398st.q r0, (54*8), r5499st.q r0, (55*8), r55100st.q r0, (56*8), r56101st.q r0, (57*8), r57102st.q r0, (58*8), r58103st.q r0, (59*8), r59104105! do this early as pta->gettr has no pipeline forwarding (=> 5 cycle latency)106! Use a local label to avoid creating a symbol that will confuse the !107! backtrace108pta .Lsave_pc, tr0109110gettr tr5, r45111gettr tr6, r46112gettr tr7, r47113st.q r8, (5*8), r45114st.q r8, (6*8), r46115st.q r8, (7*8), r47116117! Now switch context118gettr tr0, r9119st.l r3, 0, r15 ! prev->thread.sp120st.l r3, 8, r1 ! prev->thread.kregs121st.l r3, 4, r9 ! prev->thread.pc122st.q r1, 0, r9 ! save prev->thread.pc into pt_regs->pc123124! Load PC for next task (init value or save_pc later)125ld.l r5, 4, r18 ! next->thread.pc126! Switch stacks127ld.l r5, 0, r15 ! next->thread.sp128ptabs r18, tr0129130! Update current131ld.l r4, 4, r9 ! next->thread_info (2nd element of next task_struct)132putcon r9, kcr0 ! current = next->thread_info133134! go to save_pc for a reschedule, or the initial thread.pc for a new process135blink tr0, r63136137! Restore (when we come back to a previously saved task)138.Lsave_pc:139addi.l r15, 32, r0 ! r0 = next's regs140addi.l r0, (63*8), r8 ! r8 = next's tr_regs141142ld.q r8, (5*8), r45143ld.q r8, (6*8), r46144ld.q r8, (7*8), r47145ptabs r45, tr5146ptabs r46, tr6147ptabs r47, tr7148149ld.q r0, ( 9*8), r9150ld.q r0, (10*8), r10151ld.q r0, (11*8), r11152ld.q r0, (12*8), r12153ld.q r0, (13*8), r13154ld.q r0, (14*8), r14155ld.q r0, (16*8), r16156157ld.q r0, (24*8), r24158ld.q r0, (25*8), r25159ld.q r0, (26*8), r26160ld.q r0, (27*8), r27161ld.q r0, (28*8), r28162ld.q r0, (29*8), r29163ld.q r0, (30*8), r30164ld.q r0, (31*8), r31165ld.q r0, (32*8), r32166ld.q r0, (33*8), r33167ld.q r0, (34*8), r34168ld.q r0, (35*8), r35169170ld.q r0, (44*8), r44171ld.q r0, (45*8), r45172ld.q r0, (46*8), r46173ld.q r0, (47*8), r47174ld.q r0, (48*8), r48175ld.q r0, (49*8), r49176ld.q r0, (50*8), r50177ld.q r0, (51*8), r51178ld.q r0, (52*8), r52179ld.q r0, (53*8), r53180ld.q r0, (54*8), r54181ld.q r0, (55*8), r55182ld.q r0, (56*8), r56183ld.q r0, (57*8), r57184ld.q r0, (58*8), r58185ld.q r0, (59*8), r59186187! epilogue188ld.l r15, 0, r18189ld.l r15, 4, r14190ptabs r18, tr0191movi FRAME_SIZE, r0192add r15, r0, r15193blink tr0, r63194__sh64_switch_to_end:195.LFE1:196.size sh64_switch_to,.LFE1-sh64_switch_to197198199200