~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/sh/kernel/cpu/sh5/switchto.S

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
21
sh64_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