The POWER platform
[linux-2.6/power.git] / arch / power / kernel / entry.S
blob637b5d3b5bb265ea15b5bb7dadefcd6c26d75f62
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  */
22 #include <linux/errno.h>
23 #include <linux/sys.h>
24 #include <linux/threads.h>
25 #include <asm/processor.h>
26 #include <asm/page.h>
27 #include <asm/mmu.h>
28 #include <asm/cputable.h>
29 #include <asm/thread_info.h>
30 #include <asm/ppc_asm.h>
31 #include <asm/asm-offsets.h>
32 #include <asm/unistd.h>
34 #undef SHOW_SYSCALLS
35 #undef SHOW_SYSCALLS_TASK
38  * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE.
39  */
40 #if MSR_KERNEL >= 0x10000
41 #define LOAD_MSR_KERNEL(r, x)   lis r,(x)@h; ori r,r,(x)@l
42 #else
43 #define LOAD_MSR_KERNEL(r, x)   li r,(x)
44 #endif
46 #ifdef CONFIG_BOOKE
47 #include "head_booke.h"
48 #define TRANSFER_TO_HANDLER_EXC_LEVEL(exc_level)        \
49         mtspr   exc_level##_SPRG,r8;                    \
50         BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);          \
51         lwz     r0,GPR10-INT_FRAME_SIZE(r8);            \
52         st      r0,GPR10(r11);                          \
53         lwz     r0,GPR11-INT_FRAME_SIZE(r8);            \
54         st      r0,GPR11(r11);                          \
55         mfspr   r8,exc_level##_SPRG
57         .globl  mcheck_transfer_to_handler
58 mcheck_transfer_to_handler:
59         TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK)
60         b       transfer_to_handler_full
62         .globl  debug_transfer_to_handler
63 debug_transfer_to_handler:
64         TRANSFER_TO_HANDLER_EXC_LEVEL(DEBUG)
65         b       transfer_to_handler_full
67         .globl  crit_transfer_to_handler
68 crit_transfer_to_handler:
69         TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT)
70         /* fall through */
71 #endif
73 #ifdef CONFIG_40x
74         .globl  crit_transfer_to_handler
75 crit_transfer_to_handler:
76         lwz     r0,crit_r10@l(0)
77         st      r0,GPR10(r11)
78         lwz     r0,crit_r11@l(0)
79         st      r0,GPR11(r11)
80         /* fall through */
81 #endif
84  * This code finishes saving the registers to the exception frame
85  * and jumps to the appropriate handler for the exception, turning
86  * on address translation.
87  * Note that we rely on the caller having set cr0.eq iff the exception
88  * occurred in kernel mode (i.e. MSR:PR = 0).
89  */
90         .globl  transfer_to_handler_full
91 transfer_to_handler_full:
92         SAVE_NVGPRS(r11)
93         /* fall through */
95         .globl  transfer_to_handler
96 transfer_to_handler:
97         st      r2,GPR2(r11)
98         st      r12,_NIP(r11)
99         st      r9,_MSR(r11)
100         andi.   r2,r9,MSR_PR
101         mfctr   r12
102         mfspr   r2,SPRN_XER
103         st      r12,_CTR(r11)
104         st      r2,_XER(r11)
105         lwz     r12,_SPRG3@l(0)
106         addi    r2,r12,-THREAD
107         tovirt(r2,r2)                   /* set r2 to current */
108         beq     2f                      /* if from user, fix up THREAD.regs */
109         addi    r11,r1,STACK_FRAME_OVERHEAD
110         st      r11,PT_REGS(r12)
111 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
112         /* Check to see if the dbcr0 register is set up to debug.  Use the
113            single-step bit to do this. */
114         lwz     r12,THREAD_DBCR0(r12)
115         andis.  r12,r12,DBCR0_IC@h
116         beq+    3f
117         /* From user and task is ptraced - load up global dbcr0 */
118         li      r12,-1                  /* clear all pending debug events */
119         mtspr   SPRN_DBSR,r12
120         lis     r11,global_dbcr0@ha
121         tophys(r11,r11)
122         addi    r11,r11,global_dbcr0@l
123         lwz     r12,0(r11)
124         mtspr   SPRN_DBCR0,r12
125         lwz     r12,4(r11)
126         addi    r12,r12,-1
127         st      r12,4(r11)
128 #endif
129         b       3f
131 2:      /* if from kernel, check interrupted DOZE/NAP mode and
132          * check for stack overflow
133          */
134         lwz     r9,THREAD_INFO-THREAD(r12)
135         cmplw   r1,r9                   /* if r1 <= current->thread_info */
136         ble-    stack_ovf               /* then the kernel stack overflowed */
138 #ifdef CONFIG_6xx
139         tophys(r9,r9)                   /* check local flags */
140         lwz     r12,TI_LOCAL_FLAGS(r9)
141         mtcrf   0x01,r12
142         bt-     31-TLF_NAPPING,4f
143 #endif /* CONFIG_6xx */
144         .globl transfer_to_handler_cont
145 transfer_to_handler_cont:
147         mflr    r9
148         lwz     r11,0(r9)               /* virtual address of handler */
149         lwz     r9,4(r9)                /* where to go when done */
150         mtspr   SPRN_SRR0,r11
151         mtspr   SPRN_SRR1,r10
152         mtlr    r9
153         SYNC
154         RFI                             /* jump to handler, enable MMU */
156 #ifdef CONFIG_6xx
157 4:      rlwinm  r12,r12,0,~_TLF_NAPPING
158         st      r12,TI_LOCAL_FLAGS(r9)
159         b       power_save_6xx_restore
160 #endif
163  * On kernel stack overflow, load up an initial stack pointer
164  * and call StackOverflow(regs), which should not return.
165  */
166 stack_ovf:
167         /* sometimes we use a statically-allocated stack, which is OK. */
168         lis     r12,_end@h
169         ori     r12,r12,_end@l
170         cmplw   r1,r12
171         ble     5b                      /* r1 <= &_end is OK */
172         SAVE_NVGPRS(r11)
173         addi    r3,r1,STACK_FRAME_OVERHEAD
174         lis     r1,init_thread_union@ha
175         addi    r1,r1,init_thread_union@l
176         addi    r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
177         lis     r9,StackOverflow@ha
178         addi    r9,r9,StackOverflow@l
179         LOAD_MSR_KERNEL(r10,MSR_KERNEL)
180         FIX_SRR1(r10,r12)
181         mtspr   SPRN_SRR0,r9
182         mtspr   SPRN_SRR1,r10
183         SYNC
184         RFI
187  * Handle a system call.
188  */
189         .stabs  "arch/ppc/kernel/",N_SO,0,0,0f
190         .stabs  "entry.S",N_SO,0,0,0f
193 _GLOBAL(DoSyscall)
194         st      r3,ORIG_GPR3(r1)
195         li      r12,0
196         st      r12,RESULT(r1)
197         lwz     r11,_CCR(r1)    /* Clear SO bit in CR */
198         rlwinm  r11,r11,0,4,2
199         st      r11,_CCR(r1)
200 #ifdef SHOW_SYSCALLS
201         bl      do_show_syscall
202 #endif /* SHOW_SYSCALLS */
203         rlwinm  r10,r1,0,0,18   /* current_thread_info() */
204         lwz     r11,TI_FLAGS(r10)
205         andi.   r11,r11,_TIF_SYSCALL_T_OR_A
206         bne-    syscall_dotrace
207 syscall_dotrace_cont:
208         cmplwi  0,r0,NR_syscalls
209         lis     r10,sys_call_table@h
210         ori     r10,r10,sys_call_table@l
211         slwi    r0,r0,2
212         bge-    66f
213         lwzx    r10,r10,r0      /* Fetch system call handler [ptr] */
214         mtlr    r10
215         addi    r9,r1,STACK_FRAME_OVERHEAD
216         PPC440EP_ERR42
217         blrl                    /* Call handler */
218         .globl  ret_from_syscall
219 ret_from_syscall:
220 #ifdef SHOW_SYSCALLS
221         bl      do_show_syscall_exit
222 #endif
223         mr      r6,r3
224         rlwinm  r12,r1,0,0,18   /* current_thread_info() */
225         /* disable interrupts so current_thread_info()->flags can't change */
226         LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
227         SYNC
228         MTMSRD(r10)
229         lwz     r9,TI_FLAGS(r12)
230         li      r8,-_LAST_ERRNO
231         andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
232         bne-    syscall_exit_work
233         cmplw   0,r3,r8
234         blt+    syscall_exit_cont
235         lwz     r11,_CCR(r1)                    /* Load CR */
236         neg     r3,r3
237         oris    r11,r11,0x1000  /* Set SO bit in CR */
238         st      r11,_CCR(r1)
239 syscall_exit_cont:
240 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
241         /* If the process has its own DBCR0 value, load it up.  The single
242            step bit tells us that dbcr0 should be loaded. */
243         lwz     r0,THREAD+THREAD_DBCR0(r2)
244         andis.  r10,r0,DBCR0_IC@h
245         bnel-   load_dbcr0
246 #endif
247 #ifdef CONFIG_44x
248         lis     r4,icache_44x_need_flush@ha
249         lwz     r5,icache_44x_need_flush@l(r4)
250         cmplwi  cr0,r5,0
251         bne-    2f
253 #endif /* CONFIG_44x */
254         stwx    r0,0,r1                 /* to clear the reservation */
255         lwz     r4,_LINK(r1)
256         lwz     r5,_CCR(r1)
257         mtlr    r4
258         mtcr    r5
259         lwz     r7,_NIP(r1)
260         lwz     r8,_MSR(r1)
261         FIX_SRR1(r8, r0)
262         lwz     r2,GPR2(r1)
263         lwz     r1,GPR1(r1)
264         mtspr   SPRN_SRR0,r7
265         mtspr   SPRN_SRR1,r8
266         SYNC
267         RFI
268 #ifdef CONFIG_44x
269 2:      li      r7,0
270         iccci   r0,r0
271         st      r7,icache_44x_need_flush@l(r4)
272         b       1b
273 #endif  /* CONFIG_44x */
275 66:     li      r3,-ENOSYS
276         b       ret_from_syscall
278         .globl  ret_from_fork
279 ret_from_fork:
280         REST_NVGPRS(r1)
281         bl      schedule_tail
282         li      r3,0
283         b       ret_from_syscall
285 /* Traced system call support */
286 syscall_dotrace:
287         SAVE_NVGPRS(r1)
288         li      r0,0xc00
289         st      r0,TRAP(r1)
290         addi    r3,r1,STACK_FRAME_OVERHEAD
291         bl      do_syscall_trace_enter
292         lwz     r0,GPR0(r1)     /* Restore original registers */
293         lwz     r3,GPR3(r1)
294         lwz     r4,GPR4(r1)
295         lwz     r5,GPR5(r1)
296         lwz     r6,GPR6(r1)
297         lwz     r7,GPR7(r1)
298         lwz     r8,GPR8(r1)
299         REST_NVGPRS(r1)
300         b       syscall_dotrace_cont
302 syscall_exit_work:
303         andi.   r0,r9,_TIF_RESTOREALL
304         beq+    0f
305         REST_NVGPRS(r1)
306         b       2f
307 0:      cmplw   0,r3,r8
308         blt+    1f
309         andi.   r0,r9,_TIF_NOERROR
310         bne-    1f
311         lwz     r11,_CCR(r1)                    /* Load CR */
312         neg     r3,r3
313         oris    r11,r11,0x1000  /* Set SO bit in CR */
314         st      r11,_CCR(r1)
316 1:      st      r6,RESULT(r1)   /* Save result */
317         st      r3,GPR3(r1)     /* Update return value */
318 2:      andi.   r0,r9,(_TIF_PERSYSCALL_MASK)
319         beq     4f
321         /* Clear per-syscall TIF flags if any are set.  */
323         li      r11,_TIF_PERSYSCALL_MASK
324         addi    r12,r12,TI_FLAGS
325         lwzx    r8,0,r12
326         subi    r12,r12,TI_FLAGS
327         
328 4:      /* Anything which requires enabling interrupts? */
329         andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
330         beq     ret_from_except
332         /* Re-enable interrupts */
333         ori     r10,r10,MSR_EE
334         SYNC
335         MTMSRD(r10)
337         /* Save NVGPRS if they're not saved already */
338         lwz     r4,TRAP(r1)
339         andi.   r4,r4,1
340         beq     5f
341         SAVE_NVGPRS(r1)
342         li      r4,0xc00
343         st      r4,TRAP(r1)
345         addi    r3,r1,STACK_FRAME_OVERHEAD
346         bl      do_syscall_trace_leave
347         b       ret_from_except_full
349 #ifdef SHOW_SYSCALLS
350 do_show_syscall:
351 #ifdef SHOW_SYSCALLS_TASK
352         lis     r11,show_syscalls_task@ha
353         lwz     r11,show_syscalls_task@l(r11)
354         cmp     0,r2,r11
355         bnelr
356 #endif
357         st      r31,GPR31(r1)
358         mflr    r31
359         lis     r3,7f@ha
360         addi    r3,r3,7f@l
361         lwz     r4,GPR0(r1)
362         lwz     r5,GPR3(r1)
363         lwz     r6,GPR4(r1)
364         lwz     r7,GPR5(r1)
365         lwz     r8,GPR6(r1)
366         lwz     r9,GPR7(r1)
367         bl      printk
368         lis     r3,77f@ha
369         addi    r3,r3,77f@l
370         lwz     r4,GPR8(r1)
371         mr      r5,r2
372         bl      printk
373         lwz     r0,GPR0(r1)
374         lwz     r3,GPR3(r1)
375         lwz     r4,GPR4(r1)
376         lwz     r5,GPR5(r1)
377         lwz     r6,GPR6(r1)
378         lwz     r7,GPR7(r1)
379         lwz     r8,GPR8(r1)
380         mtlr    r31
381         lwz     r31,GPR31(r1)
382         blr
384 do_show_syscall_exit:
385 #ifdef SHOW_SYSCALLS_TASK
386         lis     r11,show_syscalls_task@ha
387         lwz     r11,show_syscalls_task@l(r11)
388         cmp     0,r2,r11
389         bnelr
390 #endif
391         st      r31,GPR31(r1)
392         mflr    r31
393         st      r3,RESULT(r1)   /* Save result */
394         mr      r4,r3
395         lis     r3,79f@ha
396         addi    r3,r3,79f@l
397         bl      printk
398         lwz     r3,RESULT(r1)
399         mtlr    r31
400         lwz     r31,GPR31(r1)
401         blr
403 7:      .string "syscall %d(%x, %x, %x, %x, %x, "
404 77:     .string "%x), current=%p\n"
405 79:     .string " -> %x\n"
406         .align  2,0
408 #ifdef SHOW_SYSCALLS_TASK
409         .data
410         .globl  show_syscalls_task
411 show_syscalls_task:
412         .long   -1
413         .text
414 #endif
415 #endif /* SHOW_SYSCALLS */
418  * The fork/clone functions need to copy the full register set into
419  * the child process. Therefore we need to save all the nonvolatile
420  * registers (r13 - r31) before calling the C code.
421  */
422         .globl  ppc_fork
423 ppc_fork:
424         SAVE_NVGPRS(r1)
425         lwz     r0,TRAP(r1)
426         rlwinm  r0,r0,0,0,30            /* clear LSB to indicate full */
427         st      r0,TRAP(r1)             /* register set saved */
428         b       sys_fork
430         .globl  ppc_vfork
431 ppc_vfork:
432         SAVE_NVGPRS(r1)
433         lwz     r0,TRAP(r1)
434         rlwinm  r0,r0,0,0,30            /* clear LSB to indicate full */
435         st      r0,TRAP(r1)             /* register set saved */
436         b       sys_vfork
438         .globl  ppc_clone
439 ppc_clone:
440         SAVE_NVGPRS(r1)
441         lwz     r0,TRAP(r1)
442         rlwinm  r0,r0,0,0,30            /* clear LSB to indicate full */
443         stw     r0,TRAP(r1)             /* register set saved */
444         b       sys_clone
446         .globl  ppc_swapcontext
447 ppc_swapcontext:
448         SAVE_NVGPRS(r1)
449         lwz     r0,TRAP(r1)
450         rlwinm  r0,r0,0,0,30            /* clear LSB to indicate full */
451         stw     r0,TRAP(r1)             /* register set saved */
452         b       sys_swapcontext
455  * Top-level page fault handling.
456  * This is in assembler because if do_page_fault tells us that
457  * it is a bad kernel page fault, we want to save the non-volatile
458  * registers before calling bad_page_fault.
459  */
460         .globl  handle_page_fault
461 handle_page_fault:
462         stw     r4,_DAR(r1)
463         addi    r3,r1,STACK_FRAME_OVERHEAD
464         bl      do_page_fault
465         cmpwi   r3,0
466         beq+    ret_from_except
467         SAVE_NVGPRS(r1)
468         lwz     r0,TRAP(r1)
469         clrrwi  r0,r0,1
470         stw     r0,TRAP(r1)
471         mr      r5,r3
472         addi    r3,r1,STACK_FRAME_OVERHEAD
473         lwz     r4,_DAR(r1)
474         bl      bad_page_fault
475         b       ret_from_except_full
478  * This routine switches between two different tasks.  The process
479  * state of one is saved on its kernel stack.  Then the state
480  * of the other is restored from its kernel stack.  The memory
481  * management hardware is updated to the second process's state.
482  * Finally, we can return to the second process.
483  * On entry, r3 points to the THREAD for the current task, r4
484  * points to the THREAD for the new task.
486  * This routine is always called with interrupts disabled.
488  * Note: there are two ways to get to the "going out" portion
489  * of this code; either by coming in via the entry (_switch)
490  * or via "fork" which must set up an environment equivalent
491  * to the "_switch" path.  If you change this , you'll have to
492  * change the fork code also.
494  * The code which creates the new task context is in 'copy_thread'
495  * in arch/ppc/kernel/process.c
496  */
497 _GLOBAL(_switch)
498         stwu    r1,-INT_FRAME_SIZE(r1)
499         mflr    r0
500         stw     r0,INT_FRAME_SIZE+4(r1)
501         /* r3-r12 are caller saved -- Cort */
502         SAVE_NVGPRS(r1)
503         stw     r0,_NIP(r1)     /* Return to switch caller */
504         mfmsr   r11
505         li      r0,MSR_FP       /* Disable floating-point */
506 #ifdef CONFIG_ALTIVEC
507 BEGIN_FTR_SECTION
508         oris    r0,r0,MSR_VEC@h /* Disable altivec */
509         mfspr   r12,SPRN_VRSAVE /* save vrsave register value */
510         stw     r12,THREAD+THREAD_VRSAVE(r2)
511 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
512 #endif /* CONFIG_ALTIVEC */
513         and.    r0,r0,r11       /* FP or altivec enabled? */
514         beq+    1f
515         andc    r11,r11,r0
516         MTMSRD(r11)
517         isync
518 1:      stw     r11,_MSR(r1)
519         mfcr    r10
520         stw     r10,_CCR(r1)
521         stw     r1,KSP(r3)      /* Set old stack pointer */
523 #ifdef CONFIG_SMP
524         /* We need a sync somewhere here to make sure that if the
525          * previous task gets rescheduled on another CPU, it sees all
526          * stores it has performed on this one.
527          */
528         sync
529 #endif /* CONFIG_SMP */
531         tophys(r0,r4)
532         CLR_TOP32(r0)
533         stw     r0,_SPRG3@l(0)  /* Update current THREAD phys addr */
534         lwz     r1,KSP(r4)      /* Load new stack pointer */
536         /* save the old current 'last' for return value */
537         mr      r3,r2
538         addi    r2,r4,-THREAD   /* Update current */
540 #ifdef CONFIG_ALTIVEC
541 BEGIN_FTR_SECTION
542         lwz     r0,THREAD+THREAD_VRSAVE(r2)
543         mtspr   SPRN_VRSAVE,r0          /* if G4, restore VRSAVE reg */
544 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
545 #endif /* CONFIG_ALTIVEC */
546         lwz     r0,_CCR(r1)
547         mtcrf   0xFF,r0
548         /* r3-r12 are destroyed -- Cort */
549         REST_NVGPRS(r1)
551         lwz     r4,_NIP(r1)     /* Return to _switch caller in new task */
552         mtlr    r4
553         addi    r1,r1,INT_FRAME_SIZE
554         blr
556         .globl  fast_exception_return
557 fast_exception_return:
559 2:      REST_4GPRS(3, r11)
560         lwz     r10,_CCR(r11)
561         REST_GPR(1, r11)
562         mtcr    r10
563         lwz     r10,_LINK(r11)
564         mtlr    r10
565         REST_GPR(10, r11)
566         mtspr   SPRN_SRR1,r9
567         mtspr   SPRN_SRR0,r12
568         REST_GPR(9, r11)
569         REST_GPR(12, r11)
570         lwz     r11,GPR11(r11)
571         SYNC
572         RFI
574 #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
575 /* check if the exception happened in a restartable section */
576 1:      lis     r3,exc_exit_restart_end@ha
577         addi    r3,r3,exc_exit_restart_end@l
578         cmplw   r12,r3
579         bge     3f
580         lis     r4,exc_exit_restart@ha
581         addi    r4,r4,exc_exit_restart@l
582         cmplw   r12,r4
583         blt     3f
584         lis     r3,fee_restarts@ha
585         tophys(r3,r3)
586         lwz     r5,fee_restarts@l(r3)
587         addi    r5,r5,1
588         stw     r5,fee_restarts@l(r3)
589         mr      r12,r4          /* restart at exc_exit_restart */
590         b       2b
592         .section .bss
593         .align  2
594 fee_restarts:
595         .space  4
596         .previous
598 /* aargh, a nonrecoverable interrupt, panic */
599 /* aargh, we don't know which trap this is */
600 /* but the 601 doesn't implement the RI bit, so assume it's OK */
602 BEGIN_FTR_SECTION
603         b       2b
604 END_FTR_SECTION_IFSET(CPU_FTR_601)
605         li      r10,-1
606         stw     r10,TRAP(r11)
607         addi    r3,r1,STACK_FRAME_OVERHEAD
608         lis     r10,MSR_KERNEL@h
609         ori     r10,r10,MSR_KERNEL@l
610         bl      transfer_to_handler_full
611         .long   nonrecoverable_exception
612         .long   ret_from_except
613 #endif
615         .globl  ret_from_except_full
616 ret_from_except_full:
617         REST_NVGPRS(r1)
618         /* fall through */
620         .globl  ret_from_except
621 ret_from_except:
622         /* Hard-disable interrupts so that current_thread_info()->flags
623          * can't change between when we test it and when we return
624          * from the interrupt. */
625         LOAD_MSR_KERNEL(r10,MSR_KERNEL)
626         SYNC                    /* Some chip revs have problems here... */
627         MTMSRD(r10)             /* disable interrupts */
629         lwz     r3,_MSR(r1)     /* Returning to user mode? */
630         andi.   r0,r3,MSR_PR
631         beq     resume_kernel
633 user_exc_return:                /* r10 contains MSR_KERNEL here */
634         /* Check current_thread_info()->flags */
635         rlwinm  r9,r1,0,0,18
636         lwz     r9,TI_FLAGS(r9)
637         andi.   r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED)
638         bne     do_work
640 restore_user:
641 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
642         /* Check whether this process has its own DBCR0 value.  The single
643            step bit tells us that dbcr0 should be loaded. */
644         lwz     r0,THREAD+THREAD_DBCR0(r2)
645         andis.  r10,r0,DBCR0_IC@h
646         bnel-   load_dbcr0
647 #endif
649 #ifdef CONFIG_PREEMPT
650         b       restore
652 /* N.B. the only way to get here is from the beq following ret_from_except. */
653 resume_kernel:
654         /* check current_thread_info->preempt_count */
655         rlwinm  r9,r1,0,0,18
656         lwz     r0,TI_PREEMPT(r9)
657         cmpwi   0,r0,0          /* if non-zero, just restore regs and return */
658         bne     restore
659         lwz     r0,TI_FLAGS(r9)
660         andi.   r0,r0,_TIF_NEED_RESCHED
661         beq+    restore
662         andi.   r0,r3,MSR_EE    /* interrupts off? */
663         beq     restore         /* don't schedule if so */
664 1:      bl      preempt_schedule_irq
665         rlwinm  r9,r1,0,0,18
666         lwz     r3,TI_FLAGS(r9)
667         andi.   r0,r3,_TIF_NEED_RESCHED
668         bne-    1b
669 #else
670 resume_kernel:
671 #endif /* CONFIG_PREEMPT */
673         /* interrupts are hard-disabled at this point */
674 restore:
675 #ifdef CONFIG_44x
676         lis     r4,icache_44x_need_flush@ha
677         lwz     r5,icache_44x_need_flush@l(r4)
678         cmplwi  cr0,r5,0
679         beq+    1f
680         li      r6,0
681         iccci   r0,r0
682         stw     r6,icache_44x_need_flush@l(r4)
684 #endif  /* CONFIG_44x */
685         lwz     r0,GPR0(r1)
686         lwz     r2,GPR2(r1)
687         REST_4GPRS(3, r1)
688         REST_2GPRS(7, r1)
690         lwz     r10,_XER(r1)
691         lwz     r11,_CTR(r1)
692         mtspr   SPRN_XER,r10
693         mtctr   r11
695         stwx    r0,0,r1                 /* to clear the reservation */
697         /*
698          * This is a bit different on 4xx/Book-E because it doesn't have
699          * the RI bit in the MSR.
700          * The TLB miss handler checks if we have interrupted
701          * the exception exit path and restarts it if so
702          * (well maybe one day it will... :).
703          */
704         lwz     r11,_LINK(r1)
705         mtlr    r11
706         lwz     r10,_CCR(r1)
707         mtcrf   0xff,r10
708         REST_2GPRS(9, r1)
709         .globl exc_exit_restart
710 exc_exit_restart:
711         lwz     r11,_NIP(r1)
712         lwz     r12,_MSR(r1)
713 exc_exit_start:
714         mtspr   SPRN_SRR0,r11
715         mtspr   SPRN_SRR1,r12
716         REST_2GPRS(11, r1)
717         lwz     r1,GPR1(r1)
718         .globl exc_exit_restart_end
719 exc_exit_restart_end:
720         rfi
721         b       .                       /* prevent prefetch past rfi */
724  * Returning from a critical interrupt in user mode doesn't need
725  * to be any different from a normal exception.  For a critical
726  * interrupt in the kernel, we just return (without checking for
727  * preemption) since the interrupt may have happened at some crucial
728  * place (e.g. inside the TLB miss handler), and because we will be
729  * running with r1 pointing into critical_stack, not the current
730  * process's kernel stack (and therefore current_thread_info() will
731  * give the wrong answer).
732  * We have to restore various SPRs that may have been in use at the
733  * time of the critical interrupt.
735  */
736 #ifdef CONFIG_40x
737 #define PPC_40x_TURN_OFF_MSR_DR                                             \
738         /* avoid any possible TLB misses here by turning off MSR.DR, we     \
739          * assume the instructions here are mapped by a pinned TLB entry */ \
740         li      r10,MSR_IR;                                                 \
741         mtmsr   r10;                                                        \
742         isync;                                                              \
743         tophys(r1, r1);
744 #else
745 #define PPC_40x_TURN_OFF_MSR_DR
746 #endif
748 #define RET_FROM_EXC_LEVEL(exc_lvl_srr0, exc_lvl_srr1, exc_lvl_rfi)     \
749         REST_NVGPRS(r1);                                                \
750         lwz     r3,_MSR(r1);                                            \
751         andi.   r3,r3,MSR_PR;                                           \
752         LOAD_MSR_KERNEL(r10,MSR_KERNEL);                                \
753         bne     user_exc_return;                                        \
754         lwz     r0,GPR0(r1);                                            \
755         lwz     r2,GPR2(r1);                                            \
756         REST_4GPRS(3, r1);                                              \
757         REST_2GPRS(7, r1);                                              \
758         lwz     r10,_XER(r1);                                           \
759         lwz     r11,_CTR(r1);                                           \
760         mtspr   SPRN_XER,r10;                                           \
761         mtctr   r11;                                                    \
762         stwx    r0,0,r1;                /* to clear the reservation */  \
763         lwz     r11,_LINK(r1);                                          \
764         mtlr    r11;                                                    \
765         lwz     r10,_CCR(r1);                                           \
766         mtcrf   0xff,r10;                                               \
767         PPC_40x_TURN_OFF_MSR_DR;                                        \
768         /* lwz  r9,_DEAR(r1);   */                                      \
769         /* lwz  r10,_ESR(r1);   */                                      \
770         /* mtsp SPRN_DEAR,r9; */                                        \
771         /* mtsp SPRN_ESR,r10;   */                                      \
772         lwz     r11,_NIP(r1);                                           \
773         lwz     r12,_MSR(r1);                                           \
774         mtspr   exc_lvl_srr0,r11;                                       \
775         mtspr   exc_lvl_srr1,r12;                                       \
776         lwz     r9,GPR9(r1);                                            \
777         lwz     r12,GPR12(r1);                                          \
778         lwz     r10,GPR10(r1);                                          \
779         lwz     r11,GPR11(r1);                                          \
780         lwz     r1,GPR1(r1);                                            \
781         exc_lvl_rfi;                                                    \
782         b       .;              /* prevent prefetch past exc_lvl_rfi */
784         .globl  ret_from_crit_exc
785 ret_from_crit_exc:
786         RET_FROM_EXC_LEVEL(SPRN_SRR0, SPRN_SRR1, RFCI)
787 #       RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
789 #ifdef CONFIG_BOOKE
790         .globl  ret_from_debug_exc
791 ret_from_debug_exc:
792         RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI)
794         .globl  ret_from_mcheck_exc
795 ret_from_mcheck_exc:
796         RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI)
799  * Load the DBCR0 value for a task that is being ptraced,
800  * having first saved away the global DBCR0.  Note that r0
801  * has the dbcr0 value to set upon entry to this.
802  */
803 load_dbcr0:
804         mfmsr   r10             /* first disable debug exceptions */
805         rlwinm  r10,r10,0,~MSR_DE
806         mtmsr   r10
807         isync
808         mfspr   r10,SPRN_DBCR0
809         lis     r11,global_dbcr0@ha
810         addi    r11,r11,global_dbcr0@l
811         stw     r10,0(r11)
812         mtspr   SPRN_DBCR0,r0
813         lwz     r10,4(r11)
814         addi    r10,r10,1
815         stw     r10,4(r11)
816         li      r11,-1
817         mtspr   SPRN_DBSR,r11   /* clear all pending debug events */
818         blr
820         .section .bss
821         .align  4
822 global_dbcr0:
823         .space  8
824         .previous
825 #endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
827 do_work:                        /* r10 contains MSR_KERNEL here */
828         andi.   r0,r9,_TIF_NEED_RESCHED
829         beq     do_user_signal
831 do_resched:                     /* r10 contains MSR_KERNEL here */
832         ori     r10,r10,MSR_EE
833         SYNC
834         MTMSRD(r10)             /* hard-enable interrupts */
835         bl      schedule
836 recheck:
837         LOAD_MSR_KERNEL(r10,MSR_KERNEL)
838         SYNC
839         MTMSRD(r10)             /* disable interrupts */
840         rlwinm  r9,r1,0,0,18
841         lwz     r9,TI_FLAGS(r9)
842         andi.   r0,r9,_TIF_NEED_RESCHED
843         bne-    do_resched
844         andi.   r0,r9,_TIF_SIGPENDING
845         beq     restore_user
846 do_user_signal:                 /* r10 contains MSR_KERNEL here */
847         ori     r10,r10,MSR_EE
848         SYNC
849         MTMSRD(r10)             /* hard-enable interrupts */
850         /* save r13-r31 in the exception frame, if not already done */
851         lwz     r3,TRAP(r1)
852         andi.   r0,r3,1
853         beq     2f
854         SAVE_NVGPRS(r1)
855         rlwinm  r3,r3,0,0,30
856         stw     r3,TRAP(r1)
857 2:      li      r3,0
858         addi    r4,r1,STACK_FRAME_OVERHEAD
859         bl      do_signal
860         REST_NVGPRS(r1)
861         b       recheck
864  * We come here when we are at the end of handling an exception
865  * that occurred at a place where taking an exception will lose
866  * state information, such as the contents of SRR0 and SRR1.
867  */
868 nonrecoverable:
869         lis     r10,exc_exit_restart_end@ha
870         addi    r10,r10,exc_exit_restart_end@l
871         cmplw   r12,r10
872         bge     3f
873         lis     r11,exc_exit_restart@ha
874         addi    r11,r11,exc_exit_restart@l
875         cmplw   r12,r11
876         blt     3f
877         lis     r10,ee_restarts@ha
878         lwz     r12,ee_restarts@l(r10)
879         addi    r12,r12,1
880         stw     r12,ee_restarts@l(r10)
881         mr      r12,r11         /* restart at exc_exit_restart */
882         blr
883 3:      /* OK, we can't recover, kill this process */
884         /* but the 601 doesn't implement the RI bit, so assume it's OK */
885 BEGIN_FTR_SECTION
886         blr
887 END_FTR_SECTION_IFSET(CPU_FTR_601)
888         lwz     r3,TRAP(r1)
889         andi.   r0,r3,1
890         beq     4f
891         SAVE_NVGPRS(r1)
892         rlwinm  r3,r3,0,0,30
893         stw     r3,TRAP(r1)
894 4:      addi    r3,r1,STACK_FRAME_OVERHEAD
895         bl      nonrecoverable_exception
896         /* shouldn't return */
897         b       4b
899         .section .bss
900         .align  2
901 ee_restarts:
902         .space  4
903         .previous