patch-2.1.101 linux/arch/mips/kernel/traps.c
Next file: linux/arch/mips/kernel/unaligned.c
Previous file: linux/arch/mips/kernel/time.c
Back to the patch index
Back to the overall index
- Lines: 191
- Date:
Fri May 8 00:13:24 1998
- Orig file:
v2.1.100/linux/arch/mips/kernel/traps.c
- Orig date:
Wed Dec 10 10:31:10 1997
diff -u --recursive --new-file v2.1.100/linux/arch/mips/kernel/traps.c linux/arch/mips/kernel/traps.c
@@ -8,11 +8,12 @@
* Copyright 1994, 1995, 1996, 1997 by Ralf Baechle
* Modified for R3000 by Paul M. Antoine, 1995, 1996
*
- * $Id: traps.c,v 1.7 1997/12/01 16:33:28 ralf Exp $
+ * $Id: traps.c,v 1.10 1998/05/04 09:17:57 ralf Exp $
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/mm.h>
+#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
@@ -27,10 +28,6 @@
#include <asm/system.h>
#include <asm/uaccess.h>
-#ifdef CONFIG_SGI
-#include <asm/sgialib.h>
-#endif
-
#undef CONF_DEBUG_EXCEPTIONS
static inline void console_verbose(void)
@@ -105,7 +102,7 @@
/*
* Dump the stack
*/
- printk("Process %s (pid: %d, stackpage=%08lx)\nStack: ",
+ printk("Process %s (pid: %ld, stackpage=%08lx)\nStack: ",
current->comm, current->pid, (unsigned long)current);
for(i=0;i<5;i++)
printk("%08x ", *sp++);
@@ -167,18 +164,9 @@
void die_if_kernel(const char * str, struct pt_regs * regs, long err)
{
- /*
- * Just return if in user mode.
- * XXX
- */
-#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
- if (!((regs)->cp0_status & 0x4))
- return;
-#endif
-#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
- if (regs->cp0_status & ST0_KSU == KSU_USER)
+ if (user_mode(regs)) /* Just return if in user mode. */
return;
-#endif
+
console_verbose();
printk("%s: %04lx\n", str, err & 0xffff);
show_regs(regs);
@@ -196,6 +184,7 @@
void do_ibe(struct pt_regs *regs)
{
lock_kernel();
+show_regs(regs); while(1);
ibe_board_handler(regs);
unlock_kernel();
}
@@ -203,6 +192,7 @@
void do_dbe(struct pt_regs *regs)
{
lock_kernel();
+show_regs(regs); while(1);
dbe_board_handler(regs);
unlock_kernel();
}
@@ -240,7 +230,10 @@
}
#endif
-void do_fpe(struct pt_regs *regs, unsigned int fcr31)
+/*
+ * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
+ */
+void do_fpe(struct pt_regs *regs, unsigned long fcr31)
{
#ifdef CONFIG_MIPS_FPE_MODULE
if (fpe_handler != NULL) {
@@ -252,8 +245,23 @@
#ifdef CONF_DEBUG_EXCEPTIONS
show_regs(regs);
#endif
- printk("Caught floating exception at epc == %08lx, fcr31 == %08x\n",
- regs->cp0_epc, fcr31);
+ if (fcr31 & 0x20000) {
+ /* Retry instruction with flush to zero ... */
+ if (!(fcr31 & (1<<24))) {
+ printk("Setting flush to zero for %s.\n",
+ current->comm);
+ fcr31 &= ~0x20000;
+ fcr31 |= (1<<24);
+ __asm__ __volatile__(
+ "ctc1\t%0,$31"
+ : /* No outputs */
+ : "r" (fcr31));
+ goto out;
+ }
+ printk("Unimplemented exception at 0x%08lx in %s.\n",
+ regs->cp0_epc, current->comm);
+ }
+
if (compute_return_epc(regs))
goto out;
force_sig(SIGFPE, current);
@@ -337,7 +345,7 @@
#ifdef CONF_DEBUG_EXCEPTIONS
show_regs(regs);
#endif
- printk("[%s:%d] Illegal instruction at %08lx ra=%08lx\n",
+ printk("[%s:%ld] Illegal instruction at %08lx ra=%08lx\n",
current->comm, current->pid, regs->cp0_epc, regs->regs[31]);
if (compute_return_epc(regs))
goto out;
@@ -350,16 +358,29 @@
{
unsigned int cpid;
- lock_kernel();
cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
- if (cpid == 1)
- {
- regs->cp0_status |= ST0_CU1;
+ if (cpid != 1)
+ goto bad_cid;
+
+ regs->cp0_status |= ST0_CU1;
+ if (last_task_used_math == current)
goto out;
+
+ if (current->used_math) { /* Using the FPU again. */
+ r4xx0_lazy_fpu_switch(last_task_used_math);
+ } else { /* First time FPU user. */
+
+ r4xx0_init_fpu();
+ current->used_math = 1;
}
+ last_task_used_math = current;
+ return;
+
+bad_cid:
+ lock_kernel();
force_sig(SIGILL, current);
-out:
unlock_kernel();
+out:
}
void do_vcei(struct pt_regs *regs)
@@ -460,13 +481,6 @@
}
}
-typedef asmlinkage int (*syscall_t)(void *a0,...);
-asmlinkage int (*do_syscalls)(struct pt_regs *regs, syscall_t fun, int narg);
-extern asmlinkage int r4k_do_syscalls(struct pt_regs *regs,
- syscall_t fun, int narg);
-extern asmlinkage int r2300_do_syscalls(struct pt_regs *regs,
- syscall_t fun, int narg);
-
asmlinkage void (*save_fp_context)(struct sigcontext *sc);
extern asmlinkage void r4k_save_fp_context(struct sigcontext *sc);
extern asmlinkage void r2300_save_fp_context(struct sigcontext *sc);
@@ -489,7 +503,6 @@
unsigned long i;
if(mips_machtype == MACH_MIPS_MAGNUM_4000 ||
- mips_machtype == MACH_DESKSTATION_RPC44 ||
mips_machtype == MACH_SNI_RM200_PCI)
EISA_bus = 1;
@@ -560,7 +573,6 @@
memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80);
memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x80);
- do_syscalls = r4k_do_syscalls;
save_fp_context = r4k_save_fp_context;
restore_fp_context = r4k_restore_fp_context;
resume = r4xx0_resume;
@@ -607,7 +619,6 @@
case CPU_R3000:
case CPU_R3000A:
memcpy((void *)KSEG0, &except_vec0_r2300, 0x80);
- do_syscalls = r2300_do_syscalls;
save_fp_context = r2300_save_fp_context;
restore_fp_context = r2300_restore_fp_context;
resume = r2300_resume;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov