diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-05-07 02:55:41 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-05-07 02:55:41 +0000 |
commit | dcec8a13bf565e47942a1751a9cec21bec5648fe (patch) | |
tree | 548b69625b18cc2e88c3e68d0923be546c9ebb03 /arch/sparc/kernel/traps.c | |
parent | 2e0f55e79c49509b7ff70ff1a10e1e9e90a3dfd4 (diff) |
o Merge with Linux 2.1.99.
o Fix ancient bug in the ELF loader making ldd crash.
o Fix ancient bug in the keyboard code for SGI, SNI and Jazz.
Diffstat (limited to 'arch/sparc/kernel/traps.c')
-rw-r--r-- | arch/sparc/kernel/traps.c | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c index 19a3afbd0..015d05357 100644 --- a/arch/sparc/kernel/traps.c +++ b/arch/sparc/kernel/traps.c @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.53 1997/01/25 02:43:05 miguel Exp $ +/* $Id: traps.c,v 1.56 1998/04/06 16:08:32 jj Exp $ * arch/sparc/kernel/traps.c * * Copyright 1995 David S. Miller (davem@caip.rutgers.edu) @@ -62,6 +62,14 @@ void sun4m_nmi(struct pt_regs *regs) prom_halt(); } +void sun4d_nmi(struct pt_regs *regs) +{ + printk("Aieee: sun4d NMI received!\n"); + printk("you lose buddy boy...\n"); + show_regs(regs); + prom_halt(); +} + void instruction_dump (unsigned long *pc) { int i; @@ -229,10 +237,13 @@ static unsigned long fake_fsr; static unsigned long fake_queue[32] __attribute__ ((aligned (8))); static unsigned long fake_depth; +extern int do_mathemu(struct pt_regs *, struct task_struct *); + void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { static calls = 0; + int ret; #ifndef __SMP__ struct task_struct *fpt = last_task_used_math; #else @@ -255,6 +266,40 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, } fpsave(&fpt->tss.float_regs[0], &fpt->tss.fsr, &fpt->tss.fpqueue[0], &fpt->tss.fpqdepth); +#ifdef DEBUG_FPU + printk("Hmm, FP exception, fsr was %016lx\n", fpt->tss.fsr); +#endif + + switch ((fpt->tss.fsr & 0x1c000)) { + /* switch on the contents of the ftt [floating point trap type] field */ +#ifdef DEBUG_FPU + case (1 << 14): + printk("IEEE_754_exception\n"); + break; +#endif + case (2 << 14): /* unfinished_FPop (underflow & co) */ + case (3 << 14): /* unimplemented_FPop (quad stuff, maybe sqrt) */ + ret = do_mathemu(regs, fpt); + break; +#ifdef DEBUG_FPU + case (4 << 14): + printk("sequence_error (OS bug...)\n"); + break; + case (5 << 14): + printk("hardware_error (uhoh!)\n"); + break; + case (6 << 14): + printk("invalid_fp_register (user error)\n"); + break; +#endif /* DEBUG_FPU */ + } + /* If we successfully emulated the FPop, we pretend the trap never happened :-> */ + if (ret) { + fpload(¤t->tss.float_regs[0], ¤t->tss.fsr); + return; + } + /* nope, better SIGFPE the offending process... */ + fpt->tss.sig_address = pc; fpt->tss.sig_desc = SUBSIG_FPERROR; /* as good as any */ #ifdef __SMP__ @@ -331,19 +376,6 @@ void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long np unlock_kernel(); } -void handle_bad_flush(struct pt_regs *regs, unsigned long pc, unsigned long npc, - unsigned long psr) -{ - lock_kernel(); -#ifdef TRAP_DEBUG - printk("Unimplemented FLUSH Exception at PC %08lx NPC %08lx PSR %08lx\n", - pc, npc, psr); -#endif - printk("INSTRUCTION=%08lx\n", *((unsigned long *) regs->pc)); - send_sig(SIGILL, current, 1); - unlock_kernel(); -} - void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long npc, unsigned long psr) { |