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