linux/arch/sh/kernel/cpu/sh5/switchto.S
<<
>>
Prefs
   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