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