x86: fix bogus KERN_ALERT on oops
[wrt350n-kernel.git] / arch / powerpc / kernel / entry_32.S
blob21d889e63e87520d9e49112a99d20fc8d887da90
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/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>
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         stw     r0,GPR10(r11);                          \
53         lwz     r0,GPR11-INT_FRAME_SIZE(r8);            \
54         stw     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         stw     r0,GPR10(r11)
78         lwz     r0,crit_r11@l(0)
79         stw     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         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            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         stw     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         stw     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/powerpc/kernel/",N_SO,0,0,0f
190         .stabs  "entry_32.S",N_SO,0,0,0f
193 _GLOBAL(DoSyscall)
194         stw     r3,ORIG_GPR3(r1)
195         li      r12,0
196         stw     r12,RESULT(r1)
197         lwz     r11,_CCR(r1)    /* Clear SO bit in CR */
198         rlwinm  r11,r11,0,4,2
199         stw     r11,_CCR(r1)
200 #ifdef SHOW_SYSCALLS
201         bl      do_show_syscall
202 #endif /* SHOW_SYSCALLS */
203         rlwinm  r10,r1,0,0,(31-THREAD_SHIFT)    /* 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,(31-THREAD_SHIFT)    /* 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         stw     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         stwcx.  r0,0,r1                 /* to clear the reservation */
248         lwz     r4,_LINK(r1)
249         lwz     r5,_CCR(r1)
250         mtlr    r4
251         mtcr    r5
252         lwz     r7,_NIP(r1)
253         lwz     r8,_MSR(r1)
254         FIX_SRR1(r8, r0)
255         lwz     r2,GPR2(r1)
256         lwz     r1,GPR1(r1)
257         mtspr   SPRN_SRR0,r7
258         mtspr   SPRN_SRR1,r8
259         SYNC
260         RFI
262 66:     li      r3,-ENOSYS
263         b       ret_from_syscall
265         .globl  ret_from_fork
266 ret_from_fork:
267         REST_NVGPRS(r1)
268         bl      schedule_tail
269         li      r3,0
270         b       ret_from_syscall
272 /* Traced system call support */
273 syscall_dotrace:
274         SAVE_NVGPRS(r1)
275         li      r0,0xc00
276         stw     r0,_TRAP(r1)
277         addi    r3,r1,STACK_FRAME_OVERHEAD
278         bl      do_syscall_trace_enter
279         lwz     r0,GPR0(r1)     /* Restore original registers */
280         lwz     r3,GPR3(r1)
281         lwz     r4,GPR4(r1)
282         lwz     r5,GPR5(r1)
283         lwz     r6,GPR6(r1)
284         lwz     r7,GPR7(r1)
285         lwz     r8,GPR8(r1)
286         REST_NVGPRS(r1)
287         b       syscall_dotrace_cont
289 syscall_exit_work:
290         andi.   r0,r9,_TIF_RESTOREALL
291         beq+    0f
292         REST_NVGPRS(r1)
293         b       2f
294 0:      cmplw   0,r3,r8
295         blt+    1f
296         andi.   r0,r9,_TIF_NOERROR
297         bne-    1f
298         lwz     r11,_CCR(r1)                    /* Load CR */
299         neg     r3,r3
300         oris    r11,r11,0x1000  /* Set SO bit in CR */
301         stw     r11,_CCR(r1)
303 1:      stw     r6,RESULT(r1)   /* Save result */
304         stw     r3,GPR3(r1)     /* Update return value */
305 2:      andi.   r0,r9,(_TIF_PERSYSCALL_MASK)
306         beq     4f
308         /* Clear per-syscall TIF flags if any are set.  */
310         li      r11,_TIF_PERSYSCALL_MASK
311         addi    r12,r12,TI_FLAGS
312 3:      lwarx   r8,0,r12
313         andc    r8,r8,r11
314 #ifdef CONFIG_IBM405_ERR77
315         dcbt    0,r12
316 #endif
317         stwcx.  r8,0,r12
318         bne-    3b
319         subi    r12,r12,TI_FLAGS
320         
321 4:      /* Anything which requires enabling interrupts? */
322         andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
323         beq     ret_from_except
325         /* Re-enable interrupts */
326         ori     r10,r10,MSR_EE
327         SYNC
328         MTMSRD(r10)
330         /* Save NVGPRS if they're not saved already */
331         lwz     r4,_TRAP(r1)
332         andi.   r4,r4,1
333         beq     5f
334         SAVE_NVGPRS(r1)
335         li      r4,0xc00
336         stw     r4,_TRAP(r1)
338         addi    r3,r1,STACK_FRAME_OVERHEAD
339         bl      do_syscall_trace_leave
340         b       ret_from_except_full
342 #ifdef SHOW_SYSCALLS
343 do_show_syscall:
344 #ifdef SHOW_SYSCALLS_TASK
345         lis     r11,show_syscalls_task@ha
346         lwz     r11,show_syscalls_task@l(r11)
347         cmp     0,r2,r11
348         bnelr
349 #endif
350         stw     r31,GPR31(r1)
351         mflr    r31
352         lis     r3,7f@ha
353         addi    r3,r3,7f@l
354         lwz     r4,GPR0(r1)
355         lwz     r5,GPR3(r1)
356         lwz     r6,GPR4(r1)
357         lwz     r7,GPR5(r1)
358         lwz     r8,GPR6(r1)
359         lwz     r9,GPR7(r1)
360         bl      printk
361         lis     r3,77f@ha
362         addi    r3,r3,77f@l
363         lwz     r4,GPR8(r1)
364         mr      r5,r2
365         bl      printk
366         lwz     r0,GPR0(r1)
367         lwz     r3,GPR3(r1)
368         lwz     r4,GPR4(r1)
369         lwz     r5,GPR5(r1)
370         lwz     r6,GPR6(r1)
371         lwz     r7,GPR7(r1)
372         lwz     r8,GPR8(r1)
373         mtlr    r31
374         lwz     r31,GPR31(r1)
375         blr
377 do_show_syscall_exit:
378 #ifdef SHOW_SYSCALLS_TASK
379         lis     r11,show_syscalls_task@ha
380         lwz     r11,show_syscalls_task@l(r11)
381         cmp     0,r2,r11
382         bnelr
383 #endif
384         stw     r31,GPR31(r1)
385         mflr    r31
386         stw     r3,RESULT(r1)   /* Save result */
387         mr      r4,r3
388         lis     r3,79f@ha
389         addi    r3,r3,79f@l
390         bl      printk
391         lwz     r3,RESULT(r1)
392         mtlr    r31
393         lwz     r31,GPR31(r1)
394         blr
396 7:      .string "syscall %d(%x, %x, %x, %x, %x, "
397 77:     .string "%x), current=%p\n"
398 79:     .string " -> %x\n"
399         .align  2,0
401 #ifdef SHOW_SYSCALLS_TASK
402         .data
403         .globl  show_syscalls_task
404 show_syscalls_task:
405         .long   -1
406         .text
407 #endif
408 #endif /* SHOW_SYSCALLS */
411  * The fork/clone functions need to copy the full register set into
412  * the child process. Therefore we need to save all the nonvolatile
413  * registers (r13 - r31) before calling the C code.
414  */
415         .globl  ppc_fork
416 ppc_fork:
417         SAVE_NVGPRS(r1)
418         lwz     r0,_TRAP(r1)
419         rlwinm  r0,r0,0,0,30            /* clear LSB to indicate full */
420         stw     r0,_TRAP(r1)            /* register set saved */
421         b       sys_fork
423         .globl  ppc_vfork
424 ppc_vfork:
425         SAVE_NVGPRS(r1)
426         lwz     r0,_TRAP(r1)
427         rlwinm  r0,r0,0,0,30            /* clear LSB to indicate full */
428         stw     r0,_TRAP(r1)            /* register set saved */
429         b       sys_vfork
431         .globl  ppc_clone
432 ppc_clone:
433         SAVE_NVGPRS(r1)
434         lwz     r0,_TRAP(r1)
435         rlwinm  r0,r0,0,0,30            /* clear LSB to indicate full */
436         stw     r0,_TRAP(r1)            /* register set saved */
437         b       sys_clone
439         .globl  ppc_swapcontext
440 ppc_swapcontext:
441         SAVE_NVGPRS(r1)
442         lwz     r0,_TRAP(r1)
443         rlwinm  r0,r0,0,0,30            /* clear LSB to indicate full */
444         stw     r0,_TRAP(r1)            /* register set saved */
445         b       sys_swapcontext
448  * Top-level page fault handling.
449  * This is in assembler because if do_page_fault tells us that
450  * it is a bad kernel page fault, we want to save the non-volatile
451  * registers before calling bad_page_fault.
452  */
453         .globl  handle_page_fault
454 handle_page_fault:
455         stw     r4,_DAR(r1)
456         addi    r3,r1,STACK_FRAME_OVERHEAD
457         bl      do_page_fault
458         cmpwi   r3,0
459         beq+    ret_from_except
460         SAVE_NVGPRS(r1)
461         lwz     r0,_TRAP(r1)
462         clrrwi  r0,r0,1
463         stw     r0,_TRAP(r1)
464         mr      r5,r3
465         addi    r3,r1,STACK_FRAME_OVERHEAD
466         lwz     r4,_DAR(r1)
467         bl      bad_page_fault
468         b       ret_from_except_full
471  * This routine switches between two different tasks.  The process
472  * state of one is saved on its kernel stack.  Then the state
473  * of the other is restored from its kernel stack.  The memory
474  * management hardware is updated to the second process's state.
475  * Finally, we can return to the second process.
476  * On entry, r3 points to the THREAD for the current task, r4
477  * points to the THREAD for the new task.
479  * This routine is always called with interrupts disabled.
481  * Note: there are two ways to get to the "going out" portion
482  * of this code; either by coming in via the entry (_switch)
483  * or via "fork" which must set up an environment equivalent
484  * to the "_switch" path.  If you change this , you'll have to
485  * change the fork code also.
487  * The code which creates the new task context is in 'copy_thread'
488  * in arch/ppc/kernel/process.c
489  */
490 _GLOBAL(_switch)
491         stwu    r1,-INT_FRAME_SIZE(r1)
492         mflr    r0
493         stw     r0,INT_FRAME_SIZE+4(r1)
494         /* r3-r12 are caller saved -- Cort */
495         SAVE_NVGPRS(r1)
496         stw     r0,_NIP(r1)     /* Return to switch caller */
497         mfmsr   r11
498         li      r0,MSR_FP       /* Disable floating-point */
499 #ifdef CONFIG_ALTIVEC
500 BEGIN_FTR_SECTION
501         oris    r0,r0,MSR_VEC@h /* Disable altivec */
502         mfspr   r12,SPRN_VRSAVE /* save vrsave register value */
503         stw     r12,THREAD+THREAD_VRSAVE(r2)
504 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
505 #endif /* CONFIG_ALTIVEC */
506 #ifdef CONFIG_SPE
507 BEGIN_FTR_SECTION
508         oris    r0,r0,MSR_SPE@h  /* Disable SPE */
509         mfspr   r12,SPRN_SPEFSCR /* save spefscr register value */
510         stw     r12,THREAD+THREAD_SPEFSCR(r2)
511 END_FTR_SECTION_IFSET(CPU_FTR_SPE)
512 #endif /* CONFIG_SPE */
513         and.    r0,r0,r11       /* FP or altivec or SPE 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         mtspr   SPRN_SPRG3,r0   /* 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 #ifdef CONFIG_SPE
547 BEGIN_FTR_SECTION
548         lwz     r0,THREAD+THREAD_SPEFSCR(r2)
549         mtspr   SPRN_SPEFSCR,r0         /* restore SPEFSCR reg */
550 END_FTR_SECTION_IFSET(CPU_FTR_SPE)
551 #endif /* CONFIG_SPE */
553         lwz     r0,_CCR(r1)
554         mtcrf   0xFF,r0
555         /* r3-r12 are destroyed -- Cort */
556         REST_NVGPRS(r1)
558         lwz     r4,_NIP(r1)     /* Return to _switch caller in new task */
559         mtlr    r4
560         addi    r1,r1,INT_FRAME_SIZE
561         blr
563         .globl  fast_exception_return
564 fast_exception_return:
565 #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
566         andi.   r10,r9,MSR_RI           /* check for recoverable interrupt */
567         beq     1f                      /* if not, we've got problems */
568 #endif
570 2:      REST_4GPRS(3, r11)
571         lwz     r10,_CCR(r11)
572         REST_GPR(1, r11)
573         mtcr    r10
574         lwz     r10,_LINK(r11)
575         mtlr    r10
576         REST_GPR(10, r11)
577         mtspr   SPRN_SRR1,r9
578         mtspr   SPRN_SRR0,r12
579         REST_GPR(9, r11)
580         REST_GPR(12, r11)
581         lwz     r11,GPR11(r11)
582         SYNC
583         RFI
585 #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
586 /* check if the exception happened in a restartable section */
587 1:      lis     r3,exc_exit_restart_end@ha
588         addi    r3,r3,exc_exit_restart_end@l
589         cmplw   r12,r3
590         bge     3f
591         lis     r4,exc_exit_restart@ha
592         addi    r4,r4,exc_exit_restart@l
593         cmplw   r12,r4
594         blt     3f
595         lis     r3,fee_restarts@ha
596         tophys(r3,r3)
597         lwz     r5,fee_restarts@l(r3)
598         addi    r5,r5,1
599         stw     r5,fee_restarts@l(r3)
600         mr      r12,r4          /* restart at exc_exit_restart */
601         b       2b
603         .section .bss
604         .align  2
605 fee_restarts:
606         .space  4
607         .previous
609 /* aargh, a nonrecoverable interrupt, panic */
610 /* aargh, we don't know which trap this is */
611 /* but the 601 doesn't implement the RI bit, so assume it's OK */
613 BEGIN_FTR_SECTION
614         b       2b
615 END_FTR_SECTION_IFSET(CPU_FTR_601)
616         li      r10,-1
617         stw     r10,_TRAP(r11)
618         addi    r3,r1,STACK_FRAME_OVERHEAD
619         lis     r10,MSR_KERNEL@h
620         ori     r10,r10,MSR_KERNEL@l
621         bl      transfer_to_handler_full
622         .long   nonrecoverable_exception
623         .long   ret_from_except
624 #endif
626         .globl  ret_from_except_full
627 ret_from_except_full:
628         REST_NVGPRS(r1)
629         /* fall through */
631         .globl  ret_from_except
632 ret_from_except:
633         /* Hard-disable interrupts so that current_thread_info()->flags
634          * can't change between when we test it and when we return
635          * from the interrupt. */
636         LOAD_MSR_KERNEL(r10,MSR_KERNEL)
637         SYNC                    /* Some chip revs have problems here... */
638         MTMSRD(r10)             /* disable interrupts */
640         lwz     r3,_MSR(r1)     /* Returning to user mode? */
641         andi.   r0,r3,MSR_PR
642         beq     resume_kernel
644 user_exc_return:                /* r10 contains MSR_KERNEL here */
645         /* Check current_thread_info()->flags */
646         rlwinm  r9,r1,0,0,(31-THREAD_SHIFT)
647         lwz     r9,TI_FLAGS(r9)
648         andi.   r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED)
649         bne     do_work
651 restore_user:
652 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
653         /* Check whether this process has its own DBCR0 value.  The single
654            step bit tells us that dbcr0 should be loaded. */
655         lwz     r0,THREAD+THREAD_DBCR0(r2)
656         andis.  r10,r0,DBCR0_IC@h
657         bnel-   load_dbcr0
658 #endif
660 #ifdef CONFIG_PREEMPT
661         b       restore
663 /* N.B. the only way to get here is from the beq following ret_from_except. */
664 resume_kernel:
665         /* check current_thread_info->preempt_count */
666         rlwinm  r9,r1,0,0,(31-THREAD_SHIFT)
667         lwz     r0,TI_PREEMPT(r9)
668         cmpwi   0,r0,0          /* if non-zero, just restore regs and return */
669         bne     restore
670         lwz     r0,TI_FLAGS(r9)
671         andi.   r0,r0,_TIF_NEED_RESCHED
672         beq+    restore
673         andi.   r0,r3,MSR_EE    /* interrupts off? */
674         beq     restore         /* don't schedule if so */
675 1:      bl      preempt_schedule_irq
676         rlwinm  r9,r1,0,0,(31-THREAD_SHIFT)
677         lwz     r3,TI_FLAGS(r9)
678         andi.   r0,r3,_TIF_NEED_RESCHED
679         bne-    1b
680 #else
681 resume_kernel:
682 #endif /* CONFIG_PREEMPT */
684         /* interrupts are hard-disabled at this point */
685 restore:
686         lwz     r0,GPR0(r1)
687         lwz     r2,GPR2(r1)
688         REST_4GPRS(3, r1)
689         REST_2GPRS(7, r1)
691         lwz     r10,_XER(r1)
692         lwz     r11,_CTR(r1)
693         mtspr   SPRN_XER,r10
694         mtctr   r11
696         PPC405_ERR77(0,r1)
697         stwcx.  r0,0,r1                 /* to clear the reservation */
699 #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
700         lwz     r9,_MSR(r1)
701         andi.   r10,r9,MSR_RI           /* check if this exception occurred */
702         beql    nonrecoverable          /* at a bad place (MSR:RI = 0) */
704         lwz     r10,_CCR(r1)
705         lwz     r11,_LINK(r1)
706         mtcrf   0xFF,r10
707         mtlr    r11
709         /*
710          * Once we put values in SRR0 and SRR1, we are in a state
711          * where exceptions are not recoverable, since taking an
712          * exception will trash SRR0 and SRR1.  Therefore we clear the
713          * MSR:RI bit to indicate this.  If we do take an exception,
714          * we can't return to the point of the exception but we
715          * can restart the exception exit path at the label
716          * exc_exit_restart below.  -- paulus
717          */
718         LOAD_MSR_KERNEL(r10,MSR_KERNEL & ~MSR_RI)
719         SYNC
720         MTMSRD(r10)             /* clear the RI bit */
721         .globl exc_exit_restart
722 exc_exit_restart:
723         lwz     r9,_MSR(r1)
724         lwz     r12,_NIP(r1)
725         FIX_SRR1(r9,r10)
726         mtspr   SPRN_SRR0,r12
727         mtspr   SPRN_SRR1,r9
728         REST_4GPRS(9, r1)
729         lwz     r1,GPR1(r1)
730         .globl exc_exit_restart_end
731 exc_exit_restart_end:
732         SYNC
733         RFI
735 #else /* !(CONFIG_4xx || CONFIG_BOOKE) */
736         /*
737          * This is a bit different on 4xx/Book-E because it doesn't have
738          * the RI bit in the MSR.
739          * The TLB miss handler checks if we have interrupted
740          * the exception exit path and restarts it if so
741          * (well maybe one day it will... :).
742          */
743         lwz     r11,_LINK(r1)
744         mtlr    r11
745         lwz     r10,_CCR(r1)
746         mtcrf   0xff,r10
747         REST_2GPRS(9, r1)
748         .globl exc_exit_restart
749 exc_exit_restart:
750         lwz     r11,_NIP(r1)
751         lwz     r12,_MSR(r1)
752 exc_exit_start:
753         mtspr   SPRN_SRR0,r11
754         mtspr   SPRN_SRR1,r12
755         REST_2GPRS(11, r1)
756         lwz     r1,GPR1(r1)
757         .globl exc_exit_restart_end
758 exc_exit_restart_end:
759         PPC405_ERR77_SYNC
760         rfi
761         b       .                       /* prevent prefetch past rfi */
764  * Returning from a critical interrupt in user mode doesn't need
765  * to be any different from a normal exception.  For a critical
766  * interrupt in the kernel, we just return (without checking for
767  * preemption) since the interrupt may have happened at some crucial
768  * place (e.g. inside the TLB miss handler), and because we will be
769  * running with r1 pointing into critical_stack, not the current
770  * process's kernel stack (and therefore current_thread_info() will
771  * give the wrong answer).
772  * We have to restore various SPRs that may have been in use at the
773  * time of the critical interrupt.
775  */
776 #ifdef CONFIG_40x
777 #define PPC_40x_TURN_OFF_MSR_DR                                             \
778         /* avoid any possible TLB misses here by turning off MSR.DR, we     \
779          * assume the instructions here are mapped by a pinned TLB entry */ \
780         li      r10,MSR_IR;                                                 \
781         mtmsr   r10;                                                        \
782         isync;                                                              \
783         tophys(r1, r1);
784 #else
785 #define PPC_40x_TURN_OFF_MSR_DR
786 #endif
788 #define RET_FROM_EXC_LEVEL(exc_lvl_srr0, exc_lvl_srr1, exc_lvl_rfi)     \
789         REST_NVGPRS(r1);                                                \
790         lwz     r3,_MSR(r1);                                            \
791         andi.   r3,r3,MSR_PR;                                           \
792         LOAD_MSR_KERNEL(r10,MSR_KERNEL);                                \
793         bne     user_exc_return;                                        \
794         lwz     r0,GPR0(r1);                                            \
795         lwz     r2,GPR2(r1);                                            \
796         REST_4GPRS(3, r1);                                              \
797         REST_2GPRS(7, r1);                                              \
798         lwz     r10,_XER(r1);                                           \
799         lwz     r11,_CTR(r1);                                           \
800         mtspr   SPRN_XER,r10;                                           \
801         mtctr   r11;                                                    \
802         PPC405_ERR77(0,r1);                                             \
803         stwcx.  r0,0,r1;                /* to clear the reservation */  \
804         lwz     r11,_LINK(r1);                                          \
805         mtlr    r11;                                                    \
806         lwz     r10,_CCR(r1);                                           \
807         mtcrf   0xff,r10;                                               \
808         PPC_40x_TURN_OFF_MSR_DR;                                        \
809         lwz     r9,_DEAR(r1);                                           \
810         lwz     r10,_ESR(r1);                                           \
811         mtspr   SPRN_DEAR,r9;                                           \
812         mtspr   SPRN_ESR,r10;                                           \
813         lwz     r11,_NIP(r1);                                           \
814         lwz     r12,_MSR(r1);                                           \
815         mtspr   exc_lvl_srr0,r11;                                       \
816         mtspr   exc_lvl_srr1,r12;                                       \
817         lwz     r9,GPR9(r1);                                            \
818         lwz     r12,GPR12(r1);                                          \
819         lwz     r10,GPR10(r1);                                          \
820         lwz     r11,GPR11(r1);                                          \
821         lwz     r1,GPR1(r1);                                            \
822         PPC405_ERR77_SYNC;                                              \
823         exc_lvl_rfi;                                                    \
824         b       .;              /* prevent prefetch past exc_lvl_rfi */
826         .globl  ret_from_crit_exc
827 ret_from_crit_exc:
828         RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
830 #ifdef CONFIG_BOOKE
831         .globl  ret_from_debug_exc
832 ret_from_debug_exc:
833         RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI)
835         .globl  ret_from_mcheck_exc
836 ret_from_mcheck_exc:
837         RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI)
838 #endif /* CONFIG_BOOKE */
841  * Load the DBCR0 value for a task that is being ptraced,
842  * having first saved away the global DBCR0.  Note that r0
843  * has the dbcr0 value to set upon entry to this.
844  */
845 load_dbcr0:
846         mfmsr   r10             /* first disable debug exceptions */
847         rlwinm  r10,r10,0,~MSR_DE
848         mtmsr   r10
849         isync
850         mfspr   r10,SPRN_DBCR0
851         lis     r11,global_dbcr0@ha
852         addi    r11,r11,global_dbcr0@l
853         stw     r10,0(r11)
854         mtspr   SPRN_DBCR0,r0
855         lwz     r10,4(r11)
856         addi    r10,r10,1
857         stw     r10,4(r11)
858         li      r11,-1
859         mtspr   SPRN_DBSR,r11   /* clear all pending debug events */
860         blr
862         .section .bss
863         .align  4
864 global_dbcr0:
865         .space  8
866         .previous
867 #endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
869 do_work:                        /* r10 contains MSR_KERNEL here */
870         andi.   r0,r9,_TIF_NEED_RESCHED
871         beq     do_user_signal
873 do_resched:                     /* r10 contains MSR_KERNEL here */
874         ori     r10,r10,MSR_EE
875         SYNC
876         MTMSRD(r10)             /* hard-enable interrupts */
877         bl      schedule
878 recheck:
879         LOAD_MSR_KERNEL(r10,MSR_KERNEL)
880         SYNC
881         MTMSRD(r10)             /* disable interrupts */
882         rlwinm  r9,r1,0,0,(31-THREAD_SHIFT)
883         lwz     r9,TI_FLAGS(r9)
884         andi.   r0,r9,_TIF_NEED_RESCHED
885         bne-    do_resched
886         andi.   r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK
887         beq     restore_user
888 do_user_signal:                 /* r10 contains MSR_KERNEL here */
889         ori     r10,r10,MSR_EE
890         SYNC
891         MTMSRD(r10)             /* hard-enable interrupts */
892         /* save r13-r31 in the exception frame, if not already done */
893         lwz     r3,_TRAP(r1)
894         andi.   r0,r3,1
895         beq     2f
896         SAVE_NVGPRS(r1)
897         rlwinm  r3,r3,0,0,30
898         stw     r3,_TRAP(r1)
899 2:      li      r3,0
900         addi    r4,r1,STACK_FRAME_OVERHEAD
901         bl      do_signal
902         REST_NVGPRS(r1)
903         b       recheck
906  * We come here when we are at the end of handling an exception
907  * that occurred at a place where taking an exception will lose
908  * state information, such as the contents of SRR0 and SRR1.
909  */
910 nonrecoverable:
911         lis     r10,exc_exit_restart_end@ha
912         addi    r10,r10,exc_exit_restart_end@l
913         cmplw   r12,r10
914         bge     3f
915         lis     r11,exc_exit_restart@ha
916         addi    r11,r11,exc_exit_restart@l
917         cmplw   r12,r11
918         blt     3f
919         lis     r10,ee_restarts@ha
920         lwz     r12,ee_restarts@l(r10)
921         addi    r12,r12,1
922         stw     r12,ee_restarts@l(r10)
923         mr      r12,r11         /* restart at exc_exit_restart */
924         blr
925 3:      /* OK, we can't recover, kill this process */
926         /* but the 601 doesn't implement the RI bit, so assume it's OK */
927 BEGIN_FTR_SECTION
928         blr
929 END_FTR_SECTION_IFSET(CPU_FTR_601)
930         lwz     r3,_TRAP(r1)
931         andi.   r0,r3,1
932         beq     4f
933         SAVE_NVGPRS(r1)
934         rlwinm  r3,r3,0,0,30
935         stw     r3,_TRAP(r1)
936 4:      addi    r3,r1,STACK_FRAME_OVERHEAD
937         bl      nonrecoverable_exception
938         /* shouldn't return */
939         b       4b
941         .section .bss
942         .align  2
943 ee_restarts:
944         .space  4
945         .previous
948  * PROM code for specific machines follows.  Put it
949  * here so it's easy to add arch-specific sections later.
950  * -- Cort
951  */
952 #ifdef CONFIG_PPC_RTAS
954  * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
955  * called with the MMU off.
956  */
957 _GLOBAL(enter_rtas)
958         stwu    r1,-INT_FRAME_SIZE(r1)
959         mflr    r0
960         stw     r0,INT_FRAME_SIZE+4(r1)
961         LOAD_REG_ADDR(r4, rtas)
962         lis     r6,1f@ha        /* physical return address for rtas */
963         addi    r6,r6,1f@l
964         tophys(r6,r6)
965         tophys(r7,r1)
966         lwz     r8,RTASENTRY(r4)
967         lwz     r4,RTASBASE(r4)
968         mfmsr   r9
969         stw     r9,8(r1)
970         LOAD_MSR_KERNEL(r0,MSR_KERNEL)
971         SYNC                    /* disable interrupts so SRR0/1 */
972         MTMSRD(r0)              /* don't get trashed */
973         li      r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
974         mtlr    r6
975         mtspr   SPRN_SPRG2,r7
976         mtspr   SPRN_SRR0,r8
977         mtspr   SPRN_SRR1,r9
978         RFI
979 1:      tophys(r9,r1)
980         lwz     r8,INT_FRAME_SIZE+4(r9) /* get return address */
981         lwz     r9,8(r9)        /* original msr value */
982         FIX_SRR1(r9,r0)
983         addi    r1,r1,INT_FRAME_SIZE
984         li      r0,0
985         mtspr   SPRN_SPRG2,r0
986         mtspr   SPRN_SRR0,r8
987         mtspr   SPRN_SRR1,r9
988         RFI                     /* return to caller */
990         .globl  machine_check_in_rtas
991 machine_check_in_rtas:
992         twi     31,0,0
993         /* XXX load up BATs and panic */
995 #endif /* CONFIG_PPC_RTAS */