Update of /cvsroot/linux-mips/linux/arch/mips64/kernel
In directory usw-pr-cvs1:/tmp/cvs-serv16961
Modified Files:
traps.c unaligned.c
Log Message:
FPU emulator for the 64-bit kernel.
Index: traps.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips64/kernel/traps.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- traps.c 21 Apr 2002 20:01:14 -0000 1.15
+++ traps.c 24 Apr 2002 17:34:12 -0000 1.16
@@ -49,6 +49,9 @@
extern asmlinkage void handle_mcheck(void);
extern asmlinkage void handle_reserved(void);
+extern int fpu_emulator_cop1Handler(struct pt_regs *);
+void fpu_emulator_init_fpu(void);
+
char watch_available = 0;
char dedicated_iv_available = 0;
@@ -471,11 +474,15 @@
void do_cpu(struct pt_regs *regs)
{
u32 cpid;
+ int sig;
cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
if (cpid != 1)
goto bad_cid;
+ if (!(mips_cpu.options & MIPS_CPU_FPU))
+ goto fp_emul;
+
regs->cp0_status |= ST0_CU1;
#ifdef CONFIG_SMP
@@ -499,6 +506,16 @@
}
last_task_used_math = current;
#endif
+ return;
+
+fp_emul:
+ if (!current->used_math) {
+ fpu_emulator_init_fpu();
+ current->used_math = 1;
+ }
+ sig = fpu_emulator_cop1Handler(regs);
+ if (sig)
+ force_sig(sig, current);
return;
bad_cid:
Index: unaligned.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips64/kernel/unaligned.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- unaligned.c 26 Feb 2002 17:34:15 -0000 1.5
+++ unaligned.c 24 Apr 2002 17:34:12 -0000 1.6
@@ -381,10 +381,24 @@
asmlinkage void do_ade(struct pt_regs *regs)
{
unsigned long pc;
+ extern int do_dsemulret(struct pt_regs *);
+
#if 0
printk("ade: Cpu%d[%s:%d:%0lx:%0lx]\n", smp_processor_id(),
current->comm, current->pid, regs->cp0_badvaddr, regs->cp0_epc);
#endif
+
+ /*
+ * Address errors may be deliberately induced
+ * by the FPU emulator to take retake control
+ * of the CPU after executing the instruction
+ * in the delay slot of an emulated branch.
+ */
+ /* Terminate if exception was recognized as a delay slot return */
+ if (do_dsemulret(regs))
+ return;
+
+ /* Otherwise handle as normal */
/*
* Did we catch a fault trying to load an instruction?
|