Merge master.kernel.org:/home/rmk/linux-2.6-serial
[linux-2.6] / arch / ppc64 / kernel / entry.S
1 /*
2  *  arch/ppc64/kernel/entry.S
3  *
4  *  PowerPC version 
5  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
7  *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
8  *  Adapted for Power Macintosh by Paul Mackerras.
9  *  Low-level exception handlers and MMU support
10  *  rewritten by Paul Mackerras.
11  *    Copyright (C) 1996 Paul Mackerras.
12  *  MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
13  *
14  *  This file contains the system call entry code, context switch
15  *  code, and exception/interrupt return code for PowerPC.
16  *
17  *  This program is free software; you can redistribute it and/or
18  *  modify it under the terms of the GNU General Public License
19  *  as published by the Free Software Foundation; either version
20  *  2 of the License, or (at your option) any later version.
21  */
22
23 #include <linux/config.h>
24 #include <linux/errno.h>
25 #include <asm/unistd.h>
26 #include <asm/processor.h>
27 #include <asm/page.h>
28 #include <asm/mmu.h>
29 #include <asm/thread_info.h>
30 #include <asm/ppc_asm.h>
31 #include <asm/asm-offsets.h>
32 #include <asm/cputable.h>
33
34 #ifdef CONFIG_PPC_ISERIES
35 #define DO_SOFT_DISABLE
36 #endif
37
38 /*
39  * System calls.
40  */
41         .section        ".toc","aw"
42 .SYS_CALL_TABLE:
43         .tc .sys_call_table[TC],.sys_call_table
44
45 .SYS_CALL_TABLE32:
46         .tc .sys_call_table32[TC],.sys_call_table32
47
48 /* This value is used to mark exception frames on the stack. */
49 exception_marker:
50         .tc     ID_72656773_68657265[TC],0x7265677368657265
51
52         .section        ".text"
53         .align 7
54
55 #undef SHOW_SYSCALLS
56
57         .globl system_call_common
58 system_call_common:
59         andi.   r10,r12,MSR_PR
60         mr      r10,r1
61         addi    r1,r1,-INT_FRAME_SIZE
62         beq-    1f
63         ld      r1,PACAKSAVE(r13)
64 1:      std     r10,0(r1)
65         std     r11,_NIP(r1)
66         std     r12,_MSR(r1)
67         std     r0,GPR0(r1)
68         std     r10,GPR1(r1)
69         std     r2,GPR2(r1)
70         std     r3,GPR3(r1)
71         std     r4,GPR4(r1)
72         std     r5,GPR5(r1)
73         std     r6,GPR6(r1)
74         std     r7,GPR7(r1)
75         std     r8,GPR8(r1)
76         li      r11,0
77         std     r11,GPR9(r1)
78         std     r11,GPR10(r1)
79         std     r11,GPR11(r1)
80         std     r11,GPR12(r1)
81         std     r9,GPR13(r1)
82         crclr   so
83         mfcr    r9
84         mflr    r10
85         li      r11,0xc01
86         std     r9,_CCR(r1)
87         std     r10,_LINK(r1)
88         std     r11,_TRAP(r1)
89         mfxer   r9
90         mfctr   r10
91         std     r9,_XER(r1)
92         std     r10,_CTR(r1)
93         std     r3,ORIG_GPR3(r1)
94         ld      r2,PACATOC(r13)
95         addi    r9,r1,STACK_FRAME_OVERHEAD
96         ld      r11,exception_marker@toc(r2)
97         std     r11,-16(r9)             /* "regshere" marker */
98 #ifdef CONFIG_PPC_ISERIES
99         /* Hack for handling interrupts when soft-enabling on iSeries */
100         cmpdi   cr1,r0,0x5555           /* syscall 0x5555 */
101         andi.   r10,r12,MSR_PR          /* from kernel */
102         crand   4*cr0+eq,4*cr1+eq,4*cr0+eq
103         beq     hardware_interrupt_entry
104         lbz     r10,PACAPROCENABLED(r13)
105         std     r10,SOFTE(r1)
106 #endif
107         mfmsr   r11
108         ori     r11,r11,MSR_EE
109         mtmsrd  r11,1
110
111 #ifdef SHOW_SYSCALLS
112         bl      .do_show_syscall
113         REST_GPR(0,r1)
114         REST_4GPRS(3,r1)
115         REST_2GPRS(7,r1)
116         addi    r9,r1,STACK_FRAME_OVERHEAD
117 #endif
118         clrrdi  r11,r1,THREAD_SHIFT
119         li      r12,0
120         ld      r10,TI_FLAGS(r11)
121         stb     r12,TI_SC_NOERR(r11)
122         andi.   r11,r10,_TIF_SYSCALL_T_OR_A
123         bne-    syscall_dotrace
124 syscall_dotrace_cont:
125         cmpldi  0,r0,NR_syscalls
126         bge-    syscall_enosys
127
128 system_call:                    /* label this so stack traces look sane */
129 /*
130  * Need to vector to 32 Bit or default sys_call_table here,
131  * based on caller's run-mode / personality.
132  */
133         ld      r11,.SYS_CALL_TABLE@toc(2)
134         andi.   r10,r10,_TIF_32BIT
135         beq     15f
136         ld      r11,.SYS_CALL_TABLE32@toc(2)
137         clrldi  r3,r3,32
138         clrldi  r4,r4,32
139         clrldi  r5,r5,32
140         clrldi  r6,r6,32
141         clrldi  r7,r7,32
142         clrldi  r8,r8,32
143 15:
144         slwi    r0,r0,3
145         ldx     r10,r11,r0      /* Fetch system call handler [ptr] */
146         mtctr   r10
147         bctrl                   /* Call handler */
148
149 syscall_exit:
150 #ifdef SHOW_SYSCALLS
151         std     r3,GPR3(r1)
152         bl      .do_show_syscall_exit
153         ld      r3,GPR3(r1)
154 #endif
155         std     r3,RESULT(r1)
156         ld      r5,_CCR(r1)
157         li      r10,-_LAST_ERRNO
158         cmpld   r3,r10
159         clrrdi  r12,r1,THREAD_SHIFT
160         bge-    syscall_error
161 syscall_error_cont:
162
163         /* check for syscall tracing or audit */
164         ld      r9,TI_FLAGS(r12)
165         andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
166         bne-    syscall_exit_trace
167 syscall_exit_trace_cont:
168
169         /* disable interrupts so current_thread_info()->flags can't change,
170            and so that we don't get interrupted after loading SRR0/1. */
171         ld      r8,_MSR(r1)
172         andi.   r10,r8,MSR_RI
173         beq-    unrecov_restore
174         mfmsr   r10
175         rldicl  r10,r10,48,1
176         rotldi  r10,r10,16
177         mtmsrd  r10,1
178         ld      r9,TI_FLAGS(r12)
179         andi.   r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
180         bne-    syscall_exit_work
181         ld      r7,_NIP(r1)
182         stdcx.  r0,0,r1                 /* to clear the reservation */
183         andi.   r6,r8,MSR_PR
184         ld      r4,_LINK(r1)
185         beq-    1f                      /* only restore r13 if */
186         ld      r13,GPR13(r1)           /* returning to usermode */
187 1:      ld      r2,GPR2(r1)
188         li      r12,MSR_RI
189         andc    r10,r10,r12
190         mtmsrd  r10,1                   /* clear MSR.RI */
191         ld      r1,GPR1(r1)
192         mtlr    r4
193         mtcr    r5
194         mtspr   SRR0,r7
195         mtspr   SRR1,r8
196         rfid
197         b       .       /* prevent speculative execution */
198
199 syscall_enosys:
200         li      r3,-ENOSYS
201         std     r3,RESULT(r1)
202         clrrdi  r12,r1,THREAD_SHIFT
203         ld      r5,_CCR(r1)
204
205 syscall_error:
206         lbz     r11,TI_SC_NOERR(r12)
207         cmpwi   0,r11,0
208         bne-    syscall_error_cont
209         neg     r3,r3
210         oris    r5,r5,0x1000    /* Set SO bit in CR */
211         std     r5,_CCR(r1)
212         b       syscall_error_cont
213         
214 /* Traced system call support */
215 syscall_dotrace:
216         bl      .save_nvgprs
217         addi    r3,r1,STACK_FRAME_OVERHEAD
218         bl      .do_syscall_trace_enter
219         ld      r0,GPR0(r1)     /* Restore original registers */
220         ld      r3,GPR3(r1)
221         ld      r4,GPR4(r1)
222         ld      r5,GPR5(r1)
223         ld      r6,GPR6(r1)
224         ld      r7,GPR7(r1)
225         ld      r8,GPR8(r1)
226         addi    r9,r1,STACK_FRAME_OVERHEAD
227         clrrdi  r10,r1,THREAD_SHIFT
228         ld      r10,TI_FLAGS(r10)
229         b       syscall_dotrace_cont
230
231 syscall_exit_trace:
232         std     r3,GPR3(r1)
233         bl      .save_nvgprs
234         addi    r3,r1,STACK_FRAME_OVERHEAD
235         bl      .do_syscall_trace_leave
236         REST_NVGPRS(r1)
237         ld      r3,GPR3(r1)
238         ld      r5,_CCR(r1)
239         clrrdi  r12,r1,THREAD_SHIFT
240         b       syscall_exit_trace_cont
241
242 /* Stuff to do on exit from a system call. */
243 syscall_exit_work:
244         std     r3,GPR3(r1)
245         std     r5,_CCR(r1)
246         b       .ret_from_except_lite
247
248 /* Save non-volatile GPRs, if not already saved. */
249 _GLOBAL(save_nvgprs)
250         ld      r11,_TRAP(r1)
251         andi.   r0,r11,1
252         beqlr-
253         SAVE_NVGPRS(r1)
254         clrrdi  r0,r11,1
255         std     r0,_TRAP(r1)
256         blr
257
258 /*
259  * The sigsuspend and rt_sigsuspend system calls can call do_signal
260  * and thus put the process into the stopped state where we might
261  * want to examine its user state with ptrace.  Therefore we need
262  * to save all the nonvolatile registers (r14 - r31) before calling
263  * the C code.  Similarly, fork, vfork and clone need the full
264  * register state on the stack so that it can be copied to the child.
265  */
266 _GLOBAL(ppc32_sigsuspend)
267         bl      .save_nvgprs
268         bl      .sys32_sigsuspend
269         b       70f
270
271 _GLOBAL(ppc64_rt_sigsuspend)
272         bl      .save_nvgprs
273         bl      .sys_rt_sigsuspend
274         b       70f
275
276 _GLOBAL(ppc32_rt_sigsuspend)
277         bl      .save_nvgprs
278         bl      .sys32_rt_sigsuspend
279         /* If sigsuspend() returns zero, we are going into a signal handler */
280 70:     cmpdi   0,r3,0
281         beq     .ret_from_except
282         /* If it returned -EINTR, we need to return via syscall_exit to set
283            the SO bit in cr0 and potentially stop for ptrace. */
284         b       syscall_exit
285
286 _GLOBAL(ppc_fork)
287         bl      .save_nvgprs
288         bl      .sys_fork
289         b       syscall_exit
290
291 _GLOBAL(ppc_vfork)
292         bl      .save_nvgprs
293         bl      .sys_vfork
294         b       syscall_exit
295
296 _GLOBAL(ppc_clone)
297         bl      .save_nvgprs
298         bl      .sys_clone
299         b       syscall_exit
300
301 _GLOBAL(ppc32_swapcontext)
302         bl      .save_nvgprs
303         bl      .sys32_swapcontext
304         b       80f
305         
306 _GLOBAL(ppc64_swapcontext)
307         bl      .save_nvgprs
308         bl      .sys_swapcontext
309         b       80f
310
311 _GLOBAL(ppc32_sigreturn)
312         bl      .sys32_sigreturn
313         b       80f
314
315 _GLOBAL(ppc32_rt_sigreturn)
316         bl      .sys32_rt_sigreturn
317         b       80f
318
319 _GLOBAL(ppc64_rt_sigreturn)
320         bl      .sys_rt_sigreturn
321
322 80:     cmpdi   0,r3,0
323         blt     syscall_exit
324         clrrdi  r4,r1,THREAD_SHIFT
325         ld      r4,TI_FLAGS(r4)
326         andi.   r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
327         beq+    81f
328         addi    r3,r1,STACK_FRAME_OVERHEAD
329         bl      .do_syscall_trace_leave
330 81:     b       .ret_from_except
331
332 _GLOBAL(ret_from_fork)
333         bl      .schedule_tail
334         REST_NVGPRS(r1)
335         li      r3,0
336         b       syscall_exit
337
338 /*
339  * This routine switches between two different tasks.  The process
340  * state of one is saved on its kernel stack.  Then the state
341  * of the other is restored from its kernel stack.  The memory
342  * management hardware is updated to the second process's state.
343  * Finally, we can return to the second process, via ret_from_except.
344  * On entry, r3 points to the THREAD for the current task, r4
345  * points to the THREAD for the new task.
346  *
347  * Note: there are two ways to get to the "going out" portion
348  * of this code; either by coming in via the entry (_switch)
349  * or via "fork" which must set up an environment equivalent
350  * to the "_switch" path.  If you change this you'll have to change
351  * the fork code also.
352  *
353  * The code which creates the new task context is in 'copy_thread'
354  * in arch/ppc64/kernel/process.c
355  */
356         .align  7
357 _GLOBAL(_switch)
358         mflr    r0
359         std     r0,16(r1)
360         stdu    r1,-SWITCH_FRAME_SIZE(r1)
361         /* r3-r13 are caller saved -- Cort */
362         SAVE_8GPRS(14, r1)
363         SAVE_10GPRS(22, r1)
364         mflr    r20             /* Return to switch caller */
365         mfmsr   r22
366         li      r0, MSR_FP
367 #ifdef CONFIG_ALTIVEC
368 BEGIN_FTR_SECTION
369         oris    r0,r0,MSR_VEC@h /* Disable altivec */
370         mfspr   r24,SPRN_VRSAVE /* save vrsave register value */
371         std     r24,THREAD_VRSAVE(r3)
372 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
373 #endif /* CONFIG_ALTIVEC */
374         and.    r0,r0,r22
375         beq+    1f
376         andc    r22,r22,r0
377         mtmsrd  r22
378         isync
379 1:      std     r20,_NIP(r1)
380         mfcr    r23
381         std     r23,_CCR(r1)
382         std     r1,KSP(r3)      /* Set old stack pointer */
383
384 #ifdef CONFIG_SMP
385         /* We need a sync somewhere here to make sure that if the
386          * previous task gets rescheduled on another CPU, it sees all
387          * stores it has performed on this one.
388          */
389         sync
390 #endif /* CONFIG_SMP */
391
392         addi    r6,r4,-THREAD   /* Convert THREAD to 'current' */
393         std     r6,PACACURRENT(r13)     /* Set new 'current' */
394
395         ld      r8,KSP(r4)      /* new stack pointer */
396 BEGIN_FTR_SECTION
397         clrrdi  r6,r8,28        /* get its ESID */
398         clrrdi  r9,r1,28        /* get current sp ESID */
399         clrldi. r0,r6,2         /* is new ESID c00000000? */
400         cmpd    cr1,r6,r9       /* or is new ESID the same as current ESID? */
401         cror    eq,4*cr1+eq,eq
402         beq     2f              /* if yes, don't slbie it */
403
404         /* Bolt in the new stack SLB entry */
405         ld      r7,KSP_VSID(r4) /* Get new stack's VSID */
406         oris    r0,r6,(SLB_ESID_V)@h
407         ori     r0,r0,(SLB_NUM_BOLTED-1)@l
408         slbie   r6
409         slbie   r6              /* Workaround POWER5 < DD2.1 issue */
410         slbmte  r7,r0
411         isync
412
413 2:
414 END_FTR_SECTION_IFSET(CPU_FTR_SLB)
415         clrrdi  r7,r8,THREAD_SHIFT      /* base of new stack */
416         /* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE
417            because we don't need to leave the 288-byte ABI gap at the
418            top of the kernel stack. */
419         addi    r7,r7,THREAD_SIZE-SWITCH_FRAME_SIZE
420
421         mr      r1,r8           /* start using new stack pointer */
422         std     r7,PACAKSAVE(r13)
423
424         ld      r6,_CCR(r1)
425         mtcrf   0xFF,r6
426
427 #ifdef CONFIG_ALTIVEC
428 BEGIN_FTR_SECTION
429         ld      r0,THREAD_VRSAVE(r4)
430         mtspr   SPRN_VRSAVE,r0          /* if G4, restore VRSAVE reg */
431 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
432 #endif /* CONFIG_ALTIVEC */
433
434         /* r3-r13 are destroyed -- Cort */
435         REST_8GPRS(14, r1)
436         REST_10GPRS(22, r1)
437
438         /* convert old thread to its task_struct for return value */
439         addi    r3,r3,-THREAD
440         ld      r7,_NIP(r1)     /* Return to _switch caller in new task */
441         mtlr    r7
442         addi    r1,r1,SWITCH_FRAME_SIZE
443         blr
444
445         .align  7
446 _GLOBAL(ret_from_except)
447         ld      r11,_TRAP(r1)
448         andi.   r0,r11,1
449         bne     .ret_from_except_lite
450         REST_NVGPRS(r1)
451
452 _GLOBAL(ret_from_except_lite)
453         /*
454          * Disable interrupts so that current_thread_info()->flags
455          * can't change between when we test it and when we return
456          * from the interrupt.
457          */
458         mfmsr   r10             /* Get current interrupt state */
459         rldicl  r9,r10,48,1     /* clear MSR_EE */
460         rotldi  r9,r9,16
461         mtmsrd  r9,1            /* Update machine state */
462
463 #ifdef CONFIG_PREEMPT
464         clrrdi  r9,r1,THREAD_SHIFT      /* current_thread_info() */
465         li      r0,_TIF_NEED_RESCHED    /* bits to check */
466         ld      r3,_MSR(r1)
467         ld      r4,TI_FLAGS(r9)
468         /* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */
469         rlwimi  r0,r3,32+TIF_SIGPENDING-MSR_PR_LG,_TIF_SIGPENDING
470         and.    r0,r4,r0        /* check NEED_RESCHED and maybe SIGPENDING */
471         bne     do_work
472
473 #else /* !CONFIG_PREEMPT */
474         ld      r3,_MSR(r1)     /* Returning to user mode? */
475         andi.   r3,r3,MSR_PR
476         beq     restore         /* if not, just restore regs and return */
477
478         /* Check current_thread_info()->flags */
479         clrrdi  r9,r1,THREAD_SHIFT
480         ld      r4,TI_FLAGS(r9)
481         andi.   r0,r4,_TIF_USER_WORK_MASK
482         bne     do_work
483 #endif
484
485 restore:
486 #ifdef CONFIG_PPC_ISERIES
487         ld      r5,SOFTE(r1)
488         cmpdi   0,r5,0
489         beq     4f
490         /* Check for pending interrupts (iSeries) */
491         ld      r3,PACALPPACA+LPPACAANYINT(r13)
492         cmpdi   r3,0
493         beq+    4f                      /* skip do_IRQ if no interrupts */
494
495         li      r3,0
496         stb     r3,PACAPROCENABLED(r13) /* ensure we are soft-disabled */
497         ori     r10,r10,MSR_EE
498         mtmsrd  r10                     /* hard-enable again */
499         addi    r3,r1,STACK_FRAME_OVERHEAD
500         bl      .do_IRQ
501         b       .ret_from_except_lite           /* loop back and handle more */
502
503 4:      stb     r5,PACAPROCENABLED(r13)
504 #endif
505
506         ld      r3,_MSR(r1)
507         andi.   r0,r3,MSR_RI
508         beq-    unrecov_restore
509
510         andi.   r0,r3,MSR_PR
511
512         /*
513          * r13 is our per cpu area, only restore it if we are returning to
514          * userspace
515          */
516         beq     1f
517         REST_GPR(13, r1)
518 1:
519         ld      r3,_CTR(r1)
520         ld      r0,_LINK(r1)
521         mtctr   r3
522         mtlr    r0
523         ld      r3,_XER(r1)
524         mtspr   XER,r3
525
526         REST_8GPRS(5, r1)
527
528         stdcx.  r0,0,r1         /* to clear the reservation */
529
530         mfmsr   r0
531         li      r2, MSR_RI
532         andc    r0,r0,r2
533         mtmsrd  r0,1
534
535         ld      r0,_MSR(r1)
536         mtspr   SRR1,r0
537
538         ld      r2,_CCR(r1)
539         mtcrf   0xFF,r2
540         ld      r2,_NIP(r1)
541         mtspr   SRR0,r2
542
543         ld      r0,GPR0(r1)
544         ld      r2,GPR2(r1)
545         ld      r3,GPR3(r1)
546         ld      r4,GPR4(r1)
547         ld      r1,GPR1(r1)
548
549         rfid
550         b       .       /* prevent speculative execution */
551
552 /* Note: this must change if we start using the TIF_NOTIFY_RESUME bit */
553 do_work:
554 #ifdef CONFIG_PREEMPT
555         andi.   r0,r3,MSR_PR    /* Returning to user mode? */
556         bne     user_work
557         /* Check that preempt_count() == 0 and interrupts are enabled */
558         lwz     r8,TI_PREEMPT(r9)
559         cmpwi   cr1,r8,0
560 #ifdef CONFIG_PPC_ISERIES
561         ld      r0,SOFTE(r1)
562         cmpdi   r0,0
563 #else
564         andi.   r0,r3,MSR_EE
565 #endif
566         crandc  eq,cr1*4+eq,eq
567         bne     restore
568         /* here we are preempting the current task */
569 1:
570 #ifdef CONFIG_PPC_ISERIES
571         li      r0,1
572         stb     r0,PACAPROCENABLED(r13)
573 #endif
574         ori     r10,r10,MSR_EE
575         mtmsrd  r10,1           /* reenable interrupts */
576         bl      .preempt_schedule
577         mfmsr   r10
578         clrrdi  r9,r1,THREAD_SHIFT
579         rldicl  r10,r10,48,1    /* disable interrupts again */
580         rotldi  r10,r10,16
581         mtmsrd  r10,1
582         ld      r4,TI_FLAGS(r9)
583         andi.   r0,r4,_TIF_NEED_RESCHED
584         bne     1b
585         b       restore
586
587 user_work:
588 #endif
589         /* Enable interrupts */
590         ori     r10,r10,MSR_EE
591         mtmsrd  r10,1
592
593         andi.   r0,r4,_TIF_NEED_RESCHED
594         beq     1f
595         bl      .schedule
596         b       .ret_from_except_lite
597
598 1:      bl      .save_nvgprs
599         li      r3,0
600         addi    r4,r1,STACK_FRAME_OVERHEAD
601         bl      .do_signal
602         b       .ret_from_except
603
604 unrecov_restore:
605         addi    r3,r1,STACK_FRAME_OVERHEAD
606         bl      .unrecoverable_exception
607         b       unrecov_restore
608
609 #ifdef CONFIG_PPC_RTAS
610 /*
611  * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
612  * called with the MMU off.
613  *
614  * In addition, we need to be in 32b mode, at least for now.
615  * 
616  * Note: r3 is an input parameter to rtas, so don't trash it...
617  */
618 _GLOBAL(enter_rtas)
619         mflr    r0
620         std     r0,16(r1)
621         stdu    r1,-RTAS_FRAME_SIZE(r1) /* Save SP and create stack space. */
622
623         /* Because RTAS is running in 32b mode, it clobbers the high order half
624          * of all registers that it saves.  We therefore save those registers
625          * RTAS might touch to the stack.  (r0, r3-r13 are caller saved)
626          */
627         SAVE_GPR(2, r1)                 /* Save the TOC */
628         SAVE_GPR(13, r1)                /* Save paca */
629         SAVE_8GPRS(14, r1)              /* Save the non-volatiles */
630         SAVE_10GPRS(22, r1)             /* ditto */
631
632         mfcr    r4
633         std     r4,_CCR(r1)
634         mfctr   r5
635         std     r5,_CTR(r1)
636         mfspr   r6,XER
637         std     r6,_XER(r1)
638         mfdar   r7
639         std     r7,_DAR(r1)
640         mfdsisr r8
641         std     r8,_DSISR(r1)
642         mfsrr0  r9
643         std     r9,_SRR0(r1)
644         mfsrr1  r10
645         std     r10,_SRR1(r1)
646
647         /* There is no way it is acceptable to get here with interrupts enabled,
648          * check it with the asm equivalent of WARN_ON
649          */
650         mfmsr   r6
651         andi.   r0,r6,MSR_EE
652 1:      tdnei   r0,0
653 .section __bug_table,"a"
654         .llong  1b,__LINE__ + 0x1000000, 1f, 2f
655 .previous
656 .section .rodata,"a"
657 1:      .asciz  __FILE__
658 2:      .asciz "enter_rtas"
659 .previous
660         
661         /* Unfortunately, the stack pointer and the MSR are also clobbered,
662          * so they are saved in the PACA which allows us to restore
663          * our original state after RTAS returns.
664          */
665         std     r1,PACAR1(r13)
666         std     r6,PACASAVEDMSR(r13)
667
668         /* Setup our real return addr */        
669         SET_REG_TO_LABEL(r4,.rtas_return_loc)
670         SET_REG_TO_CONST(r9,KERNELBASE)
671         sub     r4,r4,r9
672         mtlr    r4
673
674         li      r0,0
675         ori     r0,r0,MSR_EE|MSR_SE|MSR_BE|MSR_RI
676         andc    r0,r6,r0
677         
678         li      r9,1
679         rldicr  r9,r9,MSR_SF_LG,(63-MSR_SF_LG)
680         ori     r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP
681         andc    r6,r0,r9
682         ori     r6,r6,MSR_RI
683         sync                            /* disable interrupts so SRR0/1 */
684         mtmsrd  r0                      /* don't get trashed */
685
686         SET_REG_TO_LABEL(r4,rtas)
687         ld      r5,RTASENTRY(r4)        /* get the rtas->entry value */
688         ld      r4,RTASBASE(r4)         /* get the rtas->base value */
689         
690         mtspr   SRR0,r5
691         mtspr   SRR1,r6
692         rfid
693         b       .       /* prevent speculative execution */
694
695 _STATIC(rtas_return_loc)
696         /* relocation is off at this point */
697         mfspr   r4,SPRG3                /* Get PACA */
698         SET_REG_TO_CONST(r5, KERNELBASE)
699         sub     r4,r4,r5                /* RELOC the PACA base pointer */
700
701         mfmsr   r6
702         li      r0,MSR_RI
703         andc    r6,r6,r0
704         sync    
705         mtmsrd  r6
706         
707         ld      r1,PACAR1(r4)           /* Restore our SP */
708         LOADADDR(r3,.rtas_restore_regs)
709         ld      r4,PACASAVEDMSR(r4)     /* Restore our MSR */
710
711         mtspr   SRR0,r3
712         mtspr   SRR1,r4
713         rfid
714         b       .       /* prevent speculative execution */
715
716 _STATIC(rtas_restore_regs)
717         /* relocation is on at this point */
718         REST_GPR(2, r1)                 /* Restore the TOC */
719         REST_GPR(13, r1)                /* Restore paca */
720         REST_8GPRS(14, r1)              /* Restore the non-volatiles */
721         REST_10GPRS(22, r1)             /* ditto */
722
723         mfspr   r13,SPRG3
724
725         ld      r4,_CCR(r1)
726         mtcr    r4
727         ld      r5,_CTR(r1)
728         mtctr   r5
729         ld      r6,_XER(r1)
730         mtspr   XER,r6
731         ld      r7,_DAR(r1)
732         mtdar   r7
733         ld      r8,_DSISR(r1)
734         mtdsisr r8
735         ld      r9,_SRR0(r1)
736         mtsrr0  r9
737         ld      r10,_SRR1(r1)
738         mtsrr1  r10
739
740         addi    r1,r1,RTAS_FRAME_SIZE   /* Unstack our frame */
741         ld      r0,16(r1)               /* get return address */
742
743         mtlr    r0
744         blr                             /* return to caller */
745
746 #endif /* CONFIG_PPC_RTAS */
747
748 #ifdef CONFIG_PPC_MULTIPLATFORM
749
750 _GLOBAL(enter_prom)
751         mflr    r0
752         std     r0,16(r1)
753         stdu    r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */
754
755         /* Because PROM is running in 32b mode, it clobbers the high order half
756          * of all registers that it saves.  We therefore save those registers
757          * PROM might touch to the stack.  (r0, r3-r13 are caller saved)
758          */
759         SAVE_8GPRS(2, r1)
760         SAVE_GPR(13, r1)
761         SAVE_8GPRS(14, r1)
762         SAVE_10GPRS(22, r1)
763         mfcr    r4
764         std     r4,_CCR(r1)
765         mfctr   r5
766         std     r5,_CTR(r1)
767         mfspr   r6,XER
768         std     r6,_XER(r1)
769         mfdar   r7
770         std     r7,_DAR(r1)
771         mfdsisr r8
772         std     r8,_DSISR(r1)
773         mfsrr0  r9
774         std     r9,_SRR0(r1)
775         mfsrr1  r10
776         std     r10,_SRR1(r1)
777         mfmsr   r11
778         std     r11,_MSR(r1)
779
780         /* Get the PROM entrypoint */
781         ld      r0,GPR4(r1)
782         mtlr    r0
783
784         /* Switch MSR to 32 bits mode
785          */
786         mfmsr   r11
787         li      r12,1
788         rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
789         andc    r11,r11,r12
790         li      r12,1
791         rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
792         andc    r11,r11,r12
793         mtmsrd  r11
794         isync
795
796         /* Restore arguments & enter PROM here... */
797         ld      r3,GPR3(r1)
798         blrl
799
800         /* Just make sure that r1 top 32 bits didn't get
801          * corrupt by OF
802          */
803         rldicl  r1,r1,0,32
804
805         /* Restore the MSR (back to 64 bits) */
806         ld      r0,_MSR(r1)
807         mtmsrd  r0
808         isync
809
810         /* Restore other registers */
811         REST_GPR(2, r1)
812         REST_GPR(13, r1)
813         REST_8GPRS(14, r1)
814         REST_10GPRS(22, r1)
815         ld      r4,_CCR(r1)
816         mtcr    r4
817         ld      r5,_CTR(r1)
818         mtctr   r5
819         ld      r6,_XER(r1)
820         mtspr   XER,r6
821         ld      r7,_DAR(r1)
822         mtdar   r7
823         ld      r8,_DSISR(r1)
824         mtdsisr r8
825         ld      r9,_SRR0(r1)
826         mtsrr0  r9
827         ld      r10,_SRR1(r1)
828         mtsrr1  r10
829         
830         addi    r1,r1,PROM_FRAME_SIZE
831         ld      r0,16(r1)
832         mtlr    r0
833         blr
834         
835 #endif  /* CONFIG_PPC_MULTIPLATFORM */