2 * arch/ppc64/kernel/entry.S
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).
14 * This file contains the system call entry code, context switch
15 * code, and exception/interrupt return code for PowerPC.
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.
24 #include <asm/processor.h>
27 #include <linux/errno.h>
28 #include <linux/sys.h>
29 #include <linux/config.h>
30 #include <asm/cputable.h>
32 #ifdef CONFIG_PPC_ISERIES
33 #define DO_SOFT_DISABLE
37 #undef SHOW_SYSCALLS_TASK
39 #ifdef SHOW_SYSCALLS_TASK
46 * Handle a system call.
50 ld r11,_CCR(r1) /* Clear SO bit in CR */
54 ld r10,PACACURRENT(r13)
55 std r0,THREAD+LAST_SYSCALL(r10)
57 # ifdef SHOW_SYSCALLS_TASK
58 LOADBASE(r31,show_syscalls_task)
59 ld r31,show_syscalls_task@l(r31)
62 # endif /* SHOW_SYSCALLS_TASK */
74 ld r6, PACACURRENT(r13)
84 #endif /* SHOW_SYSCALLS */
85 ld r11,TASK_PTRACE(r10)
86 andi. r11,r11,PT_TRACESYS
88 cmpli 0,r0,NR_syscalls
90 /* Ken Aaker: Need to vector to 32 Bit or default sys_call_table here,
91 * based on caller's run-mode / personality.
94 #ifdef CONFIG_BINFMT_ELF32
95 ld r11,THREAD+THREAD_FLAGS(r10)
96 andi. r11,r11,PPC_FLAG_32BIT
98 LOADADDR(r11,.sys_call_table32)
99 /* Now mung the first 4 parameters into shape, by making certain that
100 * the high bits (most significant 32 bits in 64 bit reg) are 0
101 * for the first 4 parameter regs(3-6).
110 LOADADDR(r11,.sys_call_table)
113 ldx r10,r11,r0 /* Fetch system call handler [ptr] */
115 addi r9,r1,STACK_FRAME_OVERHEAD
116 blrl /* Call handler */
117 _GLOBAL(ret_from_syscall_1)
118 20: std r3,RESULT(r1) /* Save result */
120 # ifdef SHOW_SYSCALLS_TASK
123 # endif /* SHOW_SYSCALLS_TASK */
129 #endif /* SHOW_SYSCALLS */
134 cmpi 0,r3,ERESTARTNOHAND
137 22: ld r10,_CCR(r1) /* Set SO bit in CR */
140 30: std r3,GPR3(r1) /* Update return value */
145 /* Traced system call support */
146 50: bl .syscall_trace
147 ld r0,GPR0(r1) /* Restore original registers */
155 cmpli 0,r0,NR_syscalls
157 #ifdef CONFIG_BINFMT_ELF32
158 ld r10,PACACURRENT(r13)
159 ld r10,THREAD+THREAD_FLAGS(r10)
160 andi. r10,r10,PPC_FLAG_32BIT
162 LOADADDR(r10,.sys_call_table32)
163 /* Now mung the first 4 parameters into shape, by making certain that
164 * the high bits (most significant 32 bits in 64 bit reg) are 0
165 * for the first 4 parameter regs(3-6).
174 LOADADDR(r10,.sys_call_table)
177 ldx r10,r10,r0 /* Fetch system call handler [ptr] */
179 addi r9,r1,STACK_FRAME_OVERHEAD
180 blrl /* Call handler */
181 _GLOBAL(ret_from_syscall_2)
182 58: std r3,RESULT(r1) /* Save result */
187 cmpi 0,r3,ERESTARTNOHAND
190 57: ld r10,_CCR(r1) /* Set SO bit in CR */
193 60: std r3,GPR3(r1) /* Update return value */
199 7: .string "syscall %d(%x, %x, %x, %x, %x, "
200 77: .string "%x, %x), current=%p\n"
201 79: .string " -> %x\n"
205 _GLOBAL(ppc32_sigreturn)
209 _GLOBAL(ppc32_rt_sigreturn)
210 bl .sys32_rt_sigreturn
213 _GLOBAL(ppc64_sigreturn)
217 _GLOBAL(ppc64_rt_sigreturn)
220 80: ld r10,PACACURRENT(r13)
221 ld r10,TASK_PTRACE(r10)
222 andi. r10,r10,PT_TRACESYS
233 * This routine switches between two different tasks. The process
234 * state of one is saved on its kernel stack. Then the state
235 * of the other is restored from its kernel stack. The memory
236 * management hardware is updated to the second process's state.
237 * Finally, we can return to the second process, via ret_from_except.
238 * On entry, r3 points to the THREAD for the current task, r4
239 * points to the THREAD for the new task.
241 * Note: there are two ways to get to the "going out" portion
242 * of this code; either by coming in via the entry (_switch)
243 * or via "fork" which must set up an environment equivalent
244 * to the "_switch" path. If you change this (or in particular, the
245 * SAVE_REGS macro), you'll have to change the fork code also.
247 * The code which creates the new task context is in 'copy_thread'
248 * in arch/ppc64/kernel/process.c
251 stdu r1,-INT_FRAME_SIZE(r1)
254 /* r3-r13 are caller saved -- Cort */
258 mflr r20 /* Return to switch caller */
260 li r6,MSR_FP /* Disable floating-point */
261 #ifdef CONFIG_ALTIVEC
263 oris r6,r6,MSR_VEC@h /* Disable altivec */
264 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
265 #endif /* CONFIG_ALTIVEC */
276 std r1,KSP(r3) /* Set old stack pointer */
278 addi r3,r3,-THREAD /* old 'current' for return value */
279 addi r7,r4,-THREAD /* Convert THREAD to 'current' */
280 std r7,PACACURRENT(r13) /* Set new 'current' */
282 #ifdef CONFIG_PPC_ISERIES
283 ld r7,THREAD_FLAGS(r4) /* Get run light flag */
285 srdi r7,r7,1 /* Align to run light bit in CTRL reg */
286 insrdi r9,r7,1,63 /* Insert run light into CTRL */
289 ld r1,KSP(r4) /* Load new stack pointer */
292 /* r3-r13 are destroyed -- Cort */
296 ld r7,_NIP(r1) /* Return to _switch caller in new task */
301 _GLOBAL(ret_from_fork)
303 ld r4,PACACURRENT(r13)
304 ld r0,TASK_PTRACE(r4)
305 andi. r0,r0,PT_TRACESYS
306 beq+ .ret_from_except
310 _GLOBAL(ret_from_except)
311 #ifdef CONFIG_PPC_ISERIES
316 /* Check for pending interrupts (iSeries) */
318 beq+ 4f /* skip do_IRQ if no interrupts */
321 stb r3,PACAPROCENABLED(r13) /* ensure we are disabled */
322 addi r3,r1,STACK_FRAME_OVERHEAD
324 b irq_recheck /* loop back and handle more */
327 _GLOBAL(do_bottom_half_ret)
328 ld r3,_MSR(r1) /* Returning to user mode? */
330 beq+ restore /* if so, check need_resched and signals */
331 _GLOBAL(ret_to_user_hook)
333 /* NEED_RESCHED is a volatile long (64-bits) */
334 ld r3,PACACURRENT(r13)
335 ld r3,NEED_RESCHED(r3)
336 cmpi 0,r3,0 /* check need_resched flag */
339 /* SIGPENDING is an int (32-bits) */
341 ld r5,PACACURRENT(r13)
342 lwz r5,SIGPENDING(r5) /* Check for pending unblocked signals */
346 addi r4,r1,STACK_FRAME_OVERHEAD
348 _GLOBAL(do_signal_ret)
361 /* make sure we hard disable here, even if rtl is active, to protect
362 * SRR[01] and SPRG2 -- Cort
364 mfmsr r0 /* Get current interrupt state */
366 ori r4,r4,MSR_EE|MSR_RI
367 andc r0,r0,r4 /* clear MSR_EE and MSR_RI */
368 mtmsrd r0 /* Update machine state */
369 #ifdef CONFIG_PPC_ISERIES
377 ori r0,r0,MSR_EE|MSR_RI
383 stdcx. r0,0,r1 /* to clear the reservation */
385 #ifdef DO_SOFT_DISABLE
387 stb r0,PACAPROCENABLED(r13)
389 /* if returning to user mode, save kernel SP */
393 ld r4,PACACURRENT(r13)
394 #ifdef CONFIG_ALTIVEC
396 ld r0,THREAD+THREAD_VRSAVE(r4)
397 mtspr SPRN_VRSAVE,r0 /* if GPUL, restore VRSAVE reg */
398 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
399 #endif /* CONFIG_ALTIVEC */
400 addi r0,r1,INT_FRAME_SIZE /* size of frame */
401 std r0,THREAD+KSP(r4) /* save kernel stack pointer */
402 std r1,PACAKSAVE(r13) /* save exception stack pointer */
425 * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
426 * called with the MMU off.
428 * In addition, we need to be in 32b mode, at least for now.
430 * Note: r3 is an input parameter to rtas, so don't trash it...
435 stdu r1,-RTAS_FRAME_SIZE(r1) /* Save SP and create stack space. */
437 /* Because RTAS is running in 32b mode, it clobbers the high order half
438 * of all registers that it saves. We therefore save those registers
439 * RTAS might touch to the stack. (r0, r3-r13 are caller saved)
441 SAVE_GPR(2, r1) /* Save the TOC */
442 SAVE_GPR(13, r1) /* Save current */
443 SAVE_8GPRS(14, r1) /* Save the non-volatiles */
444 SAVE_10GPRS(22, r1) /* ditto */
461 /* Unfortunately, the stack pointer and the MSR are also clobbered,
462 * so they are saved in the PACA (SPRG3) which allows us to restore
463 * our original state after RTAS returns.
467 std r6,PACASAVEDMSR(r13)
469 /* Setup our real return addr */
470 SET_REG_TO_LABEL(r4,.rtas_return_loc)
471 SET_REG_TO_CONST(r9,KERNELBASE)
476 ori r0,r0,MSR_EE|MSR_SE|MSR_BE|MSR_RI
480 rldicr r9,r9,MSR_SF_LG,(63-MSR_SF_LG)
481 ori r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP|MSR_RI
483 sync /* disable interrupts so SRR0/1 */
484 mtmsrd r0 /* don't get trashed */
486 SET_REG_TO_LABEL(r4,rtas)
487 ld r5,RTASENTRY(r4) /* get the rtas->entry value */
488 ld r4,RTASBASE(r4) /* get the rtas->base value */
494 _STATIC(rtas_return_loc)
495 /* relocation is off at this point */
496 mfspr r13,SPRG3 /* Get PACA */
497 SET_REG_TO_CONST(r5, KERNELBASE)
498 sub r13,r13,r5 /* RELOC the PACA base pointer */
500 mfmsr r6 /* Clear RI while SRR0/1 are live */
506 ld r1,PACAR1(r13) /* Restore our SP */
507 LOADADDR(r3,.rtas_restore_regs)
508 ld r4,PACASAVEDMSR(r13) /* Restore our MSR */
514 _STATIC(rtas_restore_regs)
515 /* relocation is on at this point */
516 REST_GPR(2, r1) /* Restore the TOC */
517 REST_GPR(13, r1) /* Restore current */
518 REST_8GPRS(14, r1) /* Restore the non-volatiles */
519 REST_10GPRS(22, r1) /* ditto */
521 /* put back paca in r13 */
539 addi r1,r1,RTAS_FRAME_SIZE /* Unstack our frame */
540 ld r0,16(r1) /* get return address */
543 blr /* return to caller */
548 stdu r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */
550 /* Because PROM is running in 32b mode, it clobbers the high order half
551 * of all registers that it saves. We therefore save those registers
552 * PROM might touch to the stack. (r0, r3-r13 are caller saved)
554 SAVE_8GPRS(2, r1) /* Save the TOC & incoming param(s) */
555 SAVE_GPR(13, r1) /* Save current */
556 SAVE_8GPRS(14, r1) /* Save the non-volatiles */
557 SAVE_10GPRS(22, r1) /* ditto */
576 /* Unfortunately, the stack pointer is also clobbered, so it is saved
577 * in the SPRG2 which allows us to restore our original state after
582 /* put a relocation offset into r3 */
586 ld r12,PROMENTRY(r12) /* get the prom->entry value */
589 mfmsr r11 /* grab the current MSR */
591 rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
594 rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
599 REST_8GPRS(2, r1) /* Restore the TOC & param(s) */
600 REST_GPR(13, r1) /* Restore current */
601 REST_8GPRS(14, r1) /* Restore the non-volatiles */
602 REST_10GPRS(22, r1) /* ditto */
603 blrl /* Entering PROM here... */
605 mfspr r1,SPRG2 /* Restore the stack pointer */
606 ld r6,_MSR(r1) /* Restore the MSR */
610 REST_GPR(2, r1) /* Restore the TOC */
611 REST_GPR(13, r1) /* Restore current */
612 REST_8GPRS(14, r1) /* Restore the non-volatiles */
613 REST_10GPRS(22, r1) /* ditto */
629 addi r1,r1,PROM_FRAME_SIZE
630 ld r0,16(r1) /* get return address */
633 blr /* return to caller */