summaryrefslogtreecommitdiff
path: root/arch/ppc/kernel/entry.S
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@tango.paulus.ozlabs.org>2002-02-16 20:14:24 +1100
committerPaul Mackerras <paulus@tango.paulus.ozlabs.org>2002-02-16 20:14:24 +1100
commit03aed178cf27d8b67697883ae698372b662f3841 (patch)
treeac279d66664a024b29c7b117cce6c573f50d0b69 /arch/ppc/kernel/entry.S
parentbff60e8b905ef243391391558e62a4826e86e207 (diff)
PPC fixes for SMP; also fix the stack overflow detection, remove
various bits of cruft, and remove the third argument to switch_to.
Diffstat (limited to 'arch/ppc/kernel/entry.S')
-rw-r--r--arch/ppc/kernel/entry.S66
1 files changed, 66 insertions, 0 deletions
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 35e5c9c1363f..2bd06ecca9f6 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -41,6 +41,72 @@
#undef SHOW_SYSCALLS
#undef SHOW_SYSCALLS_TASK
+#ifndef CONFIG_PPC_ISERIES /* iSeries version is in iSeries_head.S */
+/*
+ * This code finishes saving the registers to the exception frame
+ * and jumps to the appropriate handler for the exception, turning
+ * on address translation.
+ */
+ .globl transfer_to_handler
+transfer_to_handler:
+ stw r22,_NIP(r21)
+ stw r23,_MSR(r21)
+ SAVE_4GPRS(8, r21)
+ SAVE_8GPRS(12, r21)
+ SAVE_8GPRS(24, r21)
+ andi. r23,r23,MSR_PR
+ mfspr r23,SPRG3
+ addi r2,r23,-THREAD /* set r2 to current */
+ tovirt(r2,r2)
+ beq 2f /* if from user, fix up THREAD.regs */
+ addi r24,r1,STACK_FRAME_OVERHEAD
+ stw r24,PT_REGS(r23)
+#ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
+ mfspr r22,SPRN_VRSAVE /* if G4, save vrsave register value */
+ stw r22,THREAD_VRSAVE(r23)
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif /* CONFIG_ALTIVEC */
+ b 3f
+2: /* if from kernel, check for stack overflow */
+ lwz r22,THREAD_INFO-THREAD(r23)
+ cmplw r1,r22 /* if r1 <= current->thread_info */
+ ble- stack_ovf /* then the kernel stack overflowed */
+3:
+ mflr r23
+ andi. r24,r23,0x3f00 /* get vector offset */
+ stw r24,TRAP(r21)
+ li r22,0
+ stw r22,RESULT(r21)
+ mtspr SPRG2,r22 /* r1 is now kernel sp */
+ lwz r24,0(r23) /* virtual address of handler */
+ lwz r23,4(r23) /* where to go when done */
+ FIX_SRR1(r20,r22)
+ mtspr SRR0,r24
+ mtspr SRR1,r20
+ mtlr r23
+ SYNC
+ RFI /* jump to handler, enable MMU */
+
+/*
+ * On kernel stack overflow, load up an initial stack pointer
+ * and call StackOverflow(regs), which should not return.
+ */
+stack_ovf:
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lis r1,init_thread_union@ha
+ addi r1,r1,init_thread_union@l
+ addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+ lis r24,StackOverflow@ha
+ addi r24,r24,StackOverflow@l
+ li r20,MSR_KERNEL
+ FIX_SRR1(r20,r22)
+ mtspr SRR0,r24
+ mtspr SRR1,r20
+ SYNC
+ RFI
+#endif /* CONFIG_PPC_ISERIES */
+
#ifdef SHOW_SYSCALLS_TASK
.data
show_syscalls_task: