Commit ce0ac1fc326b6a4116728be933ff46d75269baa1

Authored by Michael Neuling
Committed by Benjamin Herrenschmidt
1 parent fb5153d05a

powerpc/tm: Remove unnecessary r1 save

We save r1 to the scratch SPR and restore it from there after the trechkpt so
saving r1 to the paca is not needed.

Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Showing 1 changed file with 0 additions and 2 deletions Inline Diff

arch/powerpc/kernel/tm.S
1 /* 1 /*
2 * Transactional memory support routines to reclaim and recheckpoint 2 * Transactional memory support routines to reclaim and recheckpoint
3 * transactional process state. 3 * transactional process state.
4 * 4 *
5 * Copyright 2012 Matt Evans & Michael Neuling, IBM Corporation. 5 * Copyright 2012 Matt Evans & Michael Neuling, IBM Corporation.
6 */ 6 */
7 7
8 #include <asm/asm-offsets.h> 8 #include <asm/asm-offsets.h>
9 #include <asm/ppc_asm.h> 9 #include <asm/ppc_asm.h>
10 #include <asm/ppc-opcode.h> 10 #include <asm/ppc-opcode.h>
11 #include <asm/ptrace.h> 11 #include <asm/ptrace.h>
12 #include <asm/reg.h> 12 #include <asm/reg.h>
13 13
14 #ifdef CONFIG_VSX 14 #ifdef CONFIG_VSX
15 /* See fpu.S, this is borrowed from there */ 15 /* See fpu.S, this is borrowed from there */
16 #define __SAVE_32FPRS_VSRS(n,c,base) \ 16 #define __SAVE_32FPRS_VSRS(n,c,base) \
17 BEGIN_FTR_SECTION \ 17 BEGIN_FTR_SECTION \
18 b 2f; \ 18 b 2f; \
19 END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ 19 END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
20 SAVE_32FPRS(n,base); \ 20 SAVE_32FPRS(n,base); \
21 b 3f; \ 21 b 3f; \
22 2: SAVE_32VSRS(n,c,base); \ 22 2: SAVE_32VSRS(n,c,base); \
23 3: 23 3:
24 #define __REST_32FPRS_VSRS(n,c,base) \ 24 #define __REST_32FPRS_VSRS(n,c,base) \
25 BEGIN_FTR_SECTION \ 25 BEGIN_FTR_SECTION \
26 b 2f; \ 26 b 2f; \
27 END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ 27 END_FTR_SECTION_IFSET(CPU_FTR_VSX); \
28 REST_32FPRS(n,base); \ 28 REST_32FPRS(n,base); \
29 b 3f; \ 29 b 3f; \
30 2: REST_32VSRS(n,c,base); \ 30 2: REST_32VSRS(n,c,base); \
31 3: 31 3:
32 #else 32 #else
33 #define __SAVE_32FPRS_VSRS(n,c,base) SAVE_32FPRS(n, base) 33 #define __SAVE_32FPRS_VSRS(n,c,base) SAVE_32FPRS(n, base)
34 #define __REST_32FPRS_VSRS(n,c,base) REST_32FPRS(n, base) 34 #define __REST_32FPRS_VSRS(n,c,base) REST_32FPRS(n, base)
35 #endif 35 #endif
36 #define SAVE_32FPRS_VSRS(n,c,base) \ 36 #define SAVE_32FPRS_VSRS(n,c,base) \
37 __SAVE_32FPRS_VSRS(n,__REG_##c,__REG_##base) 37 __SAVE_32FPRS_VSRS(n,__REG_##c,__REG_##base)
38 #define REST_32FPRS_VSRS(n,c,base) \ 38 #define REST_32FPRS_VSRS(n,c,base) \
39 __REST_32FPRS_VSRS(n,__REG_##c,__REG_##base) 39 __REST_32FPRS_VSRS(n,__REG_##c,__REG_##base)
40 40
41 /* Stack frame offsets for local variables. */ 41 /* Stack frame offsets for local variables. */
42 #define TM_FRAME_L0 TM_FRAME_SIZE-16 42 #define TM_FRAME_L0 TM_FRAME_SIZE-16
43 #define TM_FRAME_L1 TM_FRAME_SIZE-8 43 #define TM_FRAME_L1 TM_FRAME_SIZE-8
44 #define STACK_PARAM(x) (48+((x)*8)) 44 #define STACK_PARAM(x) (48+((x)*8))
45 45
46 46
47 /* In order to access the TM SPRs, TM must be enabled. So, do so: */ 47 /* In order to access the TM SPRs, TM must be enabled. So, do so: */
48 _GLOBAL(tm_enable) 48 _GLOBAL(tm_enable)
49 mfmsr r4 49 mfmsr r4
50 li r3, MSR_TM >> 32 50 li r3, MSR_TM >> 32
51 sldi r3, r3, 32 51 sldi r3, r3, 32
52 and. r0, r4, r3 52 and. r0, r4, r3
53 bne 1f 53 bne 1f
54 or r4, r4, r3 54 or r4, r4, r3
55 mtmsrd r4 55 mtmsrd r4
56 1: blr 56 1: blr
57 57
58 _GLOBAL(tm_save_sprs) 58 _GLOBAL(tm_save_sprs)
59 mfspr r0, SPRN_TFHAR 59 mfspr r0, SPRN_TFHAR
60 std r0, THREAD_TM_TFHAR(r3) 60 std r0, THREAD_TM_TFHAR(r3)
61 mfspr r0, SPRN_TEXASR 61 mfspr r0, SPRN_TEXASR
62 std r0, THREAD_TM_TEXASR(r3) 62 std r0, THREAD_TM_TEXASR(r3)
63 mfspr r0, SPRN_TFIAR 63 mfspr r0, SPRN_TFIAR
64 std r0, THREAD_TM_TFIAR(r3) 64 std r0, THREAD_TM_TFIAR(r3)
65 blr 65 blr
66 66
67 _GLOBAL(tm_restore_sprs) 67 _GLOBAL(tm_restore_sprs)
68 ld r0, THREAD_TM_TFHAR(r3) 68 ld r0, THREAD_TM_TFHAR(r3)
69 mtspr SPRN_TFHAR, r0 69 mtspr SPRN_TFHAR, r0
70 ld r0, THREAD_TM_TEXASR(r3) 70 ld r0, THREAD_TM_TEXASR(r3)
71 mtspr SPRN_TEXASR, r0 71 mtspr SPRN_TEXASR, r0
72 ld r0, THREAD_TM_TFIAR(r3) 72 ld r0, THREAD_TM_TFIAR(r3)
73 mtspr SPRN_TFIAR, r0 73 mtspr SPRN_TFIAR, r0
74 blr 74 blr
75 75
76 /* Passed an 8-bit failure cause as first argument. */ 76 /* Passed an 8-bit failure cause as first argument. */
77 _GLOBAL(tm_abort) 77 _GLOBAL(tm_abort)
78 TABORT(R3) 78 TABORT(R3)
79 blr 79 blr
80 80
81 .section ".toc","aw" 81 .section ".toc","aw"
82 DSCR_DEFAULT: 82 DSCR_DEFAULT:
83 .tc dscr_default[TC],dscr_default 83 .tc dscr_default[TC],dscr_default
84 84
85 .section ".text" 85 .section ".text"
86 86
87 /* void tm_reclaim(struct thread_struct *thread, 87 /* void tm_reclaim(struct thread_struct *thread,
88 * unsigned long orig_msr, 88 * unsigned long orig_msr,
89 * uint8_t cause) 89 * uint8_t cause)
90 * 90 *
91 * - Performs a full reclaim. This destroys outstanding 91 * - Performs a full reclaim. This destroys outstanding
92 * transactions and updates thread->regs.tm_ckpt_* with the 92 * transactions and updates thread->regs.tm_ckpt_* with the
93 * original checkpointed state. Note that thread->regs is 93 * original checkpointed state. Note that thread->regs is
94 * unchanged. 94 * unchanged.
95 * - FP regs are written back to thread->transact_fpr before 95 * - FP regs are written back to thread->transact_fpr before
96 * reclaiming. These are the transactional (current) versions. 96 * reclaiming. These are the transactional (current) versions.
97 * 97 *
98 * Purpose is to both abort transactions of, and preserve the state of, 98 * Purpose is to both abort transactions of, and preserve the state of,
99 * a transactions at a context switch. We preserve/restore both sets of process 99 * a transactions at a context switch. We preserve/restore both sets of process
100 * state to restore them when the thread's scheduled again. We continue in 100 * state to restore them when the thread's scheduled again. We continue in
101 * userland as though nothing happened, but when the transaction is resumed 101 * userland as though nothing happened, but when the transaction is resumed
102 * they will abort back to the checkpointed state we save out here. 102 * they will abort back to the checkpointed state we save out here.
103 * 103 *
104 * Call with IRQs off, stacks get all out of sync for some periods in here! 104 * Call with IRQs off, stacks get all out of sync for some periods in here!
105 */ 105 */
106 _GLOBAL(tm_reclaim) 106 _GLOBAL(tm_reclaim)
107 mfcr r6 107 mfcr r6
108 mflr r0 108 mflr r0
109 stw r6, 8(r1) 109 stw r6, 8(r1)
110 std r0, 16(r1) 110 std r0, 16(r1)
111 std r2, 40(r1) 111 std r2, 40(r1)
112 stdu r1, -TM_FRAME_SIZE(r1) 112 stdu r1, -TM_FRAME_SIZE(r1)
113 113
114 /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD]. */ 114 /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD]. */
115 115
116 std r3, STACK_PARAM(0)(r1) 116 std r3, STACK_PARAM(0)(r1)
117 SAVE_NVGPRS(r1) 117 SAVE_NVGPRS(r1)
118 118
119 /* We need to setup MSR for VSX register save instructions. Here we 119 /* We need to setup MSR for VSX register save instructions. Here we
120 * also clear the MSR RI since when we do the treclaim, we won't have a 120 * also clear the MSR RI since when we do the treclaim, we won't have a
121 * valid kernel pointer for a while. We clear RI here as it avoids 121 * valid kernel pointer for a while. We clear RI here as it avoids
122 * adding another mtmsr closer to the treclaim. This makes the region 122 * adding another mtmsr closer to the treclaim. This makes the region
123 * maked as non-recoverable wider than it needs to be but it saves on 123 * maked as non-recoverable wider than it needs to be but it saves on
124 * inserting another mtmsrd later. 124 * inserting another mtmsrd later.
125 */ 125 */
126 mfmsr r14 126 mfmsr r14
127 mr r15, r14 127 mr r15, r14
128 ori r15, r15, MSR_FP 128 ori r15, r15, MSR_FP
129 li r16, MSR_RI 129 li r16, MSR_RI
130 ori r16, r16, MSR_EE /* IRQs hard off */ 130 ori r16, r16, MSR_EE /* IRQs hard off */
131 andc r15, r15, r16 131 andc r15, r15, r16
132 oris r15, r15, MSR_VEC@h 132 oris r15, r15, MSR_VEC@h
133 #ifdef CONFIG_VSX 133 #ifdef CONFIG_VSX
134 BEGIN_FTR_SECTION 134 BEGIN_FTR_SECTION
135 oris r15,r15, MSR_VSX@h 135 oris r15,r15, MSR_VSX@h
136 END_FTR_SECTION_IFSET(CPU_FTR_VSX) 136 END_FTR_SECTION_IFSET(CPU_FTR_VSX)
137 #endif 137 #endif
138 mtmsrd r15 138 mtmsrd r15
139 std r14, TM_FRAME_L0(r1) 139 std r14, TM_FRAME_L0(r1)
140 140
141 /* Stash the stack pointer away for use after reclaim */ 141 /* Stash the stack pointer away for use after reclaim */
142 std r1, PACAR1(r13) 142 std r1, PACAR1(r13)
143 143
144 /* ******************** FPR/VR/VSRs ************ 144 /* ******************** FPR/VR/VSRs ************
145 * Before reclaiming, capture the current/transactional FPR/VR 145 * Before reclaiming, capture the current/transactional FPR/VR
146 * versions /if used/. 146 * versions /if used/.
147 * 147 *
148 * (If VSX used, FP and VMX are implied. Or, we don't need to look 148 * (If VSX used, FP and VMX are implied. Or, we don't need to look
149 * at MSR.VSX as copying FP regs if .FP, vector regs if .VMX covers it.) 149 * at MSR.VSX as copying FP regs if .FP, vector regs if .VMX covers it.)
150 * 150 *
151 * We're passed the thread's MSR as parameter 2. 151 * We're passed the thread's MSR as parameter 2.
152 * 152 *
153 * We enabled VEC/FP/VSX in the msr above, so we can execute these 153 * We enabled VEC/FP/VSX in the msr above, so we can execute these
154 * instructions! 154 * instructions!
155 */ 155 */
156 andis. r0, r4, MSR_VEC@h 156 andis. r0, r4, MSR_VEC@h
157 beq dont_backup_vec 157 beq dont_backup_vec
158 158
159 addi r7, r3, THREAD_TRANSACT_VRSTATE 159 addi r7, r3, THREAD_TRANSACT_VRSTATE
160 SAVE_32VRS(0, r6, r7) /* r6 scratch, r7 transact vr state */ 160 SAVE_32VRS(0, r6, r7) /* r6 scratch, r7 transact vr state */
161 mfvscr vr0 161 mfvscr vr0
162 li r6, VRSTATE_VSCR 162 li r6, VRSTATE_VSCR
163 stvx vr0, r7, r6 163 stvx vr0, r7, r6
164 dont_backup_vec: 164 dont_backup_vec:
165 mfspr r0, SPRN_VRSAVE 165 mfspr r0, SPRN_VRSAVE
166 std r0, THREAD_TRANSACT_VRSAVE(r3) 166 std r0, THREAD_TRANSACT_VRSAVE(r3)
167 167
168 andi. r0, r4, MSR_FP 168 andi. r0, r4, MSR_FP
169 beq dont_backup_fp 169 beq dont_backup_fp
170 170
171 addi r7, r3, THREAD_TRANSACT_FPSTATE 171 addi r7, r3, THREAD_TRANSACT_FPSTATE
172 SAVE_32FPRS_VSRS(0, R6, R7) /* r6 scratch, r7 transact fp state */ 172 SAVE_32FPRS_VSRS(0, R6, R7) /* r6 scratch, r7 transact fp state */
173 173
174 mffs fr0 174 mffs fr0
175 stfd fr0,FPSTATE_FPSCR(r7) 175 stfd fr0,FPSTATE_FPSCR(r7)
176 176
177 dont_backup_fp: 177 dont_backup_fp:
178 /* The moment we treclaim, ALL of our GPRs will switch 178 /* The moment we treclaim, ALL of our GPRs will switch
179 * to user register state. (FPRs, CCR etc. also!) 179 * to user register state. (FPRs, CCR etc. also!)
180 * Use an sprg and a tm_scratch in the PACA to shuffle. 180 * Use an sprg and a tm_scratch in the PACA to shuffle.
181 */ 181 */
182 TRECLAIM(R5) /* Cause in r5 */ 182 TRECLAIM(R5) /* Cause in r5 */
183 183
184 /* ******************** GPRs ******************** */ 184 /* ******************** GPRs ******************** */
185 /* Stash the checkpointed r13 away in the scratch SPR and get the real 185 /* Stash the checkpointed r13 away in the scratch SPR and get the real
186 * paca 186 * paca
187 */ 187 */
188 SET_SCRATCH0(r13) 188 SET_SCRATCH0(r13)
189 GET_PACA(r13) 189 GET_PACA(r13)
190 190
191 /* Stash the checkpointed r1 away in paca tm_scratch and get the real 191 /* Stash the checkpointed r1 away in paca tm_scratch and get the real
192 * stack pointer back 192 * stack pointer back
193 */ 193 */
194 std r1, PACATMSCRATCH(r13) 194 std r1, PACATMSCRATCH(r13)
195 ld r1, PACAR1(r13) 195 ld r1, PACAR1(r13)
196 196
197 /* Store the PPR in r11 and reset to decent value */ 197 /* Store the PPR in r11 and reset to decent value */
198 std r11, GPR11(r1) /* Temporary stash */ 198 std r11, GPR11(r1) /* Temporary stash */
199 mfspr r11, SPRN_PPR 199 mfspr r11, SPRN_PPR
200 HMT_MEDIUM 200 HMT_MEDIUM
201 201
202 /* Now get some more GPRS free */ 202 /* Now get some more GPRS free */
203 std r7, GPR7(r1) /* Temporary stash */ 203 std r7, GPR7(r1) /* Temporary stash */
204 std r12, GPR12(r1) /* '' '' '' */ 204 std r12, GPR12(r1) /* '' '' '' */
205 ld r12, STACK_PARAM(0)(r1) /* Param 0, thread_struct * */ 205 ld r12, STACK_PARAM(0)(r1) /* Param 0, thread_struct * */
206 206
207 std r11, THREAD_TM_PPR(r12) /* Store PPR and free r11 */ 207 std r11, THREAD_TM_PPR(r12) /* Store PPR and free r11 */
208 208
209 addi r7, r12, PT_CKPT_REGS /* Thread's ckpt_regs */ 209 addi r7, r12, PT_CKPT_REGS /* Thread's ckpt_regs */
210 210
211 /* Make r7 look like an exception frame so that we 211 /* Make r7 look like an exception frame so that we
212 * can use the neat GPRx(n) macros. r7 is NOT a pt_regs ptr! 212 * can use the neat GPRx(n) macros. r7 is NOT a pt_regs ptr!
213 */ 213 */
214 subi r7, r7, STACK_FRAME_OVERHEAD 214 subi r7, r7, STACK_FRAME_OVERHEAD
215 215
216 /* Sync the userland GPRs 2-12, 14-31 to thread->regs: */ 216 /* Sync the userland GPRs 2-12, 14-31 to thread->regs: */
217 SAVE_GPR(0, r7) /* user r0 */ 217 SAVE_GPR(0, r7) /* user r0 */
218 SAVE_GPR(2, r7) /* user r2 */ 218 SAVE_GPR(2, r7) /* user r2 */
219 SAVE_4GPRS(3, r7) /* user r3-r6 */ 219 SAVE_4GPRS(3, r7) /* user r3-r6 */
220 SAVE_GPR(8, r7) /* user r8 */ 220 SAVE_GPR(8, r7) /* user r8 */
221 SAVE_GPR(9, r7) /* user r9 */ 221 SAVE_GPR(9, r7) /* user r9 */
222 SAVE_GPR(10, r7) /* user r10 */ 222 SAVE_GPR(10, r7) /* user r10 */
223 ld r3, PACATMSCRATCH(r13) /* user r1 */ 223 ld r3, PACATMSCRATCH(r13) /* user r1 */
224 ld r4, GPR7(r1) /* user r7 */ 224 ld r4, GPR7(r1) /* user r7 */
225 ld r5, GPR11(r1) /* user r11 */ 225 ld r5, GPR11(r1) /* user r11 */
226 ld r6, GPR12(r1) /* user r12 */ 226 ld r6, GPR12(r1) /* user r12 */
227 GET_SCRATCH0(8) /* user r13 */ 227 GET_SCRATCH0(8) /* user r13 */
228 std r3, GPR1(r7) 228 std r3, GPR1(r7)
229 std r4, GPR7(r7) 229 std r4, GPR7(r7)
230 std r5, GPR11(r7) 230 std r5, GPR11(r7)
231 std r6, GPR12(r7) 231 std r6, GPR12(r7)
232 std r8, GPR13(r7) 232 std r8, GPR13(r7)
233 233
234 SAVE_NVGPRS(r7) /* user r14-r31 */ 234 SAVE_NVGPRS(r7) /* user r14-r31 */
235 235
236 /* ******************** NIP ******************** */ 236 /* ******************** NIP ******************** */
237 mfspr r3, SPRN_TFHAR 237 mfspr r3, SPRN_TFHAR
238 std r3, _NIP(r7) /* Returns to failhandler */ 238 std r3, _NIP(r7) /* Returns to failhandler */
239 /* The checkpointed NIP is ignored when rescheduling/rechkpting, 239 /* The checkpointed NIP is ignored when rescheduling/rechkpting,
240 * but is used in signal return to 'wind back' to the abort handler. 240 * but is used in signal return to 'wind back' to the abort handler.
241 */ 241 */
242 242
243 /* ******************** CR,LR,CCR,MSR ********** */ 243 /* ******************** CR,LR,CCR,MSR ********** */
244 mfctr r3 244 mfctr r3
245 mflr r4 245 mflr r4
246 mfcr r5 246 mfcr r5
247 mfxer r6 247 mfxer r6
248 248
249 std r3, _CTR(r7) 249 std r3, _CTR(r7)
250 std r4, _LINK(r7) 250 std r4, _LINK(r7)
251 std r5, _CCR(r7) 251 std r5, _CCR(r7)
252 std r6, _XER(r7) 252 std r6, _XER(r7)
253 253
254 254
255 /* ******************** TAR, DSCR ********** */ 255 /* ******************** TAR, DSCR ********** */
256 mfspr r3, SPRN_TAR 256 mfspr r3, SPRN_TAR
257 mfspr r4, SPRN_DSCR 257 mfspr r4, SPRN_DSCR
258 258
259 std r3, THREAD_TM_TAR(r12) 259 std r3, THREAD_TM_TAR(r12)
260 std r4, THREAD_TM_DSCR(r12) 260 std r4, THREAD_TM_DSCR(r12)
261 261
262 /* MSR and flags: We don't change CRs, and we don't need to alter 262 /* MSR and flags: We don't change CRs, and we don't need to alter
263 * MSR. 263 * MSR.
264 */ 264 */
265 265
266 /* TM regs, incl TEXASR -- these live in thread_struct. Note they've 266 /* TM regs, incl TEXASR -- these live in thread_struct. Note they've
267 * been updated by the treclaim, to explain to userland the failure 267 * been updated by the treclaim, to explain to userland the failure
268 * cause (aborted). 268 * cause (aborted).
269 */ 269 */
270 mfspr r0, SPRN_TEXASR 270 mfspr r0, SPRN_TEXASR
271 mfspr r3, SPRN_TFHAR 271 mfspr r3, SPRN_TFHAR
272 mfspr r4, SPRN_TFIAR 272 mfspr r4, SPRN_TFIAR
273 std r0, THREAD_TM_TEXASR(r12) 273 std r0, THREAD_TM_TEXASR(r12)
274 std r3, THREAD_TM_TFHAR(r12) 274 std r3, THREAD_TM_TFHAR(r12)
275 std r4, THREAD_TM_TFIAR(r12) 275 std r4, THREAD_TM_TFIAR(r12)
276 276
277 /* AMR is checkpointed too, but is unsupported by Linux. */ 277 /* AMR is checkpointed too, but is unsupported by Linux. */
278 278
279 /* Restore original MSR/IRQ state & clear TM mode */ 279 /* Restore original MSR/IRQ state & clear TM mode */
280 ld r14, TM_FRAME_L0(r1) /* Orig MSR */ 280 ld r14, TM_FRAME_L0(r1) /* Orig MSR */
281 li r15, 0 281 li r15, 0
282 rldimi r14, r15, MSR_TS_LG, (63-MSR_TS_LG)-1 282 rldimi r14, r15, MSR_TS_LG, (63-MSR_TS_LG)-1
283 mtmsrd r14 283 mtmsrd r14
284 284
285 REST_NVGPRS(r1) 285 REST_NVGPRS(r1)
286 286
287 addi r1, r1, TM_FRAME_SIZE 287 addi r1, r1, TM_FRAME_SIZE
288 lwz r4, 8(r1) 288 lwz r4, 8(r1)
289 ld r0, 16(r1) 289 ld r0, 16(r1)
290 mtcr r4 290 mtcr r4
291 mtlr r0 291 mtlr r0
292 ld r2, 40(r1) 292 ld r2, 40(r1)
293 293
294 /* Load system default DSCR */ 294 /* Load system default DSCR */
295 ld r4, DSCR_DEFAULT@toc(r2) 295 ld r4, DSCR_DEFAULT@toc(r2)
296 ld r0, 0(r4) 296 ld r0, 0(r4)
297 mtspr SPRN_DSCR, r0 297 mtspr SPRN_DSCR, r0
298 298
299 blr 299 blr
300 300
301 301
302 /* void tm_recheckpoint(struct thread_struct *thread, 302 /* void tm_recheckpoint(struct thread_struct *thread,
303 * unsigned long orig_msr) 303 * unsigned long orig_msr)
304 * - Restore the checkpointed register state saved by tm_reclaim 304 * - Restore the checkpointed register state saved by tm_reclaim
305 * when we switch_to a process. 305 * when we switch_to a process.
306 * 306 *
307 * Call with IRQs off, stacks get all out of sync for 307 * Call with IRQs off, stacks get all out of sync for
308 * some periods in here! 308 * some periods in here!
309 */ 309 */
310 _GLOBAL(__tm_recheckpoint) 310 _GLOBAL(__tm_recheckpoint)
311 mfcr r5 311 mfcr r5
312 mflr r0 312 mflr r0
313 stw r5, 8(r1) 313 stw r5, 8(r1)
314 std r0, 16(r1) 314 std r0, 16(r1)
315 std r2, 40(r1) 315 std r2, 40(r1)
316 stdu r1, -TM_FRAME_SIZE(r1) 316 stdu r1, -TM_FRAME_SIZE(r1)
317 317
318 /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD]. 318 /* We've a struct pt_regs at [r1+STACK_FRAME_OVERHEAD].
319 * This is used for backing up the NVGPRs: 319 * This is used for backing up the NVGPRs:
320 */ 320 */
321 SAVE_NVGPRS(r1) 321 SAVE_NVGPRS(r1)
322 322
323 std r1, PACAR1(r13)
324
325 /* Load complete register state from ts_ckpt* registers */ 323 /* Load complete register state from ts_ckpt* registers */
326 324
327 addi r7, r3, PT_CKPT_REGS /* Thread's ckpt_regs */ 325 addi r7, r3, PT_CKPT_REGS /* Thread's ckpt_regs */
328 326
329 /* Make r7 look like an exception frame so that we 327 /* Make r7 look like an exception frame so that we
330 * can use the neat GPRx(n) macros. r7 is now NOT a pt_regs ptr! 328 * can use the neat GPRx(n) macros. r7 is now NOT a pt_regs ptr!
331 */ 329 */
332 subi r7, r7, STACK_FRAME_OVERHEAD 330 subi r7, r7, STACK_FRAME_OVERHEAD
333 331
334 SET_SCRATCH0(r1) 332 SET_SCRATCH0(r1)
335 333
336 mfmsr r6 334 mfmsr r6
337 /* R4 = original MSR to indicate whether thread used FP/Vector etc. */ 335 /* R4 = original MSR to indicate whether thread used FP/Vector etc. */
338 336
339 /* Enable FP/vec in MSR if necessary! */ 337 /* Enable FP/vec in MSR if necessary! */
340 lis r5, MSR_VEC@h 338 lis r5, MSR_VEC@h
341 ori r5, r5, MSR_FP 339 ori r5, r5, MSR_FP
342 and. r5, r4, r5 340 and. r5, r4, r5
343 beq restore_gprs /* if neither, skip both */ 341 beq restore_gprs /* if neither, skip both */
344 342
345 #ifdef CONFIG_VSX 343 #ifdef CONFIG_VSX
346 BEGIN_FTR_SECTION 344 BEGIN_FTR_SECTION
347 oris r5, r5, MSR_VSX@h 345 oris r5, r5, MSR_VSX@h
348 END_FTR_SECTION_IFSET(CPU_FTR_VSX) 346 END_FTR_SECTION_IFSET(CPU_FTR_VSX)
349 #endif 347 #endif
350 or r5, r6, r5 /* Set MSR.FP+.VSX/.VEC */ 348 or r5, r6, r5 /* Set MSR.FP+.VSX/.VEC */
351 mtmsr r5 349 mtmsr r5
352 350
353 #ifdef CONFIG_ALTIVEC 351 #ifdef CONFIG_ALTIVEC
354 /* FP and VEC registers: These are recheckpointed from thread.fpr[] 352 /* FP and VEC registers: These are recheckpointed from thread.fpr[]
355 * and thread.vr[] respectively. The thread.transact_fpr[] version 353 * and thread.vr[] respectively. The thread.transact_fpr[] version
356 * is more modern, and will be loaded subsequently by any FPUnavailable 354 * is more modern, and will be loaded subsequently by any FPUnavailable
357 * trap. 355 * trap.
358 */ 356 */
359 andis. r0, r4, MSR_VEC@h 357 andis. r0, r4, MSR_VEC@h
360 beq dont_restore_vec 358 beq dont_restore_vec
361 359
362 addi r8, r3, THREAD_VRSTATE 360 addi r8, r3, THREAD_VRSTATE
363 li r5, VRSTATE_VSCR 361 li r5, VRSTATE_VSCR
364 lvx vr0, r8, r5 362 lvx vr0, r8, r5
365 mtvscr vr0 363 mtvscr vr0
366 REST_32VRS(0, r5, r8) /* r5 scratch, r8 ptr */ 364 REST_32VRS(0, r5, r8) /* r5 scratch, r8 ptr */
367 dont_restore_vec: 365 dont_restore_vec:
368 ld r5, THREAD_VRSAVE(r3) 366 ld r5, THREAD_VRSAVE(r3)
369 mtspr SPRN_VRSAVE, r5 367 mtspr SPRN_VRSAVE, r5
370 #endif 368 #endif
371 369
372 andi. r0, r4, MSR_FP 370 andi. r0, r4, MSR_FP
373 beq dont_restore_fp 371 beq dont_restore_fp
374 372
375 addi r8, r3, THREAD_FPSTATE 373 addi r8, r3, THREAD_FPSTATE
376 lfd fr0, FPSTATE_FPSCR(r8) 374 lfd fr0, FPSTATE_FPSCR(r8)
377 MTFSF_L(fr0) 375 MTFSF_L(fr0)
378 REST_32FPRS_VSRS(0, R4, R8) 376 REST_32FPRS_VSRS(0, R4, R8)
379 377
380 dont_restore_fp: 378 dont_restore_fp:
381 mtmsr r6 /* FP/Vec off again! */ 379 mtmsr r6 /* FP/Vec off again! */
382 380
383 restore_gprs: 381 restore_gprs:
384 382
385 /* ******************** CR,LR,CCR,MSR ********** */ 383 /* ******************** CR,LR,CCR,MSR ********** */
386 ld r4, _CTR(r7) 384 ld r4, _CTR(r7)
387 ld r5, _LINK(r7) 385 ld r5, _LINK(r7)
388 ld r6, _CCR(r7) 386 ld r6, _CCR(r7)
389 ld r8, _XER(r7) 387 ld r8, _XER(r7)
390 388
391 mtctr r4 389 mtctr r4
392 mtlr r5 390 mtlr r5
393 mtcr r6 391 mtcr r6
394 mtxer r8 392 mtxer r8
395 393
396 /* ******************** TAR ******************** */ 394 /* ******************** TAR ******************** */
397 ld r4, THREAD_TM_TAR(r3) 395 ld r4, THREAD_TM_TAR(r3)
398 mtspr SPRN_TAR, r4 396 mtspr SPRN_TAR, r4
399 397
400 /* Load up the PPR and DSCR in GPRs only at this stage */ 398 /* Load up the PPR and DSCR in GPRs only at this stage */
401 ld r5, THREAD_TM_DSCR(r3) 399 ld r5, THREAD_TM_DSCR(r3)
402 ld r6, THREAD_TM_PPR(r3) 400 ld r6, THREAD_TM_PPR(r3)
403 401
404 /* Clear the MSR RI since we are about to change R1. EE is already off 402 /* Clear the MSR RI since we are about to change R1. EE is already off
405 */ 403 */
406 li r4, 0 404 li r4, 0
407 mtmsrd r4, 1 405 mtmsrd r4, 1
408 406
409 REST_4GPRS(0, r7) /* GPR0-3 */ 407 REST_4GPRS(0, r7) /* GPR0-3 */
410 REST_GPR(4, r7) /* GPR4 */ 408 REST_GPR(4, r7) /* GPR4 */
411 REST_4GPRS(8, r7) /* GPR8-11 */ 409 REST_4GPRS(8, r7) /* GPR8-11 */
412 REST_2GPRS(12, r7) /* GPR12-13 */ 410 REST_2GPRS(12, r7) /* GPR12-13 */
413 411
414 REST_NVGPRS(r7) /* GPR14-31 */ 412 REST_NVGPRS(r7) /* GPR14-31 */
415 413
416 /* Load up PPR and DSCR here so we don't run with user values for long 414 /* Load up PPR and DSCR here so we don't run with user values for long
417 */ 415 */
418 mtspr SPRN_DSCR, r5 416 mtspr SPRN_DSCR, r5
419 mtspr SPRN_PPR, r6 417 mtspr SPRN_PPR, r6
420 418
421 REST_GPR(5, r7) /* GPR5-7 */ 419 REST_GPR(5, r7) /* GPR5-7 */
422 REST_GPR(6, r7) 420 REST_GPR(6, r7)
423 ld r7, GPR7(r7) 421 ld r7, GPR7(r7)
424 422
425 /* Commit register state as checkpointed state: */ 423 /* Commit register state as checkpointed state: */
426 TRECHKPT 424 TRECHKPT
427 425
428 HMT_MEDIUM 426 HMT_MEDIUM
429 427
430 /* Our transactional state has now changed. 428 /* Our transactional state has now changed.
431 * 429 *
432 * Now just get out of here. Transactional (current) state will be 430 * Now just get out of here. Transactional (current) state will be
433 * updated once restore is called on the return path in the _switch-ed 431 * updated once restore is called on the return path in the _switch-ed
434 * -to process. 432 * -to process.
435 */ 433 */
436 434
437 GET_PACA(r13) 435 GET_PACA(r13)
438 GET_SCRATCH0(r1) 436 GET_SCRATCH0(r1)
439 437
440 /* R1 is restored, so we are recoverable again. EE is still off */ 438 /* R1 is restored, so we are recoverable again. EE is still off */
441 li r4, MSR_RI 439 li r4, MSR_RI
442 mtmsrd r4, 1 440 mtmsrd r4, 1
443 441
444 REST_NVGPRS(r1) 442 REST_NVGPRS(r1)
445 443
446 addi r1, r1, TM_FRAME_SIZE 444 addi r1, r1, TM_FRAME_SIZE
447 lwz r4, 8(r1) 445 lwz r4, 8(r1)
448 ld r0, 16(r1) 446 ld r0, 16(r1)
449 mtcr r4 447 mtcr r4
450 mtlr r0 448 mtlr r0
451 ld r2, 40(r1) 449 ld r2, 40(r1)
452 450
453 /* Load system default DSCR */ 451 /* Load system default DSCR */
454 ld r4, DSCR_DEFAULT@toc(r2) 452 ld r4, DSCR_DEFAULT@toc(r2)
455 ld r0, 0(r4) 453 ld r0, 0(r4)
456 mtspr SPRN_DSCR, r0 454 mtspr SPRN_DSCR, r0
457 455
458 blr 456 blr
459 457
460 /* ****************************************************************** */ 458 /* ****************************************************************** */
461 459