ae5d563ad93a8bff1b4fdbaa9c91b579128dbb00
[sfrench/cifs-2.6.git] / 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/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 70:     cmpdi   0,r3,0
280         /* If it returned an error, we need to return via syscall_exit to set
281            the SO bit in cr0 and potentially stop for ptrace. */
282         bne     syscall_exit
283         /* If sigsuspend() returns zero, we are going into a signal handler. We
284            may need to call audit_syscall_exit() to mark the exit from sigsuspend() */
285         ld      r3,PACACURRENT(r13)
286         ld      r4,AUDITCONTEXT(r3)
287         cmpdi   0,r4,0
288         beq     .ret_from_except        /* No audit_context: Leave immediately. */
289         li      r4, 2                   /* AUDITSC_FAILURE */
290         li      r5,-4                   /* It's always -EINTR */
291         bl      .audit_syscall_exit
292         b       .ret_from_except
293
294 _GLOBAL(ppc_fork)
295         bl      .save_nvgprs
296         bl      .sys_fork
297         b       syscall_exit
298
299 _GLOBAL(ppc_vfork)
300         bl      .save_nvgprs
301         bl      .sys_vfork
302         b       syscall_exit
303
304 _GLOBAL(ppc_clone)
305         bl      .save_nvgprs
306         bl      .sys_clone
307         b       syscall_exit
308
309 _GLOBAL(ppc32_swapcontext)
310         bl      .save_nvgprs
311         bl      .sys32_swapcontext
312         b       80f
313         
314 _GLOBAL(ppc64_swapcontext)
315         bl      .save_nvgprs
316         bl      .sys_swapcontext
317         b       80f
318
319 _GLOBAL(ppc32_sigreturn)
320         bl      .sys32_sigreturn
321         b       80f
322
323 _GLOBAL(ppc32_rt_sigreturn)
324         bl      .sys32_rt_sigreturn
325         b       80f
326
327 _GLOBAL(ppc64_rt_sigreturn)
328         bl      .sys_rt_sigreturn
329
330 80:     cmpdi   0,r3,0
331         blt     syscall_exit
332         clrrdi  r4,r1,THREAD_SHIFT
333         ld      r4,TI_FLAGS(r4)
334         andi.   r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
335         beq+    81f
336         addi    r3,r1,STACK_FRAME_OVERHEAD
337         bl      .do_syscall_trace_leave
338 81:     b       .ret_from_except
339
340 _GLOBAL(ret_from_fork)
341         bl      .schedule_tail
342         REST_NVGPRS(r1)
343         li      r3,0
344         b       syscall_exit
345
346 /*
347  * This routine switches between two different tasks.  The process
348  * state of one is saved on its kernel stack.  Then the state
349  * of the other is restored from its kernel stack.  The memory
350  * management hardware is updated to the second process's state.
351  * Finally, we can return to the second process, via ret_from_except.
352  * On entry, r3 points to the THREAD for the current task, r4
353  * points to the THREAD for the new task.
354  *
355  * Note: there are two ways to get to the "going out" portion
356  * of this code; either by coming in via the entry (_switch)
357  * or via "fork" which must set up an environment equivalent
358  * to the "_switch" path.  If you change this you'll have to change
359  * the fork code also.
360  *
361  * The code which creates the new task context is in 'copy_thread'
362  * in arch/ppc64/kernel/process.c
363  */
364         .align  7
365 _GLOBAL(_switch)
366         mflr    r0
367         std     r0,16(r1)
368         stdu    r1,-SWITCH_FRAME_SIZE(r1)
369         /* r3-r13 are caller saved -- Cort */
370         SAVE_8GPRS(14, r1)
371         SAVE_10GPRS(22, r1)
372         mflr    r20             /* Return to switch caller */
373         mfmsr   r22
374         li      r0, MSR_FP
375 #ifdef CONFIG_ALTIVEC
376 BEGIN_FTR_SECTION
377         oris    r0,r0,MSR_VEC@h /* Disable altivec */
378         mfspr   r24,SPRN_VRSAVE /* save vrsave register value */
379         std     r24,THREAD_VRSAVE(r3)
380 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
381 #endif /* CONFIG_ALTIVEC */
382         and.    r0,r0,r22
383         beq+    1f
384         andc    r22,r22,r0
385         mtmsrd  r22
386         isync
387 1:      std     r20,_NIP(r1)
388         mfcr    r23
389         std     r23,_CCR(r1)
390         std     r1,KSP(r3)      /* Set old stack pointer */
391
392 #ifdef CONFIG_SMP
393         /* We need a sync somewhere here to make sure that if the
394          * previous task gets rescheduled on another CPU, it sees all
395          * stores it has performed on this one.
396          */
397         sync
398 #endif /* CONFIG_SMP */
399
400         addi    r6,r4,-THREAD   /* Convert THREAD to 'current' */
401         std     r6,PACACURRENT(r13)     /* Set new 'current' */
402
403         ld      r8,KSP(r4)      /* new stack pointer */
404 BEGIN_FTR_SECTION
405         clrrdi  r6,r8,28        /* get its ESID */
406         clrrdi  r9,r1,28        /* get current sp ESID */
407         clrldi. r0,r6,2         /* is new ESID c00000000? */
408         cmpd    cr1,r6,r9       /* or is new ESID the same as current ESID? */
409         cror    eq,4*cr1+eq,eq
410         beq     2f              /* if yes, don't slbie it */
411         oris    r0,r6,0x0800    /* set C (class) bit */
412
413         /* Bolt in the new stack SLB entry */
414         ld      r7,KSP_VSID(r4) /* Get new stack's VSID */
415         oris    r6,r6,(SLB_ESID_V)@h
416         ori     r6,r6,(SLB_NUM_BOLTED-1)@l
417         slbie   r0
418         slbie   r0              /* Workaround POWER5 < DD2.1 issue */
419         slbmte  r7,r6
420         isync
421
422 2:
423 END_FTR_SECTION_IFSET(CPU_FTR_SLB)
424         clrrdi  r7,r8,THREAD_SHIFT      /* base of new stack */
425         /* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE
426            because we don't need to leave the 288-byte ABI gap at the
427            top of the kernel stack. */
428         addi    r7,r7,THREAD_SIZE-SWITCH_FRAME_SIZE
429
430         mr      r1,r8           /* start using new stack pointer */
431         std     r7,PACAKSAVE(r13)
432
433         ld      r6,_CCR(r1)
434         mtcrf   0xFF,r6
435
436 #ifdef CONFIG_ALTIVEC
437 BEGIN_FTR_SECTION
438         ld      r0,THREAD_VRSAVE(r4)
439         mtspr   SPRN_VRSAVE,r0          /* if G4, restore VRSAVE reg */
440 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
441 #endif /* CONFIG_ALTIVEC */
442
443         /* r3-r13 are destroyed -- Cort */
444         REST_8GPRS(14, r1)
445         REST_10GPRS(22, r1)
446
447         /* convert old thread to its task_struct for return value */
448         addi    r3,r3,-THREAD
449         ld      r7,_NIP(r1)     /* Return to _switch caller in new task */
450         mtlr    r7
451         addi    r1,r1,SWITCH_FRAME_SIZE
452         blr
453
454         .align  7
455 _GLOBAL(ret_from_except)
456         ld      r11,_TRAP(r1)
457         andi.   r0,r11,1
458         bne     .ret_from_except_lite
459         REST_NVGPRS(r1)
460
461 _GLOBAL(ret_from_except_lite)
462         /*
463          * Disable interrupts so that current_thread_info()->flags
464          * can't change between when we test it and when we return
465          * from the interrupt.
466          */
467         mfmsr   r10             /* Get current interrupt state */
468         rldicl  r9,r10,48,1     /* clear MSR_EE */
469         rotldi  r9,r9,16
470         mtmsrd  r9,1            /* Update machine state */
471
472 #ifdef CONFIG_PREEMPT
473         clrrdi  r9,r1,THREAD_SHIFT      /* current_thread_info() */
474         li      r0,_TIF_NEED_RESCHED    /* bits to check */
475         ld      r3,_MSR(r1)
476         ld      r4,TI_FLAGS(r9)
477         /* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */
478         rlwimi  r0,r3,32+TIF_SIGPENDING-MSR_PR_LG,_TIF_SIGPENDING
479         and.    r0,r4,r0        /* check NEED_RESCHED and maybe SIGPENDING */
480         bne     do_work
481
482 #else /* !CONFIG_PREEMPT */
483         ld      r3,_MSR(r1)     /* Returning to user mode? */
484         andi.   r3,r3,MSR_PR
485         beq     restore         /* if not, just restore regs and return */
486
487         /* Check current_thread_info()->flags */
488         clrrdi  r9,r1,THREAD_SHIFT
489         ld      r4,TI_FLAGS(r9)
490         andi.   r0,r4,_TIF_USER_WORK_MASK
491         bne     do_work
492 #endif
493
494 restore:
495 #ifdef CONFIG_PPC_ISERIES
496         ld      r5,SOFTE(r1)
497         cmpdi   0,r5,0
498         beq     4f
499         /* Check for pending interrupts (iSeries) */
500         ld      r3,PACALPPACA+LPPACAANYINT(r13)
501         cmpdi   r3,0
502         beq+    4f                      /* skip do_IRQ if no interrupts */
503
504         li      r3,0
505         stb     r3,PACAPROCENABLED(r13) /* ensure we are soft-disabled */
506         ori     r10,r10,MSR_EE
507         mtmsrd  r10                     /* hard-enable again */
508         addi    r3,r1,STACK_FRAME_OVERHEAD
509         bl      .do_IRQ
510         b       .ret_from_except_lite           /* loop back and handle more */
511
512 4:      stb     r5,PACAPROCENABLED(r13)
513 #endif
514
515         ld      r3,_MSR(r1)
516         andi.   r0,r3,MSR_RI
517         beq-    unrecov_restore
518
519         andi.   r0,r3,MSR_PR
520
521         /*
522          * r13 is our per cpu area, only restore it if we are returning to
523          * userspace
524          */
525         beq     1f
526         REST_GPR(13, r1)
527 1:
528         ld      r3,_CTR(r1)
529         ld      r0,_LINK(r1)
530         mtctr   r3
531         mtlr    r0
532         ld      r3,_XER(r1)
533         mtspr   XER,r3
534
535         REST_8GPRS(5, r1)
536
537         stdcx.  r0,0,r1         /* to clear the reservation */
538
539         mfmsr   r0
540         li      r2, MSR_RI
541         andc    r0,r0,r2
542         mtmsrd  r0,1
543
544         ld      r0,_MSR(r1)
545         mtspr   SRR1,r0
546
547         ld      r2,_CCR(r1)
548         mtcrf   0xFF,r2
549         ld      r2,_NIP(r1)
550         mtspr   SRR0,r2
551
552         ld      r0,GPR0(r1)
553         ld      r2,GPR2(r1)
554         ld      r3,GPR3(r1)
555         ld      r4,GPR4(r1)
556         ld      r1,GPR1(r1)
557
558         rfid
559         b       .       /* prevent speculative execution */
560
561 /* Note: this must change if we start using the TIF_NOTIFY_RESUME bit */
562 do_work:
563 #ifdef CONFIG_PREEMPT
564         andi.   r0,r3,MSR_PR    /* Returning to user mode? */
565         bne     user_work
566         /* Check that preempt_count() == 0 and interrupts are enabled */
567         lwz     r8,TI_PREEMPT(r9)
568         cmpwi   cr1,r8,0
569 #ifdef CONFIG_PPC_ISERIES
570         ld      r0,SOFTE(r1)
571         cmpdi   r0,0
572 #else
573         andi.   r0,r3,MSR_EE
574 #endif
575         crandc  eq,cr1*4+eq,eq
576         bne     restore
577         /* here we are preempting the current task */
578 1:
579 #ifdef CONFIG_PPC_ISERIES
580         li      r0,1
581         stb     r0,PACAPROCENABLED(r13)
582 #endif
583         ori     r10,r10,MSR_EE
584         mtmsrd  r10,1           /* reenable interrupts */
585         bl      .preempt_schedule
586         mfmsr   r10
587         clrrdi  r9,r1,THREAD_SHIFT
588         rldicl  r10,r10,48,1    /* disable interrupts again */
589         rotldi  r10,r10,16
590         mtmsrd  r10,1
591         ld      r4,TI_FLAGS(r9)
592         andi.   r0,r4,_TIF_NEED_RESCHED
593         bne     1b
594         b       restore
595
596 user_work:
597 #endif
598         /* Enable interrupts */
599         ori     r10,r10,MSR_EE
600         mtmsrd  r10,1
601
602         andi.   r0,r4,_TIF_NEED_RESCHED
603         beq     1f
604         bl      .schedule
605         b       .ret_from_except_lite
606
607 1:      bl      .save_nvgprs
608         li      r3,0
609         addi    r4,r1,STACK_FRAME_OVERHEAD
610         bl      .do_signal
611         b       .ret_from_except
612
613 unrecov_restore:
614         addi    r3,r1,STACK_FRAME_OVERHEAD
615         bl      .unrecoverable_exception
616         b       unrecov_restore
617
618 #ifdef CONFIG_PPC_RTAS
619 /*
620  * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
621  * called with the MMU off.
622  *
623  * In addition, we need to be in 32b mode, at least for now.
624  * 
625  * Note: r3 is an input parameter to rtas, so don't trash it...
626  */
627 _GLOBAL(enter_rtas)
628         mflr    r0
629         std     r0,16(r1)
630         stdu    r1,-RTAS_FRAME_SIZE(r1) /* Save SP and create stack space. */
631
632         /* Because RTAS is running in 32b mode, it clobbers the high order half
633          * of all registers that it saves.  We therefore save those registers
634          * RTAS might touch to the stack.  (r0, r3-r13 are caller saved)
635          */
636         SAVE_GPR(2, r1)                 /* Save the TOC */
637         SAVE_GPR(13, r1)                /* Save paca */
638         SAVE_8GPRS(14, r1)              /* Save the non-volatiles */
639         SAVE_10GPRS(22, r1)             /* ditto */
640
641         mfcr    r4
642         std     r4,_CCR(r1)
643         mfctr   r5
644         std     r5,_CTR(r1)
645         mfspr   r6,XER
646         std     r6,_XER(r1)
647         mfdar   r7
648         std     r7,_DAR(r1)
649         mfdsisr r8
650         std     r8,_DSISR(r1)
651         mfsrr0  r9
652         std     r9,_SRR0(r1)
653         mfsrr1  r10
654         std     r10,_SRR1(r1)
655
656         /* There is no way it is acceptable to get here with interrupts enabled,
657          * check it with the asm equivalent of WARN_ON
658          */
659         mfmsr   r6
660         andi.   r0,r6,MSR_EE
661 1:      tdnei   r0,0
662 .section __bug_table,"a"
663         .llong  1b,__LINE__ + 0x1000000, 1f, 2f
664 .previous
665 .section .rodata,"a"
666 1:      .asciz  __FILE__
667 2:      .asciz "enter_rtas"
668 .previous
669         
670         /* Unfortunately, the stack pointer and the MSR are also clobbered,
671          * so they are saved in the PACA which allows us to restore
672          * our original state after RTAS returns.
673          */
674         std     r1,PACAR1(r13)
675         std     r6,PACASAVEDMSR(r13)
676
677         /* Setup our real return addr */        
678         SET_REG_TO_LABEL(r4,.rtas_return_loc)
679         SET_REG_TO_CONST(r9,KERNELBASE)
680         sub     r4,r4,r9
681         mtlr    r4
682
683         li      r0,0
684         ori     r0,r0,MSR_EE|MSR_SE|MSR_BE|MSR_RI
685         andc    r0,r6,r0
686         
687         li      r9,1
688         rldicr  r9,r9,MSR_SF_LG,(63-MSR_SF_LG)
689         ori     r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP
690         andc    r6,r0,r9
691         ori     r6,r6,MSR_RI
692         sync                            /* disable interrupts so SRR0/1 */
693         mtmsrd  r0                      /* don't get trashed */
694
695         SET_REG_TO_LABEL(r4,rtas)
696         ld      r5,RTASENTRY(r4)        /* get the rtas->entry value */
697         ld      r4,RTASBASE(r4)         /* get the rtas->base value */
698         
699         mtspr   SRR0,r5
700         mtspr   SRR1,r6
701         rfid
702         b       .       /* prevent speculative execution */
703
704 _STATIC(rtas_return_loc)
705         /* relocation is off at this point */
706         mfspr   r4,SPRG3                /* Get PACA */
707         SET_REG_TO_CONST(r5, KERNELBASE)
708         sub     r4,r4,r5                /* RELOC the PACA base pointer */
709
710         mfmsr   r6
711         li      r0,MSR_RI
712         andc    r6,r6,r0
713         sync    
714         mtmsrd  r6
715         
716         ld      r1,PACAR1(r4)           /* Restore our SP */
717         LOADADDR(r3,.rtas_restore_regs)
718         ld      r4,PACASAVEDMSR(r4)     /* Restore our MSR */
719
720         mtspr   SRR0,r3
721         mtspr   SRR1,r4
722         rfid
723         b       .       /* prevent speculative execution */
724
725 _STATIC(rtas_restore_regs)
726         /* relocation is on at this point */
727         REST_GPR(2, r1)                 /* Restore the TOC */
728         REST_GPR(13, r1)                /* Restore paca */
729         REST_8GPRS(14, r1)              /* Restore the non-volatiles */
730         REST_10GPRS(22, r1)             /* ditto */
731
732         mfspr   r13,SPRG3
733
734         ld      r4,_CCR(r1)
735         mtcr    r4
736         ld      r5,_CTR(r1)
737         mtctr   r5
738         ld      r6,_XER(r1)
739         mtspr   XER,r6
740         ld      r7,_DAR(r1)
741         mtdar   r7
742         ld      r8,_DSISR(r1)
743         mtdsisr r8
744         ld      r9,_SRR0(r1)
745         mtsrr0  r9
746         ld      r10,_SRR1(r1)
747         mtsrr1  r10
748
749         addi    r1,r1,RTAS_FRAME_SIZE   /* Unstack our frame */
750         ld      r0,16(r1)               /* get return address */
751
752         mtlr    r0
753         blr                             /* return to caller */
754
755 #endif /* CONFIG_PPC_RTAS */
756
757 #ifdef CONFIG_PPC_MULTIPLATFORM
758
759 _GLOBAL(enter_prom)
760         mflr    r0
761         std     r0,16(r1)
762         stdu    r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */
763
764         /* Because PROM is running in 32b mode, it clobbers the high order half
765          * of all registers that it saves.  We therefore save those registers
766          * PROM might touch to the stack.  (r0, r3-r13 are caller saved)
767          */
768         SAVE_8GPRS(2, r1)
769         SAVE_GPR(13, r1)
770         SAVE_8GPRS(14, r1)
771         SAVE_10GPRS(22, r1)
772         mfcr    r4
773         std     r4,_CCR(r1)
774         mfctr   r5
775         std     r5,_CTR(r1)
776         mfspr   r6,XER
777         std     r6,_XER(r1)
778         mfdar   r7
779         std     r7,_DAR(r1)
780         mfdsisr r8
781         std     r8,_DSISR(r1)
782         mfsrr0  r9
783         std     r9,_SRR0(r1)
784         mfsrr1  r10
785         std     r10,_SRR1(r1)
786         mfmsr   r11
787         std     r11,_MSR(r1)
788
789         /* Get the PROM entrypoint */
790         ld      r0,GPR4(r1)
791         mtlr    r0
792
793         /* Switch MSR to 32 bits mode
794          */
795         mfmsr   r11
796         li      r12,1
797         rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
798         andc    r11,r11,r12
799         li      r12,1
800         rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
801         andc    r11,r11,r12
802         mtmsrd  r11
803         isync
804
805         /* Restore arguments & enter PROM here... */
806         ld      r3,GPR3(r1)
807         blrl
808
809         /* Just make sure that r1 top 32 bits didn't get
810          * corrupt by OF
811          */
812         rldicl  r1,r1,0,32
813
814         /* Restore the MSR (back to 64 bits) */
815         ld      r0,_MSR(r1)
816         mtmsrd  r0
817         isync
818
819         /* Restore other registers */
820         REST_GPR(2, r1)
821         REST_GPR(13, r1)
822         REST_8GPRS(14, r1)
823         REST_10GPRS(22, r1)
824         ld      r4,_CCR(r1)
825         mtcr    r4
826         ld      r5,_CTR(r1)
827         mtctr   r5
828         ld      r6,_XER(r1)
829         mtspr   XER,r6
830         ld      r7,_DAR(r1)
831         mtdar   r7
832         ld      r8,_DSISR(r1)
833         mtdsisr r8
834         ld      r9,_SRR0(r1)
835         mtsrr0  r9
836         ld      r10,_SRR1(r1)
837         mtsrr1  r10
838         
839         addi    r1,r1,PROM_FRAME_SIZE
840         ld      r0,16(r1)
841         mtlr    r0
842         blr
843         
844 #endif  /* CONFIG_PPC_MULTIPLATFORM */