void do_fpe_trap(struct pt_regs *regs, unsignedlong pc, unsignedlong npc, unsignedlong psr)
{ staticint calls; unsignedlong fsr; int ret = 0; int code; #ifndef CONFIG_SMP struct task_struct *fpt = last_task_used_math; #else struct task_struct *fpt = current; #endif
put_psr(get_psr() | PSR_EF); /* If nobody owns the fpu right now, just clear the * error into our fake static buffer and hope it don't * happen again. Thank you crashme...
*/ #ifndef CONFIG_SMP if(!fpt) { #else if (!test_tsk_thread_flag(fpt, TIF_USEDFPU)) { #endif
fpsave(&fake_regs[0], &fake_fsr, &fake_queue[0], &fake_depth);
regs->psr &= ~PSR_EF; return;
}
fpsave(&fpt->thread.float_regs[0], &fpt->thread.fsr,
&fpt->thread.fpqueue[0], &fpt->thread.fpqdepth); #ifdef DEBUG_FPU
printk("Hmm, FP exception, fsr was %016lx\n", fpt->thread.fsr); #endif
switch ((fpt->thread.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->thread.float_regs[0], ¤t->thread.fsr); return;
} /* nope, better SIGFPE the offending process... */
#ifdef CONFIG_SMP
clear_tsk_thread_flag(fpt, TIF_USEDFPU); #endif if(psr & PSR_PS) { /* The first fsr store/load we tried trapped, * the second one will not (we hope).
*/
printk("WARNING: FPU exception from kernel mode. at pc=%08lx\n",
regs->pc);
regs->pc = regs->npc;
regs->npc += 4;
calls++; if(calls > 2)
die_if_kernel("Too many Penguin-FPU traps from kernel mode",
regs); return;
}
void handle_watchpoint(struct pt_regs *regs, unsignedlong pc, unsignedlong npc, unsignedlong psr)
{ #ifdef TRAP_DEBUG
printk("Watchpoint detected at PC %08lx NPC %08lx PSR %08lx\n",
pc, npc, psr); #endif if(psr & PSR_PS)
panic("Tell me what a watchpoint trap is, and I'll then deal " "with such a beast...");
}
#ifdef CONFIG_DEBUG_BUGVERBOSE void do_BUG(constchar *file, int line)
{ // bust_spinlocks(1); XXX Not in our original BUG()
printk("kernel BUG at %s:%d!\n", file, line);
}
EXPORT_SYMBOL(do_BUG); #endif
/* Since we have our mappings set up, on multiprocessors we can spin them * up here so that timer interrupts work during initialization.
*/
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.