Merge tag 'kbuild-v4.21-3' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy...
[linux-2.6-block.git] / arch / powerpc / kernel / entry_32.S
CommitLineData
9994a338
PM
1/*
2 * PowerPC version
3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
4 * Rewritten by Cort Dougan (cort@fsmlabs.com) for PReP
5 * Copyright (C) 1996 Cort Dougan <cort@fsmlabs.com>
6 * Adapted for Power Macintosh by Paul Mackerras.
7 * Low-level exception handlers and MMU support
8 * rewritten by Paul Mackerras.
9 * Copyright (C) 1996 Paul Mackerras.
10 * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
11 *
12 * This file contains the system call entry code, context switch
13 * code, and exception/interrupt return code for PowerPC.
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version.
19 *
20 */
21
9994a338 22#include <linux/errno.h>
c3525940 23#include <linux/err.h>
9994a338
PM
24#include <linux/sys.h>
25#include <linux/threads.h>
26#include <asm/reg.h>
27#include <asm/page.h>
28#include <asm/mmu.h>
29#include <asm/cputable.h>
30#include <asm/thread_info.h>
31#include <asm/ppc_asm.h>
32#include <asm/asm-offsets.h>
33#include <asm/unistd.h>
46f52210 34#include <asm/ptrace.h>
9445aa1a 35#include <asm/export.h>
36a7eeaf 36#include <asm/asm-405.h>
2c86cd18 37#include <asm/feature-fixups.h>
c28218d4 38#include <asm/barrier.h>
9994a338 39
9994a338
PM
40/*
41 * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE.
42 */
43#if MSR_KERNEL >= 0x10000
44#define LOAD_MSR_KERNEL(r, x) lis r,(x)@h; ori r,r,(x)@l
45#else
46#define LOAD_MSR_KERNEL(r, x) li r,(x)
47#endif
48
0eb0d2e7
CL
49/*
50 * Align to 4k in order to ensure that all functions modyfing srr0/srr1
51 * fit into one page in order to not encounter a TLB miss between the
52 * modification of srr0/srr1 and the associated rfi.
53 */
54 .align 12
55
9994a338 56#ifdef CONFIG_BOOKE
9994a338
PM
57 .globl mcheck_transfer_to_handler
58mcheck_transfer_to_handler:
fca622c5
KG
59 mfspr r0,SPRN_DSRR0
60 stw r0,_DSRR0(r11)
61 mfspr r0,SPRN_DSRR1
62 stw r0,_DSRR1(r11)
63 /* fall through */
9994a338
PM
64
65 .globl debug_transfer_to_handler
66debug_transfer_to_handler:
fca622c5
KG
67 mfspr r0,SPRN_CSRR0
68 stw r0,_CSRR0(r11)
69 mfspr r0,SPRN_CSRR1
70 stw r0,_CSRR1(r11)
71 /* fall through */
9994a338
PM
72
73 .globl crit_transfer_to_handler
74crit_transfer_to_handler:
70fe3af8 75#ifdef CONFIG_PPC_BOOK3E_MMU
fca622c5
KG
76 mfspr r0,SPRN_MAS0
77 stw r0,MAS0(r11)
78 mfspr r0,SPRN_MAS1
79 stw r0,MAS1(r11)
80 mfspr r0,SPRN_MAS2
81 stw r0,MAS2(r11)
82 mfspr r0,SPRN_MAS3
83 stw r0,MAS3(r11)
84 mfspr r0,SPRN_MAS6
85 stw r0,MAS6(r11)
86#ifdef CONFIG_PHYS_64BIT
87 mfspr r0,SPRN_MAS7
88 stw r0,MAS7(r11)
89#endif /* CONFIG_PHYS_64BIT */
70fe3af8 90#endif /* CONFIG_PPC_BOOK3E_MMU */
fca622c5
KG
91#ifdef CONFIG_44x
92 mfspr r0,SPRN_MMUCR
93 stw r0,MMUCR(r11)
94#endif
95 mfspr r0,SPRN_SRR0
96 stw r0,_SRR0(r11)
97 mfspr r0,SPRN_SRR1
98 stw r0,_SRR1(r11)
99
1f8b0bc8
SY
100 /* set the stack limit to the current stack
101 * and set the limit to protect the thread_info
102 * struct
103 */
ee43eb78 104 mfspr r8,SPRN_SPRG_THREAD
fca622c5
KG
105 lwz r0,KSP_LIMIT(r8)
106 stw r0,SAVED_KSP_LIMIT(r11)
1f8b0bc8 107 rlwimi r0,r1,0,0,(31-THREAD_SHIFT)
fca622c5 108 stw r0,KSP_LIMIT(r8)
9994a338
PM
109 /* fall through */
110#endif
111
112#ifdef CONFIG_40x
113 .globl crit_transfer_to_handler
114crit_transfer_to_handler:
115 lwz r0,crit_r10@l(0)
116 stw r0,GPR10(r11)
117 lwz r0,crit_r11@l(0)
118 stw r0,GPR11(r11)
fca622c5
KG
119 mfspr r0,SPRN_SRR0
120 stw r0,crit_srr0@l(0)
121 mfspr r0,SPRN_SRR1
122 stw r0,crit_srr1@l(0)
123
1f8b0bc8
SY
124 /* set the stack limit to the current stack
125 * and set the limit to protect the thread_info
126 * struct
127 */
ee43eb78 128 mfspr r8,SPRN_SPRG_THREAD
fca622c5
KG
129 lwz r0,KSP_LIMIT(r8)
130 stw r0,saved_ksp_limit@l(0)
1f8b0bc8 131 rlwimi r0,r1,0,0,(31-THREAD_SHIFT)
fca622c5 132 stw r0,KSP_LIMIT(r8)
9994a338
PM
133 /* fall through */
134#endif
135
136/*
137 * This code finishes saving the registers to the exception frame
138 * and jumps to the appropriate handler for the exception, turning
139 * on address translation.
140 * Note that we rely on the caller having set cr0.eq iff the exception
141 * occurred in kernel mode (i.e. MSR:PR = 0).
142 */
143 .globl transfer_to_handler_full
144transfer_to_handler_full:
145 SAVE_NVGPRS(r11)
146 /* fall through */
147
148 .globl transfer_to_handler
149transfer_to_handler:
150 stw r2,GPR2(r11)
151 stw r12,_NIP(r11)
152 stw r9,_MSR(r11)
153 andi. r2,r9,MSR_PR
154 mfctr r12
155 mfspr r2,SPRN_XER
156 stw r12,_CTR(r11)
157 stw r2,_XER(r11)
ee43eb78 158 mfspr r12,SPRN_SPRG_THREAD
9994a338
PM
159 addi r2,r12,-THREAD
160 tovirt(r2,r2) /* set r2 to current */
161 beq 2f /* if from user, fix up THREAD.regs */
162 addi r11,r1,STACK_FRAME_OVERHEAD
163 stw r11,PT_REGS(r12)
164#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
165 /* Check to see if the dbcr0 register is set up to debug. Use the
4eaddb4d 166 internal debug mode bit to do this. */
9994a338 167 lwz r12,THREAD_DBCR0(r12)
2325f0a0 168 andis. r12,r12,DBCR0_IDM@h
9994a338
PM
169 beq+ 3f
170 /* From user and task is ptraced - load up global dbcr0 */
171 li r12,-1 /* clear all pending debug events */
172 mtspr SPRN_DBSR,r12
173 lis r11,global_dbcr0@ha
174 tophys(r11,r11)
175 addi r11,r11,global_dbcr0@l
4eaddb4d 176#ifdef CONFIG_SMP
9778b696 177 CURRENT_THREAD_INFO(r9, r1)
4eaddb4d
KG
178 lwz r9,TI_CPU(r9)
179 slwi r9,r9,3
180 add r11,r11,r9
181#endif
9994a338
PM
182 lwz r12,0(r11)
183 mtspr SPRN_DBCR0,r12
184 lwz r12,4(r11)
185 addi r12,r12,-1
186 stw r12,4(r11)
187#endif
c223c903
CL
188#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
189 CURRENT_THREAD_INFO(r9, r1)
190 tophys(r9, r9)
191 ACCOUNT_CPU_USER_ENTRY(r9, r11, r12)
192#endif
193
9994a338 194 b 3f
f39224a8 195
9994a338
PM
1962: /* if from kernel, check interrupted DOZE/NAP mode and
197 * check for stack overflow
198 */
85218827
KG
199 lwz r9,KSP_LIMIT(r12)
200 cmplw r1,r9 /* if r1 <= ksp_limit */
f39224a8
PM
201 ble- stack_ovf /* then the kernel stack overflowed */
2025:
d7cceda9 203#if defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_E500)
9778b696 204 CURRENT_THREAD_INFO(r9, r1)
f39224a8
PM
205 tophys(r9,r9) /* check local flags */
206 lwz r12,TI_LOCAL_FLAGS(r9)
207 mtcrf 0x01,r12
208 bt- 31-TLF_NAPPING,4f
a560643e 209 bt- 31-TLF_SLEEPING,7f
d7cceda9 210#endif /* CONFIG_PPC_BOOK3S_32 || CONFIG_E500 */
9994a338
PM
211 .globl transfer_to_handler_cont
212transfer_to_handler_cont:
9994a338
PM
2133:
214 mflr r9
215 lwz r11,0(r9) /* virtual address of handler */
216 lwz r9,4(r9) /* where to go when done */
cd99ddbe 217#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
75b82472
CL
218 mtspr SPRN_NRI, r0
219#endif
5d38902c
BH
220#ifdef CONFIG_TRACE_IRQFLAGS
221 lis r12,reenable_mmu@h
222 ori r12,r12,reenable_mmu@l
223 mtspr SPRN_SRR0,r12
224 mtspr SPRN_SRR1,r10
225 SYNC
226 RFI
227reenable_mmu: /* re-enable mmu so we can */
228 mfmsr r10
229 lwz r12,_MSR(r1)
230 xor r10,r10,r12
231 andi. r10,r10,MSR_EE /* Did EE change? */
232 beq 1f
233
2cd76629
KH
234 /*
235 * The trace_hardirqs_off will use CALLER_ADDR0 and CALLER_ADDR1.
236 * If from user mode there is only one stack frame on the stack, and
237 * accessing CALLER_ADDR1 will cause oops. So we need create a dummy
238 * stack frame to make trace_hardirqs_off happy.
08f1ec8a
BH
239 *
240 * This is handy because we also need to save a bunch of GPRs,
241 * r3 can be different from GPR3(r1) at this point, r9 and r11
242 * contains the old MSR and handler address respectively,
243 * r4 & r5 can contain page fault arguments that need to be passed
244 * along as well. r12, CCR, CTR, XER etc... are left clobbered as
245 * they aren't useful past this point (aren't syscall arguments),
246 * the rest is restored from the exception frame.
2cd76629 247 */
08f1ec8a
BH
248 stwu r1,-32(r1)
249 stw r9,8(r1)
250 stw r11,12(r1)
251 stw r3,16(r1)
252 stw r4,20(r1)
253 stw r5,24(r1)
2cd76629 254 bl trace_hardirqs_off
08f1ec8a
BH
255 lwz r5,24(r1)
256 lwz r4,20(r1)
257 lwz r3,16(r1)
258 lwz r11,12(r1)
259 lwz r9,8(r1)
260 addi r1,r1,32
5d38902c 261 lwz r0,GPR0(r1)
5d38902c
BH
262 lwz r6,GPR6(r1)
263 lwz r7,GPR7(r1)
264 lwz r8,GPR8(r1)
5d38902c
BH
2651: mtctr r11
266 mtlr r9
267 bctr /* jump to handler */
268#else /* CONFIG_TRACE_IRQFLAGS */
9994a338
PM
269 mtspr SPRN_SRR0,r11
270 mtspr SPRN_SRR1,r10
271 mtlr r9
272 SYNC
273 RFI /* jump to handler, enable MMU */
5d38902c 274#endif /* CONFIG_TRACE_IRQFLAGS */
9994a338 275
d7cceda9 276#if defined (CONFIG_PPC_BOOK3S_32) || defined(CONFIG_E500)
f39224a8
PM
2774: rlwinm r12,r12,0,~_TLF_NAPPING
278 stw r12,TI_LOCAL_FLAGS(r9)
fc4033b2 279 b power_save_ppc32_restore
a560643e
PM
280
2817: rlwinm r12,r12,0,~_TLF_SLEEPING
282 stw r12,TI_LOCAL_FLAGS(r9)
283 lwz r9,_MSR(r11) /* if sleeping, clear MSR.EE */
284 rlwinm r9,r9,0,~MSR_EE
285 lwz r12,_LINK(r11) /* and return to address in LR */
286 b fast_exception_return
a0652fc9
PM
287#endif
288
9994a338
PM
289/*
290 * On kernel stack overflow, load up an initial stack pointer
291 * and call StackOverflow(regs), which should not return.
292 */
293stack_ovf:
294 /* sometimes we use a statically-allocated stack, which is OK. */
f39224a8
PM
295 lis r12,_end@h
296 ori r12,r12,_end@l
297 cmplw r1,r12
298 ble 5b /* r1 <= &_end is OK */
9994a338
PM
299 SAVE_NVGPRS(r11)
300 addi r3,r1,STACK_FRAME_OVERHEAD
301 lis r1,init_thread_union@ha
302 addi r1,r1,init_thread_union@l
303 addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
304 lis r9,StackOverflow@ha
305 addi r9,r9,StackOverflow@l
306 LOAD_MSR_KERNEL(r10,MSR_KERNEL)
cd99ddbe 307#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
75b82472
CL
308 mtspr SPRN_NRI, r0
309#endif
9994a338
PM
310 mtspr SPRN_SRR0,r9
311 mtspr SPRN_SRR1,r10
312 SYNC
313 RFI
314
315/*
316 * Handle a system call.
317 */
318 .stabs "arch/powerpc/kernel/",N_SO,0,0,0f
319 .stabs "entry_32.S",N_SO,0,0,0f
3200:
321
322_GLOBAL(DoSyscall)
9994a338
PM
323 stw r3,ORIG_GPR3(r1)
324 li r12,0
325 stw r12,RESULT(r1)
326 lwz r11,_CCR(r1) /* Clear SO bit in CR */
327 rlwinm r11,r11,0,4,2
328 stw r11,_CCR(r1)
5d38902c
BH
329#ifdef CONFIG_TRACE_IRQFLAGS
330 /* Return from syscalls can (and generally will) hard enable
331 * interrupts. You aren't supposed to call a syscall with
332 * interrupts disabled in the first place. However, to ensure
333 * that we get it right vs. lockdep if it happens, we force
334 * that hard enable here with appropriate tracing if we see
335 * that we have been called with interrupts off
336 */
337 mfmsr r11
338 andi. r12,r11,MSR_EE
339 bne+ 1f
340 /* We came in with interrupts disabled, we enable them now */
341 bl trace_hardirqs_on
342 mfmsr r11
343 lwz r0,GPR0(r1)
344 lwz r3,GPR3(r1)
345 lwz r4,GPR4(r1)
346 ori r11,r11,MSR_EE
347 lwz r5,GPR5(r1)
348 lwz r6,GPR6(r1)
349 lwz r7,GPR7(r1)
350 lwz r8,GPR8(r1)
351 mtmsr r11
3521:
353#endif /* CONFIG_TRACE_IRQFLAGS */
9778b696 354 CURRENT_THREAD_INFO(r10, r1)
9994a338 355 lwz r11,TI_FLAGS(r10)
10ea8343 356 andi. r11,r11,_TIF_SYSCALL_DOTRACE
9994a338
PM
357 bne- syscall_dotrace
358syscall_dotrace_cont:
359 cmplwi 0,r0,NR_syscalls
360 lis r10,sys_call_table@h
361 ori r10,r10,sys_call_table@l
362 slwi r0,r0,2
363 bge- 66f
c28218d4
DC
364
365 barrier_nospec_asm
366 /*
367 * Prevent the load of the handler below (based on the user-passed
368 * system call number) being speculatively executed until the test
369 * against NR_syscalls and branch to .66f above has
370 * committed.
371 */
372
9994a338
PM
373 lwzx r10,r10,r0 /* Fetch system call handler [ptr] */
374 mtlr r10
375 addi r9,r1,STACK_FRAME_OVERHEAD
376 PPC440EP_ERR42
377 blrl /* Call handler */
378 .globl ret_from_syscall
379ret_from_syscall:
6f37be4b
BF
380#ifdef CONFIG_DEBUG_RSEQ
381 /* Check whether the syscall is issued inside a restartable sequence */
382 stw r3,GPR3(r1)
383 addi r3,r1,STACK_FRAME_OVERHEAD
384 bl rseq_syscall
385 lwz r3,GPR3(r1)
386#endif
9994a338 387 mr r6,r3
9778b696 388 CURRENT_THREAD_INFO(r12, r1)
9994a338 389 /* disable interrupts so current_thread_info()->flags can't change */
401d1f02 390 LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
5d38902c 391 /* Note: We don't bother telling lockdep about it */
9994a338
PM
392 SYNC
393 MTMSRD(r10)
394 lwz r9,TI_FLAGS(r12)
c3525940 395 li r8,-MAX_ERRNO
10ea8343 396 andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
9994a338 397 bne- syscall_exit_work
401d1f02
DW
398 cmplw 0,r3,r8
399 blt+ syscall_exit_cont
400 lwz r11,_CCR(r1) /* Load CR */
401 neg r3,r3
402 oris r11,r11,0x1000 /* Set SO bit in CR */
403 stw r11,_CCR(r1)
9994a338 404syscall_exit_cont:
5d38902c
BH
405 lwz r8,_MSR(r1)
406#ifdef CONFIG_TRACE_IRQFLAGS
407 /* If we are going to return from the syscall with interrupts
408 * off, we trace that here. It shouldn't happen though but we
409 * want to catch the bugger if it does right ?
410 */
411 andi. r10,r8,MSR_EE
412 bne+ 1f
413 stw r3,GPR3(r1)
414 bl trace_hardirqs_off
415 lwz r3,GPR3(r1)
4161:
417#endif /* CONFIG_TRACE_IRQFLAGS */
9994a338 418#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
4eaddb4d
KG
419 /* If the process has its own DBCR0 value, load it up. The internal
420 debug mode bit tells us that dbcr0 should be loaded. */
9994a338 421 lwz r0,THREAD+THREAD_DBCR0(r2)
2325f0a0 422 andis. r10,r0,DBCR0_IDM@h
9994a338
PM
423 bnel- load_dbcr0
424#endif
b98ac05d 425#ifdef CONFIG_44x
e7f75ad0 426BEGIN_MMU_FTR_SECTION
b98ac05d
BH
427 lis r4,icache_44x_need_flush@ha
428 lwz r5,icache_44x_need_flush@l(r4)
429 cmplwi cr0,r5,0
430 bne- 2f
4311:
e7f75ad0 432END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_47x)
b98ac05d 433#endif /* CONFIG_44x */
b64f87c1
BB
434BEGIN_FTR_SECTION
435 lwarx r7,0,r1
436END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
9994a338 437 stwcx. r0,0,r1 /* to clear the reservation */
c223c903
CL
438#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
439 andi. r4,r8,MSR_PR
440 beq 3f
441 CURRENT_THREAD_INFO(r4, r1)
442 ACCOUNT_CPU_USER_EXIT(r4, r5, r7)
4433:
444#endif
9994a338
PM
445 lwz r4,_LINK(r1)
446 lwz r5,_CCR(r1)
447 mtlr r4
448 mtcr r5
449 lwz r7,_NIP(r1)
9994a338
PM
450 lwz r2,GPR2(r1)
451 lwz r1,GPR1(r1)
cd99ddbe 452#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
75b82472
CL
453 mtspr SPRN_NRI, r0
454#endif
9994a338
PM
455 mtspr SPRN_SRR0,r7
456 mtspr SPRN_SRR1,r8
457 SYNC
458 RFI
b98ac05d
BH
459#ifdef CONFIG_44x
4602: li r7,0
461 iccci r0,r0
462 stw r7,icache_44x_need_flush@l(r4)
463 b 1b
464#endif /* CONFIG_44x */
9994a338
PM
465
46666: li r3,-ENOSYS
467 b ret_from_syscall
468
469 .globl ret_from_fork
470ret_from_fork:
471 REST_NVGPRS(r1)
472 bl schedule_tail
473 li r3,0
474 b ret_from_syscall
475
58254e10
AV
476 .globl ret_from_kernel_thread
477ret_from_kernel_thread:
478 REST_NVGPRS(r1)
479 bl schedule_tail
480 mtlr r14
481 mr r3,r15
482 PPC440EP_ERR42
483 blrl
484 li r3,0
be6abfa7 485 b ret_from_syscall
9994a338
PM
486
487/* Traced system call support */
488syscall_dotrace:
489 SAVE_NVGPRS(r1)
490 li r0,0xc00
d73e0c99 491 stw r0,_TRAP(r1)
9994a338
PM
492 addi r3,r1,STACK_FRAME_OVERHEAD
493 bl do_syscall_trace_enter
4f72c427
RM
494 /*
495 * Restore argument registers possibly just changed.
496 * We use the return value of do_syscall_trace_enter
497 * for call number to look up in the table (r0).
498 */
499 mr r0,r3
9994a338
PM
500 lwz r3,GPR3(r1)
501 lwz r4,GPR4(r1)
502 lwz r5,GPR5(r1)
503 lwz r6,GPR6(r1)
504 lwz r7,GPR7(r1)
505 lwz r8,GPR8(r1)
506 REST_NVGPRS(r1)
d3837414
ME
507
508 cmplwi r0,NR_syscalls
509 /* Return code is already in r3 thanks to do_syscall_trace_enter() */
510 bge- ret_from_syscall
9994a338
PM
511 b syscall_dotrace_cont
512
513syscall_exit_work:
401d1f02 514 andi. r0,r9,_TIF_RESTOREALL
1bd79336
PM
515 beq+ 0f
516 REST_NVGPRS(r1)
517 b 2f
5180: cmplw 0,r3,r8
401d1f02
DW
519 blt+ 1f
520 andi. r0,r9,_TIF_NOERROR
521 bne- 1f
522 lwz r11,_CCR(r1) /* Load CR */
523 neg r3,r3
524 oris r11,r11,0x1000 /* Set SO bit in CR */
525 stw r11,_CCR(r1)
526
5271: stw r6,RESULT(r1) /* Save result */
9994a338 528 stw r3,GPR3(r1) /* Update return value */
401d1f02
DW
5292: andi. r0,r9,(_TIF_PERSYSCALL_MASK)
530 beq 4f
531
1bd79336 532 /* Clear per-syscall TIF flags if any are set. */
401d1f02
DW
533
534 li r11,_TIF_PERSYSCALL_MASK
535 addi r12,r12,TI_FLAGS
5363: lwarx r8,0,r12
537 andc r8,r8,r11
538#ifdef CONFIG_IBM405_ERR77
539 dcbt 0,r12
540#endif
541 stwcx. r8,0,r12
542 bne- 3b
543 subi r12,r12,TI_FLAGS
544
5454: /* Anything which requires enabling interrupts? */
10ea8343 546 andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP)
1bd79336
PM
547 beq ret_from_except
548
5d38902c
BH
549 /* Re-enable interrupts. There is no need to trace that with
550 * lockdep as we are supposed to have IRQs on at this point
551 */
1bd79336
PM
552 ori r10,r10,MSR_EE
553 SYNC
554 MTMSRD(r10)
401d1f02
DW
555
556 /* Save NVGPRS if they're not saved already */
d73e0c99 557 lwz r4,_TRAP(r1)
9994a338 558 andi. r4,r4,1
401d1f02 559 beq 5f
9994a338
PM
560 SAVE_NVGPRS(r1)
561 li r4,0xc00
d73e0c99 562 stw r4,_TRAP(r1)
1bd79336 5635:
9994a338
PM
564 addi r3,r1,STACK_FRAME_OVERHEAD
565 bl do_syscall_trace_leave
1bd79336 566 b ret_from_except_full
9994a338 567
9994a338 568/*
401d1f02
DW
569 * The fork/clone functions need to copy the full register set into
570 * the child process. Therefore we need to save all the nonvolatile
571 * registers (r13 - r31) before calling the C code.
9994a338 572 */
9994a338
PM
573 .globl ppc_fork
574ppc_fork:
575 SAVE_NVGPRS(r1)
d73e0c99 576 lwz r0,_TRAP(r1)
9994a338 577 rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
d73e0c99 578 stw r0,_TRAP(r1) /* register set saved */
9994a338
PM
579 b sys_fork
580
581 .globl ppc_vfork
582ppc_vfork:
583 SAVE_NVGPRS(r1)
d73e0c99 584 lwz r0,_TRAP(r1)
9994a338 585 rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
d73e0c99 586 stw r0,_TRAP(r1) /* register set saved */
9994a338
PM
587 b sys_vfork
588
589 .globl ppc_clone
590ppc_clone:
591 SAVE_NVGPRS(r1)
d73e0c99 592 lwz r0,_TRAP(r1)
9994a338 593 rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
d73e0c99 594 stw r0,_TRAP(r1) /* register set saved */
9994a338
PM
595 b sys_clone
596
1bd79336
PM
597 .globl ppc_swapcontext
598ppc_swapcontext:
599 SAVE_NVGPRS(r1)
600 lwz r0,_TRAP(r1)
601 rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
602 stw r0,_TRAP(r1) /* register set saved */
603 b sys_swapcontext
604
9994a338
PM
605/*
606 * Top-level page fault handling.
607 * This is in assembler because if do_page_fault tells us that
608 * it is a bad kernel page fault, we want to save the non-volatile
609 * registers before calling bad_page_fault.
610 */
611 .globl handle_page_fault
612handle_page_fault:
613 stw r4,_DAR(r1)
614 addi r3,r1,STACK_FRAME_OVERHEAD
d7cceda9 615#ifdef CONFIG_PPC_BOOK3S_32
64d0a506 616 andis. r0,r5,DSISR_DABRMATCH@h
d300627c 617 bne- handle_dabr_fault
d300627c 618#endif
64d0a506 619 bl do_page_fault
9994a338
PM
620 cmpwi r3,0
621 beq+ ret_from_except
622 SAVE_NVGPRS(r1)
d73e0c99 623 lwz r0,_TRAP(r1)
9994a338 624 clrrwi r0,r0,1
d73e0c99 625 stw r0,_TRAP(r1)
9994a338
PM
626 mr r5,r3
627 addi r3,r1,STACK_FRAME_OVERHEAD
628 lwz r4,_DAR(r1)
629 bl bad_page_fault
630 b ret_from_except_full
631
d7cceda9 632#ifdef CONFIG_PPC_BOOK3S_32
d300627c
BH
633 /* We have a data breakpoint exception - handle it */
634handle_dabr_fault:
635 SAVE_NVGPRS(r1)
636 lwz r0,_TRAP(r1)
637 clrrwi r0,r0,1
638 stw r0,_TRAP(r1)
639 bl do_break
640 b ret_from_except_full
641#endif
642
9994a338
PM
643/*
644 * This routine switches between two different tasks. The process
645 * state of one is saved on its kernel stack. Then the state
646 * of the other is restored from its kernel stack. The memory
647 * management hardware is updated to the second process's state.
648 * Finally, we can return to the second process.
649 * On entry, r3 points to the THREAD for the current task, r4
650 * points to the THREAD for the new task.
651 *
652 * This routine is always called with interrupts disabled.
653 *
654 * Note: there are two ways to get to the "going out" portion
655 * of this code; either by coming in via the entry (_switch)
656 * or via "fork" which must set up an environment equivalent
657 * to the "_switch" path. If you change this , you'll have to
658 * change the fork code also.
659 *
660 * The code which creates the new task context is in 'copy_thread'
661 * in arch/ppc/kernel/process.c
662 */
663_GLOBAL(_switch)
664 stwu r1,-INT_FRAME_SIZE(r1)
665 mflr r0
666 stw r0,INT_FRAME_SIZE+4(r1)
667 /* r3-r12 are caller saved -- Cort */
668 SAVE_NVGPRS(r1)
669 stw r0,_NIP(r1) /* Return to switch caller */
670 mfmsr r11
671 li r0,MSR_FP /* Disable floating-point */
672#ifdef CONFIG_ALTIVEC
673BEGIN_FTR_SECTION
674 oris r0,r0,MSR_VEC@h /* Disable altivec */
675 mfspr r12,SPRN_VRSAVE /* save vrsave register value */
676 stw r12,THREAD+THREAD_VRSAVE(r2)
677END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
678#endif /* CONFIG_ALTIVEC */
679#ifdef CONFIG_SPE
5e14d21e 680BEGIN_FTR_SECTION
9994a338
PM
681 oris r0,r0,MSR_SPE@h /* Disable SPE */
682 mfspr r12,SPRN_SPEFSCR /* save spefscr register value */
683 stw r12,THREAD+THREAD_SPEFSCR(r2)
5e14d21e 684END_FTR_SECTION_IFSET(CPU_FTR_SPE)
9994a338
PM
685#endif /* CONFIG_SPE */
686 and. r0,r0,r11 /* FP or altivec or SPE enabled? */
687 beq+ 1f
688 andc r11,r11,r0
689 MTMSRD(r11)
690 isync
6911: stw r11,_MSR(r1)
692 mfcr r10
693 stw r10,_CCR(r1)
694 stw r1,KSP(r3) /* Set old stack pointer */
695
696#ifdef CONFIG_SMP
697 /* We need a sync somewhere here to make sure that if the
698 * previous task gets rescheduled on another CPU, it sees all
699 * stores it has performed on this one.
700 */
701 sync
702#endif /* CONFIG_SMP */
703
704 tophys(r0,r4)
ee43eb78 705 mtspr SPRN_SPRG_THREAD,r0 /* Update current THREAD phys addr */
9994a338
PM
706 lwz r1,KSP(r4) /* Load new stack pointer */
707
708 /* save the old current 'last' for return value */
709 mr r3,r2
710 addi r2,r4,-THREAD /* Update current */
711
712#ifdef CONFIG_ALTIVEC
713BEGIN_FTR_SECTION
714 lwz r0,THREAD+THREAD_VRSAVE(r2)
715 mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */
716END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
717#endif /* CONFIG_ALTIVEC */
718#ifdef CONFIG_SPE
5e14d21e 719BEGIN_FTR_SECTION
9994a338
PM
720 lwz r0,THREAD+THREAD_SPEFSCR(r2)
721 mtspr SPRN_SPEFSCR,r0 /* restore SPEFSCR reg */
5e14d21e 722END_FTR_SECTION_IFSET(CPU_FTR_SPE)
9994a338 723#endif /* CONFIG_SPE */
f2574030 724
9994a338
PM
725 lwz r0,_CCR(r1)
726 mtcrf 0xFF,r0
727 /* r3-r12 are destroyed -- Cort */
728 REST_NVGPRS(r1)
729
730 lwz r4,_NIP(r1) /* Return to _switch caller in new task */
731 mtlr r4
732 addi r1,r1,INT_FRAME_SIZE
733 blr
734
735 .globl fast_exception_return
736fast_exception_return:
737#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
738 andi. r10,r9,MSR_RI /* check for recoverable interrupt */
739 beq 1f /* if not, we've got problems */
740#endif
741
7422: REST_4GPRS(3, r11)
743 lwz r10,_CCR(r11)
744 REST_GPR(1, r11)
745 mtcr r10
746 lwz r10,_LINK(r11)
747 mtlr r10
748 REST_GPR(10, r11)
cd99ddbe 749#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
75b82472
CL
750 mtspr SPRN_NRI, r0
751#endif
9994a338
PM
752 mtspr SPRN_SRR1,r9
753 mtspr SPRN_SRR0,r12
754 REST_GPR(9, r11)
755 REST_GPR(12, r11)
756 lwz r11,GPR11(r11)
757 SYNC
758 RFI
759
760#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
761/* check if the exception happened in a restartable section */
7621: lis r3,exc_exit_restart_end@ha
763 addi r3,r3,exc_exit_restart_end@l
764 cmplw r12,r3
765 bge 3f
766 lis r4,exc_exit_restart@ha
767 addi r4,r4,exc_exit_restart@l
768 cmplw r12,r4
769 blt 3f
770 lis r3,fee_restarts@ha
771 tophys(r3,r3)
772 lwz r5,fee_restarts@l(r3)
773 addi r5,r5,1
774 stw r5,fee_restarts@l(r3)
775 mr r12,r4 /* restart at exc_exit_restart */
776 b 2b
777
991eb43a
KG
778 .section .bss
779 .align 2
780fee_restarts:
781 .space 4
782 .previous
9994a338
PM
783
784/* aargh, a nonrecoverable interrupt, panic */
785/* aargh, we don't know which trap this is */
786/* but the 601 doesn't implement the RI bit, so assume it's OK */
7873:
788BEGIN_FTR_SECTION
789 b 2b
790END_FTR_SECTION_IFSET(CPU_FTR_601)
791 li r10,-1
d73e0c99 792 stw r10,_TRAP(r11)
9994a338
PM
793 addi r3,r1,STACK_FRAME_OVERHEAD
794 lis r10,MSR_KERNEL@h
795 ori r10,r10,MSR_KERNEL@l
796 bl transfer_to_handler_full
51423a9c 797 .long unrecoverable_exception
9994a338
PM
798 .long ret_from_except
799#endif
800
9994a338
PM
801 .globl ret_from_except_full
802ret_from_except_full:
803 REST_NVGPRS(r1)
804 /* fall through */
805
806 .globl ret_from_except
807ret_from_except:
808 /* Hard-disable interrupts so that current_thread_info()->flags
809 * can't change between when we test it and when we return
810 * from the interrupt. */
5d38902c 811 /* Note: We don't bother telling lockdep about it */
9994a338
PM
812 LOAD_MSR_KERNEL(r10,MSR_KERNEL)
813 SYNC /* Some chip revs have problems here... */
814 MTMSRD(r10) /* disable interrupts */
815
816 lwz r3,_MSR(r1) /* Returning to user mode? */
817 andi. r0,r3,MSR_PR
818 beq resume_kernel
819
820user_exc_return: /* r10 contains MSR_KERNEL here */
821 /* Check current_thread_info()->flags */
9778b696 822 CURRENT_THREAD_INFO(r9, r1)
9994a338 823 lwz r9,TI_FLAGS(r9)
7a10174e 824 andi. r0,r9,_TIF_USER_WORK_MASK
9994a338
PM
825 bne do_work
826
827restore_user:
828#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
4eaddb4d
KG
829 /* Check whether this process has its own DBCR0 value. The internal
830 debug mode bit tells us that dbcr0 should be loaded. */
9994a338 831 lwz r0,THREAD+THREAD_DBCR0(r2)
2325f0a0 832 andis. r10,r0,DBCR0_IDM@h
9994a338
PM
833 bnel- load_dbcr0
834#endif
c223c903
CL
835#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
836 CURRENT_THREAD_INFO(r9, r1)
837 ACCOUNT_CPU_USER_EXIT(r9, r10, r11)
838#endif
9994a338 839
9994a338
PM
840 b restore
841
842/* N.B. the only way to get here is from the beq following ret_from_except. */
843resume_kernel:
a9c4e541 844 /* check current_thread_info, _TIF_EMULATE_STACK_STORE */
9778b696 845 CURRENT_THREAD_INFO(r9, r1)
a9c4e541 846 lwz r8,TI_FLAGS(r9)
f7b33677 847 andis. r0,r8,_TIF_EMULATE_STACK_STORE@h
a9c4e541
TC
848 beq+ 1f
849
850 addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */
851
852 lwz r3,GPR1(r1)
853 subi r3,r3,INT_FRAME_SIZE /* dst: Allocate a trampoline exception frame */
854 mr r4,r1 /* src: current exception frame */
855 mr r1,r3 /* Reroute the trampoline frame to r1 */
856
857 /* Copy from the original to the trampoline. */
858 li r5,INT_FRAME_SIZE/4 /* size: INT_FRAME_SIZE */
859 li r6,0 /* start offset: 0 */
860 mtctr r5
8612: lwzx r0,r6,r4
862 stwx r0,r6,r3
863 addi r6,r6,4
864 bdnz 2b
865
866 /* Do real store operation to complete stwu */
867 lwz r5,GPR1(r1)
868 stw r8,0(r5)
869
870 /* Clear _TIF_EMULATE_STACK_STORE flag */
871 lis r11,_TIF_EMULATE_STACK_STORE@h
872 addi r5,r9,TI_FLAGS
8730: lwarx r8,0,r5
874 andc r8,r8,r11
875#ifdef CONFIG_IBM405_ERR77
876 dcbt 0,r5
877#endif
878 stwcx. r8,0,r5
879 bne- 0b
8801:
881
882#ifdef CONFIG_PREEMPT
883 /* check current_thread_info->preempt_count */
9994a338
PM
884 lwz r0,TI_PREEMPT(r9)
885 cmpwi 0,r0,0 /* if non-zero, just restore regs and return */
886 bne restore
a9c4e541 887 andi. r8,r8,_TIF_NEED_RESCHED
9994a338 888 beq+ restore
a9c4e541 889 lwz r3,_MSR(r1)
9994a338
PM
890 andi. r0,r3,MSR_EE /* interrupts off? */
891 beq restore /* don't schedule if so */
5d38902c
BH
892#ifdef CONFIG_TRACE_IRQFLAGS
893 /* Lockdep thinks irqs are enabled, we need to call
894 * preempt_schedule_irq with IRQs off, so we inform lockdep
895 * now that we -did- turn them off already
896 */
897 bl trace_hardirqs_off
898#endif
9994a338 8991: bl preempt_schedule_irq
9778b696 900 CURRENT_THREAD_INFO(r9, r1)
9994a338
PM
901 lwz r3,TI_FLAGS(r9)
902 andi. r0,r3,_TIF_NEED_RESCHED
903 bne- 1b
5d38902c
BH
904#ifdef CONFIG_TRACE_IRQFLAGS
905 /* And now, to properly rebalance the above, we tell lockdep they
906 * are being turned back on, which will happen when we return
907 */
908 bl trace_hardirqs_on
909#endif
9994a338
PM
910#endif /* CONFIG_PREEMPT */
911
912 /* interrupts are hard-disabled at this point */
913restore:
b98ac05d 914#ifdef CONFIG_44x
e7f75ad0
DK
915BEGIN_MMU_FTR_SECTION
916 b 1f
917END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
b98ac05d
BH
918 lis r4,icache_44x_need_flush@ha
919 lwz r5,icache_44x_need_flush@l(r4)
920 cmplwi cr0,r5,0
921 beq+ 1f
922 li r6,0
923 iccci r0,r0
924 stw r6,icache_44x_need_flush@l(r4)
9251:
926#endif /* CONFIG_44x */
5d38902c
BH
927
928 lwz r9,_MSR(r1)
929#ifdef CONFIG_TRACE_IRQFLAGS
930 /* Lockdep doesn't know about the fact that IRQs are temporarily turned
931 * off in this assembly code while peeking at TI_FLAGS() and such. However
932 * we need to inform it if the exception turned interrupts off, and we
933 * are about to trun them back on.
934 *
935 * The problem here sadly is that we don't know whether the exceptions was
936 * one that turned interrupts off or not. So we always tell lockdep about
937 * turning them on here when we go back to wherever we came from with EE
938 * on, even if that may meen some redudant calls being tracked. Maybe later
939 * we could encode what the exception did somewhere or test the exception
940 * type in the pt_regs but that sounds overkill
941 */
942 andi. r10,r9,MSR_EE
943 beq 1f
06ca2188
SR
944 /*
945 * Since the ftrace irqsoff latency trace checks CALLER_ADDR1,
946 * which is the stack frame here, we need to force a stack frame
947 * in case we came from user space.
948 */
949 stwu r1,-32(r1)
950 mflr r0
951 stw r0,4(r1)
952 stwu r1,-32(r1)
5d38902c 953 bl trace_hardirqs_on
06ca2188
SR
954 lwz r1,0(r1)
955 lwz r1,0(r1)
5d38902c
BH
956 lwz r9,_MSR(r1)
9571:
958#endif /* CONFIG_TRACE_IRQFLAGS */
959
9994a338
PM
960 lwz r0,GPR0(r1)
961 lwz r2,GPR2(r1)
962 REST_4GPRS(3, r1)
963 REST_2GPRS(7, r1)
964
965 lwz r10,_XER(r1)
966 lwz r11,_CTR(r1)
967 mtspr SPRN_XER,r10
968 mtctr r11
969
970 PPC405_ERR77(0,r1)
b64f87c1
BB
971BEGIN_FTR_SECTION
972 lwarx r11,0,r1
973END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
9994a338
PM
974 stwcx. r0,0,r1 /* to clear the reservation */
975
976#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
9994a338
PM
977 andi. r10,r9,MSR_RI /* check if this exception occurred */
978 beql nonrecoverable /* at a bad place (MSR:RI = 0) */
979
980 lwz r10,_CCR(r1)
981 lwz r11,_LINK(r1)
982 mtcrf 0xFF,r10
983 mtlr r11
984
985 /*
986 * Once we put values in SRR0 and SRR1, we are in a state
987 * where exceptions are not recoverable, since taking an
988 * exception will trash SRR0 and SRR1. Therefore we clear the
989 * MSR:RI bit to indicate this. If we do take an exception,
990 * we can't return to the point of the exception but we
991 * can restart the exception exit path at the label
992 * exc_exit_restart below. -- paulus
993 */
994 LOAD_MSR_KERNEL(r10,MSR_KERNEL & ~MSR_RI)
995 SYNC
996 MTMSRD(r10) /* clear the RI bit */
997 .globl exc_exit_restart
998exc_exit_restart:
9994a338 999 lwz r12,_NIP(r1)
cd99ddbe 1000#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
75b82472
CL
1001 mtspr SPRN_NRI, r0
1002#endif
9994a338
PM
1003 mtspr SPRN_SRR0,r12
1004 mtspr SPRN_SRR1,r9
1005 REST_4GPRS(9, r1)
1006 lwz r1,GPR1(r1)
1007 .globl exc_exit_restart_end
1008exc_exit_restart_end:
1009 SYNC
1010 RFI
1011
1012#else /* !(CONFIG_4xx || CONFIG_BOOKE) */
1013 /*
1014 * This is a bit different on 4xx/Book-E because it doesn't have
1015 * the RI bit in the MSR.
1016 * The TLB miss handler checks if we have interrupted
1017 * the exception exit path and restarts it if so
1018 * (well maybe one day it will... :).
1019 */
1020 lwz r11,_LINK(r1)
1021 mtlr r11
1022 lwz r10,_CCR(r1)
1023 mtcrf 0xff,r10
1024 REST_2GPRS(9, r1)
1025 .globl exc_exit_restart
1026exc_exit_restart:
1027 lwz r11,_NIP(r1)
1028 lwz r12,_MSR(r1)
1029exc_exit_start:
1030 mtspr SPRN_SRR0,r11
1031 mtspr SPRN_SRR1,r12
1032 REST_2GPRS(11, r1)
1033 lwz r1,GPR1(r1)
1034 .globl exc_exit_restart_end
1035exc_exit_restart_end:
1036 PPC405_ERR77_SYNC
1037 rfi
1038 b . /* prevent prefetch past rfi */
1039
1040/*
1041 * Returning from a critical interrupt in user mode doesn't need
1042 * to be any different from a normal exception. For a critical
1043 * interrupt in the kernel, we just return (without checking for
1044 * preemption) since the interrupt may have happened at some crucial
1045 * place (e.g. inside the TLB miss handler), and because we will be
1046 * running with r1 pointing into critical_stack, not the current
1047 * process's kernel stack (and therefore current_thread_info() will
1048 * give the wrong answer).
1049 * We have to restore various SPRs that may have been in use at the
1050 * time of the critical interrupt.
1051 *
1052 */
1053#ifdef CONFIG_40x
1054#define PPC_40x_TURN_OFF_MSR_DR \
1055 /* avoid any possible TLB misses here by turning off MSR.DR, we \
1056 * assume the instructions here are mapped by a pinned TLB entry */ \
1057 li r10,MSR_IR; \
1058 mtmsr r10; \
1059 isync; \
1060 tophys(r1, r1);
1061#else
1062#define PPC_40x_TURN_OFF_MSR_DR
1063#endif
1064
1065#define RET_FROM_EXC_LEVEL(exc_lvl_srr0, exc_lvl_srr1, exc_lvl_rfi) \
1066 REST_NVGPRS(r1); \
1067 lwz r3,_MSR(r1); \
1068 andi. r3,r3,MSR_PR; \
1069 LOAD_MSR_KERNEL(r10,MSR_KERNEL); \
1070 bne user_exc_return; \
1071 lwz r0,GPR0(r1); \
1072 lwz r2,GPR2(r1); \
1073 REST_4GPRS(3, r1); \
1074 REST_2GPRS(7, r1); \
1075 lwz r10,_XER(r1); \
1076 lwz r11,_CTR(r1); \
1077 mtspr SPRN_XER,r10; \
1078 mtctr r11; \
1079 PPC405_ERR77(0,r1); \
1080 stwcx. r0,0,r1; /* to clear the reservation */ \
1081 lwz r11,_LINK(r1); \
1082 mtlr r11; \
1083 lwz r10,_CCR(r1); \
1084 mtcrf 0xff,r10; \
1085 PPC_40x_TURN_OFF_MSR_DR; \
1086 lwz r9,_DEAR(r1); \
1087 lwz r10,_ESR(r1); \
1088 mtspr SPRN_DEAR,r9; \
1089 mtspr SPRN_ESR,r10; \
1090 lwz r11,_NIP(r1); \
1091 lwz r12,_MSR(r1); \
1092 mtspr exc_lvl_srr0,r11; \
1093 mtspr exc_lvl_srr1,r12; \
1094 lwz r9,GPR9(r1); \
1095 lwz r12,GPR12(r1); \
1096 lwz r10,GPR10(r1); \
1097 lwz r11,GPR11(r1); \
1098 lwz r1,GPR1(r1); \
1099 PPC405_ERR77_SYNC; \
1100 exc_lvl_rfi; \
1101 b .; /* prevent prefetch past exc_lvl_rfi */
1102
fca622c5
KG
1103#define RESTORE_xSRR(exc_lvl_srr0, exc_lvl_srr1) \
1104 lwz r9,_##exc_lvl_srr0(r1); \
1105 lwz r10,_##exc_lvl_srr1(r1); \
1106 mtspr SPRN_##exc_lvl_srr0,r9; \
1107 mtspr SPRN_##exc_lvl_srr1,r10;
1108
70fe3af8 1109#if defined(CONFIG_PPC_BOOK3E_MMU)
fca622c5
KG
1110#ifdef CONFIG_PHYS_64BIT
1111#define RESTORE_MAS7 \
1112 lwz r11,MAS7(r1); \
1113 mtspr SPRN_MAS7,r11;
1114#else
1115#define RESTORE_MAS7
1116#endif /* CONFIG_PHYS_64BIT */
1117#define RESTORE_MMU_REGS \
1118 lwz r9,MAS0(r1); \
1119 lwz r10,MAS1(r1); \
1120 lwz r11,MAS2(r1); \
1121 mtspr SPRN_MAS0,r9; \
1122 lwz r9,MAS3(r1); \
1123 mtspr SPRN_MAS1,r10; \
1124 lwz r10,MAS6(r1); \
1125 mtspr SPRN_MAS2,r11; \
1126 mtspr SPRN_MAS3,r9; \
1127 mtspr SPRN_MAS6,r10; \
1128 RESTORE_MAS7;
1129#elif defined(CONFIG_44x)
1130#define RESTORE_MMU_REGS \
1131 lwz r9,MMUCR(r1); \
1132 mtspr SPRN_MMUCR,r9;
1133#else
1134#define RESTORE_MMU_REGS
1135#endif
1136
1137#ifdef CONFIG_40x
9994a338
PM
1138 .globl ret_from_crit_exc
1139ret_from_crit_exc:
ee43eb78 1140 mfspr r9,SPRN_SPRG_THREAD
fca622c5
KG
1141 lis r10,saved_ksp_limit@ha;
1142 lwz r10,saved_ksp_limit@l(r10);
1143 tovirt(r9,r9);
1144 stw r10,KSP_LIMIT(r9)
1145 lis r9,crit_srr0@ha;
1146 lwz r9,crit_srr0@l(r9);
1147 lis r10,crit_srr1@ha;
1148 lwz r10,crit_srr1@l(r10);
1149 mtspr SPRN_SRR0,r9;
1150 mtspr SPRN_SRR1,r10;
16c57b36 1151 RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI)
fca622c5 1152#endif /* CONFIG_40x */
9994a338
PM
1153
1154#ifdef CONFIG_BOOKE
fca622c5
KG
1155 .globl ret_from_crit_exc
1156ret_from_crit_exc:
ee43eb78 1157 mfspr r9,SPRN_SPRG_THREAD
fca622c5
KG
1158 lwz r10,SAVED_KSP_LIMIT(r1)
1159 stw r10,KSP_LIMIT(r9)
1160 RESTORE_xSRR(SRR0,SRR1);
1161 RESTORE_MMU_REGS;
16c57b36 1162 RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI)
fca622c5 1163
9994a338
PM
1164 .globl ret_from_debug_exc
1165ret_from_debug_exc:
ee43eb78 1166 mfspr r9,SPRN_SPRG_THREAD
fca622c5
KG
1167 lwz r10,SAVED_KSP_LIMIT(r1)
1168 stw r10,KSP_LIMIT(r9)
1169 lwz r9,THREAD_INFO-THREAD(r9)
9778b696 1170 CURRENT_THREAD_INFO(r10, r1)
fca622c5
KG
1171 lwz r10,TI_PREEMPT(r10)
1172 stw r10,TI_PREEMPT(r9)
1173 RESTORE_xSRR(SRR0,SRR1);
1174 RESTORE_xSRR(CSRR0,CSRR1);
1175 RESTORE_MMU_REGS;
16c57b36 1176 RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, PPC_RFDI)
9994a338
PM
1177
1178 .globl ret_from_mcheck_exc
1179ret_from_mcheck_exc:
ee43eb78 1180 mfspr r9,SPRN_SPRG_THREAD
fca622c5
KG
1181 lwz r10,SAVED_KSP_LIMIT(r1)
1182 stw r10,KSP_LIMIT(r9)
1183 RESTORE_xSRR(SRR0,SRR1);
1184 RESTORE_xSRR(CSRR0,CSRR1);
1185 RESTORE_xSRR(DSRR0,DSRR1);
1186 RESTORE_MMU_REGS;
16c57b36 1187 RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, PPC_RFMCI)
9994a338
PM
1188#endif /* CONFIG_BOOKE */
1189
1190/*
1191 * Load the DBCR0 value for a task that is being ptraced,
1192 * having first saved away the global DBCR0. Note that r0
1193 * has the dbcr0 value to set upon entry to this.
1194 */
1195load_dbcr0:
1196 mfmsr r10 /* first disable debug exceptions */
1197 rlwinm r10,r10,0,~MSR_DE
1198 mtmsr r10
1199 isync
1200 mfspr r10,SPRN_DBCR0
1201 lis r11,global_dbcr0@ha
1202 addi r11,r11,global_dbcr0@l
4eaddb4d 1203#ifdef CONFIG_SMP
9778b696 1204 CURRENT_THREAD_INFO(r9, r1)
4eaddb4d
KG
1205 lwz r9,TI_CPU(r9)
1206 slwi r9,r9,3
1207 add r11,r11,r9
1208#endif
9994a338
PM
1209 stw r10,0(r11)
1210 mtspr SPRN_DBCR0,r0
1211 lwz r10,4(r11)
1212 addi r10,r10,1
1213 stw r10,4(r11)
1214 li r11,-1
1215 mtspr SPRN_DBSR,r11 /* clear all pending debug events */
1216 blr
1217
991eb43a
KG
1218 .section .bss
1219 .align 4
1220global_dbcr0:
4eaddb4d 1221 .space 8*NR_CPUS
991eb43a 1222 .previous
9994a338
PM
1223#endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
1224
1225do_work: /* r10 contains MSR_KERNEL here */
1226 andi. r0,r9,_TIF_NEED_RESCHED
1227 beq do_user_signal
1228
1229do_resched: /* r10 contains MSR_KERNEL here */
5d38902c
BH
1230 /* Note: We don't need to inform lockdep that we are enabling
1231 * interrupts here. As far as it knows, they are already enabled
1232 */
9994a338
PM
1233 ori r10,r10,MSR_EE
1234 SYNC
1235 MTMSRD(r10) /* hard-enable interrupts */
1236 bl schedule
1237recheck:
5d38902c
BH
1238 /* Note: And we don't tell it we are disabling them again
1239 * neither. Those disable/enable cycles used to peek at
1240 * TI_FLAGS aren't advertised.
1241 */
9994a338
PM
1242 LOAD_MSR_KERNEL(r10,MSR_KERNEL)
1243 SYNC
1244 MTMSRD(r10) /* disable interrupts */
9778b696 1245 CURRENT_THREAD_INFO(r9, r1)
9994a338
PM
1246 lwz r9,TI_FLAGS(r9)
1247 andi. r0,r9,_TIF_NEED_RESCHED
1248 bne- do_resched
7a10174e 1249 andi. r0,r9,_TIF_USER_WORK_MASK
9994a338
PM
1250 beq restore_user
1251do_user_signal: /* r10 contains MSR_KERNEL here */
1252 ori r10,r10,MSR_EE
1253 SYNC
1254 MTMSRD(r10) /* hard-enable interrupts */
1255 /* save r13-r31 in the exception frame, if not already done */
d73e0c99 1256 lwz r3,_TRAP(r1)
9994a338
PM
1257 andi. r0,r3,1
1258 beq 2f
1259 SAVE_NVGPRS(r1)
1260 rlwinm r3,r3,0,0,30
d73e0c99 1261 stw r3,_TRAP(r1)
7d6d637d
RM
12622: addi r3,r1,STACK_FRAME_OVERHEAD
1263 mr r4,r9
18b246fa 1264 bl do_notify_resume
9994a338
PM
1265 REST_NVGPRS(r1)
1266 b recheck
1267
1268/*
1269 * We come here when we are at the end of handling an exception
1270 * that occurred at a place where taking an exception will lose
1271 * state information, such as the contents of SRR0 and SRR1.
1272 */
1273nonrecoverable:
1274 lis r10,exc_exit_restart_end@ha
1275 addi r10,r10,exc_exit_restart_end@l
1276 cmplw r12,r10
1277 bge 3f
1278 lis r11,exc_exit_restart@ha
1279 addi r11,r11,exc_exit_restart@l
1280 cmplw r12,r11
1281 blt 3f
1282 lis r10,ee_restarts@ha
1283 lwz r12,ee_restarts@l(r10)
1284 addi r12,r12,1
1285 stw r12,ee_restarts@l(r10)
1286 mr r12,r11 /* restart at exc_exit_restart */
1287 blr
12883: /* OK, we can't recover, kill this process */
1289 /* but the 601 doesn't implement the RI bit, so assume it's OK */
1290BEGIN_FTR_SECTION
1291 blr
1292END_FTR_SECTION_IFSET(CPU_FTR_601)
d73e0c99 1293 lwz r3,_TRAP(r1)
9994a338
PM
1294 andi. r0,r3,1
1295 beq 4f
1296 SAVE_NVGPRS(r1)
1297 rlwinm r3,r3,0,0,30
d73e0c99 1298 stw r3,_TRAP(r1)
9994a338 12994: addi r3,r1,STACK_FRAME_OVERHEAD
51423a9c 1300 bl unrecoverable_exception
9994a338
PM
1301 /* shouldn't return */
1302 b 4b
1303
991eb43a
KG
1304 .section .bss
1305 .align 2
1306ee_restarts:
1307 .space 4
1308 .previous
9994a338
PM
1309
1310/*
1311 * PROM code for specific machines follows. Put it
1312 * here so it's easy to add arch-specific sections later.
1313 * -- Cort
1314 */
033ef338 1315#ifdef CONFIG_PPC_RTAS
9994a338
PM
1316/*
1317 * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
1318 * called with the MMU off.
1319 */
1320_GLOBAL(enter_rtas)
1321 stwu r1,-INT_FRAME_SIZE(r1)
1322 mflr r0
1323 stw r0,INT_FRAME_SIZE+4(r1)
e58c3495 1324 LOAD_REG_ADDR(r4, rtas)
9994a338
PM
1325 lis r6,1f@ha /* physical return address for rtas */
1326 addi r6,r6,1f@l
1327 tophys(r6,r6)
1328 tophys(r7,r1)
033ef338
PM
1329 lwz r8,RTASENTRY(r4)
1330 lwz r4,RTASBASE(r4)
9994a338
PM
1331 mfmsr r9
1332 stw r9,8(r1)
1333 LOAD_MSR_KERNEL(r0,MSR_KERNEL)
1334 SYNC /* disable interrupts so SRR0/1 */
1335 MTMSRD(r0) /* don't get trashed */
1336 li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
1337 mtlr r6
ee43eb78 1338 mtspr SPRN_SPRG_RTAS,r7
9994a338
PM
1339 mtspr SPRN_SRR0,r8
1340 mtspr SPRN_SRR1,r9
1341 RFI
13421: tophys(r9,r1)
1343 lwz r8,INT_FRAME_SIZE+4(r9) /* get return address */
1344 lwz r9,8(r9) /* original msr value */
9994a338
PM
1345 addi r1,r1,INT_FRAME_SIZE
1346 li r0,0
ee43eb78 1347 mtspr SPRN_SPRG_RTAS,r0
9994a338
PM
1348 mtspr SPRN_SRR0,r8
1349 mtspr SPRN_SRR1,r9
1350 RFI /* return to caller */
1351
1352 .globl machine_check_in_rtas
1353machine_check_in_rtas:
1354 twi 31,0,0
1355 /* XXX load up BATs and panic */
1356
033ef338 1357#endif /* CONFIG_PPC_RTAS */