diff options
| author | Paul Mackerras <paulus@tango.paulus.ozlabs.org> | 2002-02-16 20:14:24 +1100 |
|---|---|---|
| committer | Paul Mackerras <paulus@tango.paulus.ozlabs.org> | 2002-02-16 20:14:24 +1100 |
| commit | 03aed178cf27d8b67697883ae698372b662f3841 (patch) | |
| tree | ac279d66664a024b29c7b117cce6c573f50d0b69 /arch/ppc/kernel/entry.S | |
| parent | bff60e8b905ef243391391558e62a4826e86e207 (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.S | 66 |
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: |
