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