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