xref: /openbmc/linux/arch/powerpc/kernel/entry_32.S (revision 87c2ce3b)
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
22#include <linux/config.h>
23#include <linux/errno.h>
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>
34
35#undef SHOW_SYSCALLS
36#undef SHOW_SYSCALLS_TASK
37
38/*
39 * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE.
40 */
41#if MSR_KERNEL >= 0x10000
42#define LOAD_MSR_KERNEL(r, x)	lis r,(x)@h; ori r,r,(x)@l
43#else
44#define LOAD_MSR_KERNEL(r, x)	li r,(x)
45#endif
46
47#ifdef CONFIG_BOOKE
48#include "head_booke.h"
49#define TRANSFER_TO_HANDLER_EXC_LEVEL(exc_level)	\
50	mtspr	exc_level##_SPRG,r8;			\
51	BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);		\
52	lwz	r0,GPR10-INT_FRAME_SIZE(r8);		\
53	stw	r0,GPR10(r11);				\
54	lwz	r0,GPR11-INT_FRAME_SIZE(r8);		\
55	stw	r0,GPR11(r11);				\
56	mfspr	r8,exc_level##_SPRG
57
58	.globl	mcheck_transfer_to_handler
59mcheck_transfer_to_handler:
60	TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK)
61	b	transfer_to_handler_full
62
63	.globl	debug_transfer_to_handler
64debug_transfer_to_handler:
65	TRANSFER_TO_HANDLER_EXC_LEVEL(DEBUG)
66	b	transfer_to_handler_full
67
68	.globl	crit_transfer_to_handler
69crit_transfer_to_handler:
70	TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT)
71	/* fall through */
72#endif
73
74#ifdef CONFIG_40x
75	.globl	crit_transfer_to_handler
76crit_transfer_to_handler:
77	lwz	r0,crit_r10@l(0)
78	stw	r0,GPR10(r11)
79	lwz	r0,crit_r11@l(0)
80	stw	r0,GPR11(r11)
81	/* fall through */
82#endif
83
84/*
85 * This code finishes saving the registers to the exception frame
86 * and jumps to the appropriate handler for the exception, turning
87 * on address translation.
88 * Note that we rely on the caller having set cr0.eq iff the exception
89 * occurred in kernel mode (i.e. MSR:PR = 0).
90 */
91	.globl	transfer_to_handler_full
92transfer_to_handler_full:
93	SAVE_NVGPRS(r11)
94	/* fall through */
95
96	.globl	transfer_to_handler
97transfer_to_handler:
98	stw	r2,GPR2(r11)
99	stw	r12,_NIP(r11)
100	stw	r9,_MSR(r11)
101	andi.	r2,r9,MSR_PR
102	mfctr	r12
103	mfspr	r2,SPRN_XER
104	stw	r12,_CTR(r11)
105	stw	r2,_XER(r11)
106	mfspr	r12,SPRN_SPRG3
107	addi	r2,r12,-THREAD
108	tovirt(r2,r2)			/* set r2 to current */
109	beq	2f			/* if from user, fix up THREAD.regs */
110	addi	r11,r1,STACK_FRAME_OVERHEAD
111	stw	r11,PT_REGS(r12)
112#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
113	/* Check to see if the dbcr0 register is set up to debug.  Use the
114	   single-step bit to do this. */
115	lwz	r12,THREAD_DBCR0(r12)
116	andis.	r12,r12,DBCR0_IC@h
117	beq+	3f
118	/* From user and task is ptraced - load up global dbcr0 */
119	li	r12,-1			/* clear all pending debug events */
120	mtspr	SPRN_DBSR,r12
121	lis	r11,global_dbcr0@ha
122	tophys(r11,r11)
123	addi	r11,r11,global_dbcr0@l
124	lwz	r12,0(r11)
125	mtspr	SPRN_DBCR0,r12
126	lwz	r12,4(r11)
127	addi	r12,r12,-1
128	stw	r12,4(r11)
129#endif
130	b	3f
1312:	/* if from kernel, check interrupted DOZE/NAP mode and
132         * check for stack overflow
133         */
134#ifdef CONFIG_6xx
135	mfspr	r11,SPRN_HID0
136	mtcr	r11
137BEGIN_FTR_SECTION
138	bt-	8,power_save_6xx_restore	/* Check DOZE */
139END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
140BEGIN_FTR_SECTION
141	bt-	9,power_save_6xx_restore	/* Check NAP */
142END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
143#endif /* CONFIG_6xx */
144	.globl transfer_to_handler_cont
145transfer_to_handler_cont:
146	lwz	r11,THREAD_INFO-THREAD(r12)
147	cmplw	r1,r11			/* if r1 <= current->thread_info */
148	ble-	stack_ovf		/* then the kernel stack overflowed */
1493:
150	mflr	r9
151	lwz	r11,0(r9)		/* virtual address of handler */
152	lwz	r9,4(r9)		/* where to go when done */
153	FIX_SRR1(r10,r12)
154	mtspr	SPRN_SRR0,r11
155	mtspr	SPRN_SRR1,r10
156	mtlr	r9
157	SYNC
158	RFI				/* jump to handler, enable MMU */
159
160/*
161 * On kernel stack overflow, load up an initial stack pointer
162 * and call StackOverflow(regs), which should not return.
163 */
164stack_ovf:
165	/* sometimes we use a statically-allocated stack, which is OK. */
166	lis	r11,_end@h
167	ori	r11,r11,_end@l
168	cmplw	r1,r11
169	ble	3b			/* r1 <= &_end is OK */
170	SAVE_NVGPRS(r11)
171	addi	r3,r1,STACK_FRAME_OVERHEAD
172	lis	r1,init_thread_union@ha
173	addi	r1,r1,init_thread_union@l
174	addi	r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
175	lis	r9,StackOverflow@ha
176	addi	r9,r9,StackOverflow@l
177	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
178	FIX_SRR1(r10,r12)
179	mtspr	SPRN_SRR0,r9
180	mtspr	SPRN_SRR1,r10
181	SYNC
182	RFI
183
184/*
185 * Handle a system call.
186 */
187	.stabs	"arch/powerpc/kernel/",N_SO,0,0,0f
188	.stabs	"entry_32.S",N_SO,0,0,0f
1890:
190
191_GLOBAL(DoSyscall)
192	stw	r0,THREAD+LAST_SYSCALL(r2)
193	stw	r3,ORIG_GPR3(r1)
194	li	r12,0
195	stw	r12,RESULT(r1)
196	lwz	r11,_CCR(r1)	/* Clear SO bit in CR */
197	rlwinm	r11,r11,0,4,2
198	stw	r11,_CCR(r1)
199#ifdef SHOW_SYSCALLS
200	bl	do_show_syscall
201#endif /* SHOW_SYSCALLS */
202	rlwinm	r10,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
203	lwz	r11,TI_FLAGS(r10)
204	andi.	r11,r11,_TIF_SYSCALL_T_OR_A
205	bne-	syscall_dotrace
206syscall_dotrace_cont:
207	cmplwi	0,r0,NR_syscalls
208	lis	r10,sys_call_table@h
209	ori	r10,r10,sys_call_table@l
210	slwi	r0,r0,2
211	bge-	66f
212	lwzx	r10,r10,r0	/* Fetch system call handler [ptr] */
213	mtlr	r10
214	addi	r9,r1,STACK_FRAME_OVERHEAD
215	PPC440EP_ERR42
216	blrl			/* Call handler */
217	.globl	ret_from_syscall
218ret_from_syscall:
219#ifdef SHOW_SYSCALLS
220	bl	do_show_syscall_exit
221#endif
222	mr	r6,r3
223	rlwinm	r12,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
224	/* disable interrupts so current_thread_info()->flags can't change */
225	LOAD_MSR_KERNEL(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
226	SYNC
227	MTMSRD(r10)
228	lwz	r9,TI_FLAGS(r12)
229	li	r8,-_LAST_ERRNO
230	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
231	bne-	syscall_exit_work
232	cmplw	0,r3,r8
233	blt+	syscall_exit_cont
234	lwz	r11,_CCR(r1)			/* Load CR */
235	neg	r3,r3
236	oris	r11,r11,0x1000	/* Set SO bit in CR */
237	stw	r11,_CCR(r1)
238syscall_exit_cont:
239#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
240	/* If the process has its own DBCR0 value, load it up.  The single
241	   step bit tells us that dbcr0 should be loaded. */
242	lwz	r0,THREAD+THREAD_DBCR0(r2)
243	andis.	r10,r0,DBCR0_IC@h
244	bnel-	load_dbcr0
245#endif
246	stwcx.	r0,0,r1			/* to clear the reservation */
247	lwz	r4,_LINK(r1)
248	lwz	r5,_CCR(r1)
249	mtlr	r4
250	mtcr	r5
251	lwz	r7,_NIP(r1)
252	lwz	r8,_MSR(r1)
253	FIX_SRR1(r8, r0)
254	lwz	r2,GPR2(r1)
255	lwz	r1,GPR1(r1)
256	mtspr	SPRN_SRR0,r7
257	mtspr	SPRN_SRR1,r8
258	SYNC
259	RFI
260
26166:	li	r3,-ENOSYS
262	b	ret_from_syscall
263
264	.globl	ret_from_fork
265ret_from_fork:
266	REST_NVGPRS(r1)
267	bl	schedule_tail
268	li	r3,0
269	b	ret_from_syscall
270
271/* Traced system call support */
272syscall_dotrace:
273	SAVE_NVGPRS(r1)
274	li	r0,0xc00
275	stw	r0,_TRAP(r1)
276	addi	r3,r1,STACK_FRAME_OVERHEAD
277	bl	do_syscall_trace_enter
278	lwz	r0,GPR0(r1)	/* Restore original registers */
279	lwz	r3,GPR3(r1)
280	lwz	r4,GPR4(r1)
281	lwz	r5,GPR5(r1)
282	lwz	r6,GPR6(r1)
283	lwz	r7,GPR7(r1)
284	lwz	r8,GPR8(r1)
285	REST_NVGPRS(r1)
286	b	syscall_dotrace_cont
287
288syscall_exit_work:
289	andi.	r0,r9,_TIF_RESTOREALL
290	bne-	2f
291	cmplw	0,r3,r8
292	blt+	1f
293	andi.	r0,r9,_TIF_NOERROR
294	bne-	1f
295	lwz	r11,_CCR(r1)			/* Load CR */
296	neg	r3,r3
297	oris	r11,r11,0x1000	/* Set SO bit in CR */
298	stw	r11,_CCR(r1)
299
3001:	stw	r6,RESULT(r1)	/* Save result */
301	stw	r3,GPR3(r1)	/* Update return value */
3022:	andi.	r0,r9,(_TIF_PERSYSCALL_MASK)
303	beq	4f
304
305	/* Clear per-syscall TIF flags if any are set, but _leave_
306	_TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
307	yet.  */
308
309	li	r11,_TIF_PERSYSCALL_MASK
310	addi	r12,r12,TI_FLAGS
3113:	lwarx	r8,0,r12
312	andc	r8,r8,r11
313#ifdef CONFIG_IBM405_ERR77
314	dcbt	0,r12
315#endif
316	stwcx.	r8,0,r12
317	bne-	3b
318	subi	r12,r12,TI_FLAGS
319
3204:	/* Anything which requires enabling interrupts? */
321	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
322	beq	7f
323
324	/* Save NVGPRS if they're not saved already */
325	lwz	r4,_TRAP(r1)
326	andi.	r4,r4,1
327	beq	5f
328	SAVE_NVGPRS(r1)
329	li	r4,0xc00
330	stw	r4,_TRAP(r1)
331
332	/* Re-enable interrupts */
3335:	ori	r10,r10,MSR_EE
334	SYNC
335	MTMSRD(r10)
336
337	andi.	r0,r9,_TIF_SAVE_NVGPRS
338	bne	save_user_nvgprs
339
340save_user_nvgprs_cont:
341	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
342	beq	7f
343
344	addi	r3,r1,STACK_FRAME_OVERHEAD
345	bl	do_syscall_trace_leave
346	REST_NVGPRS(r1)
347
3486:	lwz	r3,GPR3(r1)
349	LOAD_MSR_KERNEL(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
350	SYNC
351	MTMSRD(r10)		/* disable interrupts again */
352	rlwinm	r12,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
353	lwz	r9,TI_FLAGS(r12)
3547:
355	andi.	r0,r9,_TIF_NEED_RESCHED
356	bne	8f
357	lwz	r5,_MSR(r1)
358	andi.	r5,r5,MSR_PR
359	beq	ret_from_except
360	andi.	r0,r9,_TIF_SIGPENDING
361	beq	ret_from_except
362	b	do_user_signal
3638:
364	ori	r10,r10,MSR_EE
365	SYNC
366	MTMSRD(r10)		/* re-enable interrupts */
367	bl	schedule
368	b	6b
369
370save_user_nvgprs:
371	lwz	r8,TI_SIGFRAME(r12)
372
373.macro savewords start, end
374  1:	stw \start,4*(\start)(r8)
375	.section __ex_table,"a"
376	.align	2
377	.long	1b,save_user_nvgprs_fault
378	.previous
379	.if \end - \start
380	savewords "(\start+1)",\end
381	.endif
382.endm
383	savewords 14,31
384	b	save_user_nvgprs_cont
385
386
387save_user_nvgprs_fault:
388	li	r3,11		/* SIGSEGV */
389	lwz	r4,TI_TASK(r12)
390	bl	force_sigsegv
391
392	rlwinm	r12,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
393	lwz	r9,TI_FLAGS(r12)
394	b	save_user_nvgprs_cont
395
396#ifdef SHOW_SYSCALLS
397do_show_syscall:
398#ifdef SHOW_SYSCALLS_TASK
399	lis	r11,show_syscalls_task@ha
400	lwz	r11,show_syscalls_task@l(r11)
401	cmp	0,r2,r11
402	bnelr
403#endif
404	stw	r31,GPR31(r1)
405	mflr	r31
406	lis	r3,7f@ha
407	addi	r3,r3,7f@l
408	lwz	r4,GPR0(r1)
409	lwz	r5,GPR3(r1)
410	lwz	r6,GPR4(r1)
411	lwz	r7,GPR5(r1)
412	lwz	r8,GPR6(r1)
413	lwz	r9,GPR7(r1)
414	bl	printk
415	lis	r3,77f@ha
416	addi	r3,r3,77f@l
417	lwz	r4,GPR8(r1)
418	mr	r5,r2
419	bl	printk
420	lwz	r0,GPR0(r1)
421	lwz	r3,GPR3(r1)
422	lwz	r4,GPR4(r1)
423	lwz	r5,GPR5(r1)
424	lwz	r6,GPR6(r1)
425	lwz	r7,GPR7(r1)
426	lwz	r8,GPR8(r1)
427	mtlr	r31
428	lwz	r31,GPR31(r1)
429	blr
430
431do_show_syscall_exit:
432#ifdef SHOW_SYSCALLS_TASK
433	lis	r11,show_syscalls_task@ha
434	lwz	r11,show_syscalls_task@l(r11)
435	cmp	0,r2,r11
436	bnelr
437#endif
438	stw	r31,GPR31(r1)
439	mflr	r31
440	stw	r3,RESULT(r1)	/* Save result */
441	mr	r4,r3
442	lis	r3,79f@ha
443	addi	r3,r3,79f@l
444	bl	printk
445	lwz	r3,RESULT(r1)
446	mtlr	r31
447	lwz	r31,GPR31(r1)
448	blr
449
4507:	.string	"syscall %d(%x, %x, %x, %x, %x, "
45177:	.string	"%x), current=%p\n"
45279:	.string	" -> %x\n"
453	.align	2,0
454
455#ifdef SHOW_SYSCALLS_TASK
456	.data
457	.globl	show_syscalls_task
458show_syscalls_task:
459	.long	-1
460	.text
461#endif
462#endif /* SHOW_SYSCALLS */
463
464/*
465 * The fork/clone functions need to copy the full register set into
466 * the child process. Therefore we need to save all the nonvolatile
467 * registers (r13 - r31) before calling the C code.
468 */
469	.globl	ppc_fork
470ppc_fork:
471	SAVE_NVGPRS(r1)
472	lwz	r0,_TRAP(r1)
473	rlwinm	r0,r0,0,0,30		/* clear LSB to indicate full */
474	stw	r0,_TRAP(r1)		/* register set saved */
475	b	sys_fork
476
477	.globl	ppc_vfork
478ppc_vfork:
479	SAVE_NVGPRS(r1)
480	lwz	r0,_TRAP(r1)
481	rlwinm	r0,r0,0,0,30		/* clear LSB to indicate full */
482	stw	r0,_TRAP(r1)		/* register set saved */
483	b	sys_vfork
484
485	.globl	ppc_clone
486ppc_clone:
487	SAVE_NVGPRS(r1)
488	lwz	r0,_TRAP(r1)
489	rlwinm	r0,r0,0,0,30		/* clear LSB to indicate full */
490	stw	r0,_TRAP(r1)		/* register set saved */
491	b	sys_clone
492
493/*
494 * Top-level page fault handling.
495 * This is in assembler because if do_page_fault tells us that
496 * it is a bad kernel page fault, we want to save the non-volatile
497 * registers before calling bad_page_fault.
498 */
499	.globl	handle_page_fault
500handle_page_fault:
501	stw	r4,_DAR(r1)
502	addi	r3,r1,STACK_FRAME_OVERHEAD
503	bl	do_page_fault
504	cmpwi	r3,0
505	beq+	ret_from_except
506	SAVE_NVGPRS(r1)
507	lwz	r0,_TRAP(r1)
508	clrrwi	r0,r0,1
509	stw	r0,_TRAP(r1)
510	mr	r5,r3
511	addi	r3,r1,STACK_FRAME_OVERHEAD
512	lwz	r4,_DAR(r1)
513	bl	bad_page_fault
514	b	ret_from_except_full
515
516/*
517 * This routine switches between two different tasks.  The process
518 * state of one is saved on its kernel stack.  Then the state
519 * of the other is restored from its kernel stack.  The memory
520 * management hardware is updated to the second process's state.
521 * Finally, we can return to the second process.
522 * On entry, r3 points to the THREAD for the current task, r4
523 * points to the THREAD for the new task.
524 *
525 * This routine is always called with interrupts disabled.
526 *
527 * Note: there are two ways to get to the "going out" portion
528 * of this code; either by coming in via the entry (_switch)
529 * or via "fork" which must set up an environment equivalent
530 * to the "_switch" path.  If you change this , you'll have to
531 * change the fork code also.
532 *
533 * The code which creates the new task context is in 'copy_thread'
534 * in arch/ppc/kernel/process.c
535 */
536_GLOBAL(_switch)
537	stwu	r1,-INT_FRAME_SIZE(r1)
538	mflr	r0
539	stw	r0,INT_FRAME_SIZE+4(r1)
540	/* r3-r12 are caller saved -- Cort */
541	SAVE_NVGPRS(r1)
542	stw	r0,_NIP(r1)	/* Return to switch caller */
543	mfmsr	r11
544	li	r0,MSR_FP	/* Disable floating-point */
545#ifdef CONFIG_ALTIVEC
546BEGIN_FTR_SECTION
547	oris	r0,r0,MSR_VEC@h	/* Disable altivec */
548	mfspr	r12,SPRN_VRSAVE	/* save vrsave register value */
549	stw	r12,THREAD+THREAD_VRSAVE(r2)
550END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
551#endif /* CONFIG_ALTIVEC */
552#ifdef CONFIG_SPE
553	oris	r0,r0,MSR_SPE@h	 /* Disable SPE */
554	mfspr	r12,SPRN_SPEFSCR /* save spefscr register value */
555	stw	r12,THREAD+THREAD_SPEFSCR(r2)
556#endif /* CONFIG_SPE */
557	and.	r0,r0,r11	/* FP or altivec or SPE enabled? */
558	beq+	1f
559	andc	r11,r11,r0
560	MTMSRD(r11)
561	isync
5621:	stw	r11,_MSR(r1)
563	mfcr	r10
564	stw	r10,_CCR(r1)
565	stw	r1,KSP(r3)	/* Set old stack pointer */
566
567#ifdef CONFIG_SMP
568	/* We need a sync somewhere here to make sure that if the
569	 * previous task gets rescheduled on another CPU, it sees all
570	 * stores it has performed on this one.
571	 */
572	sync
573#endif /* CONFIG_SMP */
574
575	tophys(r0,r4)
576	CLR_TOP32(r0)
577	mtspr	SPRN_SPRG3,r0	/* Update current THREAD phys addr */
578	lwz	r1,KSP(r4)	/* Load new stack pointer */
579
580	/* save the old current 'last' for return value */
581	mr	r3,r2
582	addi	r2,r4,-THREAD	/* Update current */
583
584#ifdef CONFIG_ALTIVEC
585BEGIN_FTR_SECTION
586	lwz	r0,THREAD+THREAD_VRSAVE(r2)
587	mtspr	SPRN_VRSAVE,r0		/* if G4, restore VRSAVE reg */
588END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
589#endif /* CONFIG_ALTIVEC */
590#ifdef CONFIG_SPE
591	lwz	r0,THREAD+THREAD_SPEFSCR(r2)
592	mtspr	SPRN_SPEFSCR,r0		/* restore SPEFSCR reg */
593#endif /* CONFIG_SPE */
594
595	lwz	r0,_CCR(r1)
596	mtcrf	0xFF,r0
597	/* r3-r12 are destroyed -- Cort */
598	REST_NVGPRS(r1)
599
600	lwz	r4,_NIP(r1)	/* Return to _switch caller in new task */
601	mtlr	r4
602	addi	r1,r1,INT_FRAME_SIZE
603	blr
604
605	.globl	fast_exception_return
606fast_exception_return:
607#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
608	andi.	r10,r9,MSR_RI		/* check for recoverable interrupt */
609	beq	1f			/* if not, we've got problems */
610#endif
611
6122:	REST_4GPRS(3, r11)
613	lwz	r10,_CCR(r11)
614	REST_GPR(1, r11)
615	mtcr	r10
616	lwz	r10,_LINK(r11)
617	mtlr	r10
618	REST_GPR(10, r11)
619	mtspr	SPRN_SRR1,r9
620	mtspr	SPRN_SRR0,r12
621	REST_GPR(9, r11)
622	REST_GPR(12, r11)
623	lwz	r11,GPR11(r11)
624	SYNC
625	RFI
626
627#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
628/* check if the exception happened in a restartable section */
6291:	lis	r3,exc_exit_restart_end@ha
630	addi	r3,r3,exc_exit_restart_end@l
631	cmplw	r12,r3
632	bge	3f
633	lis	r4,exc_exit_restart@ha
634	addi	r4,r4,exc_exit_restart@l
635	cmplw	r12,r4
636	blt	3f
637	lis	r3,fee_restarts@ha
638	tophys(r3,r3)
639	lwz	r5,fee_restarts@l(r3)
640	addi	r5,r5,1
641	stw	r5,fee_restarts@l(r3)
642	mr	r12,r4		/* restart at exc_exit_restart */
643	b	2b
644
645	.comm	fee_restarts,4
646
647/* aargh, a nonrecoverable interrupt, panic */
648/* aargh, we don't know which trap this is */
649/* but the 601 doesn't implement the RI bit, so assume it's OK */
6503:
651BEGIN_FTR_SECTION
652	b	2b
653END_FTR_SECTION_IFSET(CPU_FTR_601)
654	li	r10,-1
655	stw	r10,_TRAP(r11)
656	addi	r3,r1,STACK_FRAME_OVERHEAD
657	lis	r10,MSR_KERNEL@h
658	ori	r10,r10,MSR_KERNEL@l
659	bl	transfer_to_handler_full
660	.long	nonrecoverable_exception
661	.long	ret_from_except
662#endif
663
664	.globl	ret_from_except_full
665ret_from_except_full:
666	REST_NVGPRS(r1)
667	/* fall through */
668
669	.globl	ret_from_except
670ret_from_except:
671	/* Hard-disable interrupts so that current_thread_info()->flags
672	 * can't change between when we test it and when we return
673	 * from the interrupt. */
674	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
675	SYNC			/* Some chip revs have problems here... */
676	MTMSRD(r10)		/* disable interrupts */
677
678	lwz	r3,_MSR(r1)	/* Returning to user mode? */
679	andi.	r0,r3,MSR_PR
680	beq	resume_kernel
681
682user_exc_return:		/* r10 contains MSR_KERNEL here */
683	/* Check current_thread_info()->flags */
684	rlwinm	r9,r1,0,0,(31-THREAD_SHIFT)
685	lwz	r9,TI_FLAGS(r9)
686	andi.	r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
687	bne	do_work
688
689restore_user:
690#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
691	/* Check whether this process has its own DBCR0 value.  The single
692	   step bit tells us that dbcr0 should be loaded. */
693	lwz	r0,THREAD+THREAD_DBCR0(r2)
694	andis.	r10,r0,DBCR0_IC@h
695	bnel-	load_dbcr0
696#endif
697
698#ifdef CONFIG_PREEMPT
699	b	restore
700
701/* N.B. the only way to get here is from the beq following ret_from_except. */
702resume_kernel:
703	/* check current_thread_info->preempt_count */
704	rlwinm	r9,r1,0,0,(31-THREAD_SHIFT)
705	lwz	r0,TI_PREEMPT(r9)
706	cmpwi	0,r0,0		/* if non-zero, just restore regs and return */
707	bne	restore
708	lwz	r0,TI_FLAGS(r9)
709	andi.	r0,r0,_TIF_NEED_RESCHED
710	beq+	restore
711	andi.	r0,r3,MSR_EE	/* interrupts off? */
712	beq	restore		/* don't schedule if so */
7131:	bl	preempt_schedule_irq
714	rlwinm	r9,r1,0,0,(31-THREAD_SHIFT)
715	lwz	r3,TI_FLAGS(r9)
716	andi.	r0,r3,_TIF_NEED_RESCHED
717	bne-	1b
718#else
719resume_kernel:
720#endif /* CONFIG_PREEMPT */
721
722	/* interrupts are hard-disabled at this point */
723restore:
724	lwz	r0,GPR0(r1)
725	lwz	r2,GPR2(r1)
726	REST_4GPRS(3, r1)
727	REST_2GPRS(7, r1)
728
729	lwz	r10,_XER(r1)
730	lwz	r11,_CTR(r1)
731	mtspr	SPRN_XER,r10
732	mtctr	r11
733
734	PPC405_ERR77(0,r1)
735	stwcx.	r0,0,r1			/* to clear the reservation */
736
737#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
738	lwz	r9,_MSR(r1)
739	andi.	r10,r9,MSR_RI		/* check if this exception occurred */
740	beql	nonrecoverable		/* at a bad place (MSR:RI = 0) */
741
742	lwz	r10,_CCR(r1)
743	lwz	r11,_LINK(r1)
744	mtcrf	0xFF,r10
745	mtlr	r11
746
747	/*
748	 * Once we put values in SRR0 and SRR1, we are in a state
749	 * where exceptions are not recoverable, since taking an
750	 * exception will trash SRR0 and SRR1.  Therefore we clear the
751	 * MSR:RI bit to indicate this.  If we do take an exception,
752	 * we can't return to the point of the exception but we
753	 * can restart the exception exit path at the label
754	 * exc_exit_restart below.  -- paulus
755	 */
756	LOAD_MSR_KERNEL(r10,MSR_KERNEL & ~MSR_RI)
757	SYNC
758	MTMSRD(r10)		/* clear the RI bit */
759	.globl exc_exit_restart
760exc_exit_restart:
761	lwz	r9,_MSR(r1)
762	lwz	r12,_NIP(r1)
763	FIX_SRR1(r9,r10)
764	mtspr	SPRN_SRR0,r12
765	mtspr	SPRN_SRR1,r9
766	REST_4GPRS(9, r1)
767	lwz	r1,GPR1(r1)
768	.globl exc_exit_restart_end
769exc_exit_restart_end:
770	SYNC
771	RFI
772
773#else /* !(CONFIG_4xx || CONFIG_BOOKE) */
774	/*
775	 * This is a bit different on 4xx/Book-E because it doesn't have
776	 * the RI bit in the MSR.
777	 * The TLB miss handler checks if we have interrupted
778	 * the exception exit path and restarts it if so
779	 * (well maybe one day it will... :).
780	 */
781	lwz	r11,_LINK(r1)
782	mtlr	r11
783	lwz	r10,_CCR(r1)
784	mtcrf	0xff,r10
785	REST_2GPRS(9, r1)
786	.globl exc_exit_restart
787exc_exit_restart:
788	lwz	r11,_NIP(r1)
789	lwz	r12,_MSR(r1)
790exc_exit_start:
791	mtspr	SPRN_SRR0,r11
792	mtspr	SPRN_SRR1,r12
793	REST_2GPRS(11, r1)
794	lwz	r1,GPR1(r1)
795	.globl exc_exit_restart_end
796exc_exit_restart_end:
797	PPC405_ERR77_SYNC
798	rfi
799	b	.			/* prevent prefetch past rfi */
800
801/*
802 * Returning from a critical interrupt in user mode doesn't need
803 * to be any different from a normal exception.  For a critical
804 * interrupt in the kernel, we just return (without checking for
805 * preemption) since the interrupt may have happened at some crucial
806 * place (e.g. inside the TLB miss handler), and because we will be
807 * running with r1 pointing into critical_stack, not the current
808 * process's kernel stack (and therefore current_thread_info() will
809 * give the wrong answer).
810 * We have to restore various SPRs that may have been in use at the
811 * time of the critical interrupt.
812 *
813 */
814#ifdef CONFIG_40x
815#define PPC_40x_TURN_OFF_MSR_DR						    \
816	/* avoid any possible TLB misses here by turning off MSR.DR, we	    \
817	 * assume the instructions here are mapped by a pinned TLB entry */ \
818	li	r10,MSR_IR;						    \
819	mtmsr	r10;							    \
820	isync;								    \
821	tophys(r1, r1);
822#else
823#define PPC_40x_TURN_OFF_MSR_DR
824#endif
825
826#define RET_FROM_EXC_LEVEL(exc_lvl_srr0, exc_lvl_srr1, exc_lvl_rfi)	\
827	REST_NVGPRS(r1);						\
828	lwz	r3,_MSR(r1);						\
829	andi.	r3,r3,MSR_PR;						\
830	LOAD_MSR_KERNEL(r10,MSR_KERNEL);				\
831	bne	user_exc_return;					\
832	lwz	r0,GPR0(r1);						\
833	lwz	r2,GPR2(r1);						\
834	REST_4GPRS(3, r1);						\
835	REST_2GPRS(7, r1);						\
836	lwz	r10,_XER(r1);						\
837	lwz	r11,_CTR(r1);						\
838	mtspr	SPRN_XER,r10;						\
839	mtctr	r11;							\
840	PPC405_ERR77(0,r1);						\
841	stwcx.	r0,0,r1;		/* to clear the reservation */	\
842	lwz	r11,_LINK(r1);						\
843	mtlr	r11;							\
844	lwz	r10,_CCR(r1);						\
845	mtcrf	0xff,r10;						\
846	PPC_40x_TURN_OFF_MSR_DR;					\
847	lwz	r9,_DEAR(r1);						\
848	lwz	r10,_ESR(r1);						\
849	mtspr	SPRN_DEAR,r9;						\
850	mtspr	SPRN_ESR,r10;						\
851	lwz	r11,_NIP(r1);						\
852	lwz	r12,_MSR(r1);						\
853	mtspr	exc_lvl_srr0,r11;					\
854	mtspr	exc_lvl_srr1,r12;					\
855	lwz	r9,GPR9(r1);						\
856	lwz	r12,GPR12(r1);						\
857	lwz	r10,GPR10(r1);						\
858	lwz	r11,GPR11(r1);						\
859	lwz	r1,GPR1(r1);						\
860	PPC405_ERR77_SYNC;						\
861	exc_lvl_rfi;							\
862	b	.;		/* prevent prefetch past exc_lvl_rfi */
863
864	.globl	ret_from_crit_exc
865ret_from_crit_exc:
866	RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
867
868#ifdef CONFIG_BOOKE
869	.globl	ret_from_debug_exc
870ret_from_debug_exc:
871	RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI)
872
873	.globl	ret_from_mcheck_exc
874ret_from_mcheck_exc:
875	RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI)
876#endif /* CONFIG_BOOKE */
877
878/*
879 * Load the DBCR0 value for a task that is being ptraced,
880 * having first saved away the global DBCR0.  Note that r0
881 * has the dbcr0 value to set upon entry to this.
882 */
883load_dbcr0:
884	mfmsr	r10		/* first disable debug exceptions */
885	rlwinm	r10,r10,0,~MSR_DE
886	mtmsr	r10
887	isync
888	mfspr	r10,SPRN_DBCR0
889	lis	r11,global_dbcr0@ha
890	addi	r11,r11,global_dbcr0@l
891	stw	r10,0(r11)
892	mtspr	SPRN_DBCR0,r0
893	lwz	r10,4(r11)
894	addi	r10,r10,1
895	stw	r10,4(r11)
896	li	r11,-1
897	mtspr	SPRN_DBSR,r11	/* clear all pending debug events */
898	blr
899
900	.comm	global_dbcr0,8
901#endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
902
903do_work:			/* r10 contains MSR_KERNEL here */
904	andi.	r0,r9,_TIF_NEED_RESCHED
905	beq	do_user_signal
906
907do_resched:			/* r10 contains MSR_KERNEL here */
908	ori	r10,r10,MSR_EE
909	SYNC
910	MTMSRD(r10)		/* hard-enable interrupts */
911	bl	schedule
912recheck:
913	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
914	SYNC
915	MTMSRD(r10)		/* disable interrupts */
916	rlwinm	r9,r1,0,0,(31-THREAD_SHIFT)
917	lwz	r9,TI_FLAGS(r9)
918	andi.	r0,r9,_TIF_NEED_RESCHED
919	bne-	do_resched
920	andi.	r0,r9,_TIF_SIGPENDING
921	beq	restore_user
922do_user_signal:			/* r10 contains MSR_KERNEL here */
923	ori	r10,r10,MSR_EE
924	SYNC
925	MTMSRD(r10)		/* hard-enable interrupts */
926	/* save r13-r31 in the exception frame, if not already done */
927	lwz	r3,_TRAP(r1)
928	andi.	r0,r3,1
929	beq	2f
930	SAVE_NVGPRS(r1)
931	rlwinm	r3,r3,0,0,30
932	stw	r3,_TRAP(r1)
9332:	li	r3,0
934	addi	r4,r1,STACK_FRAME_OVERHEAD
935	bl	do_signal
936	REST_NVGPRS(r1)
937	b	recheck
938
939/*
940 * We come here when we are at the end of handling an exception
941 * that occurred at a place where taking an exception will lose
942 * state information, such as the contents of SRR0 and SRR1.
943 */
944nonrecoverable:
945	lis	r10,exc_exit_restart_end@ha
946	addi	r10,r10,exc_exit_restart_end@l
947	cmplw	r12,r10
948	bge	3f
949	lis	r11,exc_exit_restart@ha
950	addi	r11,r11,exc_exit_restart@l
951	cmplw	r12,r11
952	blt	3f
953	lis	r10,ee_restarts@ha
954	lwz	r12,ee_restarts@l(r10)
955	addi	r12,r12,1
956	stw	r12,ee_restarts@l(r10)
957	mr	r12,r11		/* restart at exc_exit_restart */
958	blr
9593:	/* OK, we can't recover, kill this process */
960	/* but the 601 doesn't implement the RI bit, so assume it's OK */
961BEGIN_FTR_SECTION
962	blr
963END_FTR_SECTION_IFSET(CPU_FTR_601)
964	lwz	r3,_TRAP(r1)
965	andi.	r0,r3,1
966	beq	4f
967	SAVE_NVGPRS(r1)
968	rlwinm	r3,r3,0,0,30
969	stw	r3,_TRAP(r1)
9704:	addi	r3,r1,STACK_FRAME_OVERHEAD
971	bl	nonrecoverable_exception
972	/* shouldn't return */
973	b	4b
974
975	.comm	ee_restarts,4
976
977/*
978 * PROM code for specific machines follows.  Put it
979 * here so it's easy to add arch-specific sections later.
980 * -- Cort
981 */
982#ifdef CONFIG_PPC_RTAS
983/*
984 * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
985 * called with the MMU off.
986 */
987_GLOBAL(enter_rtas)
988	stwu	r1,-INT_FRAME_SIZE(r1)
989	mflr	r0
990	stw	r0,INT_FRAME_SIZE+4(r1)
991	LOADADDR(r4, rtas)
992	lis	r6,1f@ha	/* physical return address for rtas */
993	addi	r6,r6,1f@l
994	tophys(r6,r6)
995	tophys(r7,r1)
996	lwz	r8,RTASENTRY(r4)
997	lwz	r4,RTASBASE(r4)
998	mfmsr	r9
999	stw	r9,8(r1)
1000	LOAD_MSR_KERNEL(r0,MSR_KERNEL)
1001	SYNC			/* disable interrupts so SRR0/1 */
1002	MTMSRD(r0)		/* don't get trashed */
1003	li	r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
1004	mtlr	r6
1005	mtspr	SPRN_SPRG2,r7
1006	mtspr	SPRN_SRR0,r8
1007	mtspr	SPRN_SRR1,r9
1008	RFI
10091:	tophys(r9,r1)
1010	lwz	r8,INT_FRAME_SIZE+4(r9)	/* get return address */
1011	lwz	r9,8(r9)	/* original msr value */
1012	FIX_SRR1(r9,r0)
1013	addi	r1,r1,INT_FRAME_SIZE
1014	li	r0,0
1015	mtspr	SPRN_SPRG2,r0
1016	mtspr	SPRN_SRR0,r8
1017	mtspr	SPRN_SRR1,r9
1018	RFI			/* return to caller */
1019
1020	.globl	machine_check_in_rtas
1021machine_check_in_rtas:
1022	twi	31,0,0
1023	/* XXX load up BATs and panic */
1024
1025#endif /* CONFIG_PPC_RTAS */
1026