Index: sys/powerpc/include/fpu.h =================================================================== --- sys/powerpc/include/fpu.h +++ sys/powerpc/include/fpu.h @@ -75,6 +75,7 @@ void enable_fpu(struct thread *); void save_fpu(struct thread *); void save_fpu_nodrop(struct thread *); +u_int get_fpu_exception(struct thread *); #endif /* _KERNEL */ Index: sys/powerpc/include/psl.h =================================================================== --- sys/powerpc/include/psl.h +++ sys/powerpc/include/psl.h @@ -88,7 +88,7 @@ #define PSL_FE_NONREC PSL_FE1 /* imprecise non-recoverable */ #define PSL_FE_REC PSL_FE0 /* imprecise recoverable */ #define PSL_FE_PREC (PSL_FE0 | PSL_FE1) /* precise */ -#define PSL_FE_DFLT PSL_FE_DIS /* default == none */ +#define PSL_FE_DFLT PSL_FE_NONREC /*PSL_FE_PREC*/ /* default == precise */ #ifndef LOCORE extern register_t psl_kernset; /* Default MSR values for kernel */ Index: sys/powerpc/powerpc/fpu.c =================================================================== --- sys/powerpc/powerpc/fpu.c +++ sys/powerpc/powerpc/fpu.c @@ -208,3 +208,51 @@ if (td == PCPU_GET(fputhread)) save_fpu_int(td); } + + +/* + * * Returns the current fp exception + * */ +u_int +get_fpu_exception(struct thread *td) +{ + int msr; + u_int ucode; + uint64_t reg; + + critical_enter(); + + msr = mfmsr(); + mtmsr(msr | PSL_FP); + __asm __volatile ("mffs 0; stfd 0,0(%0)" + :: "b"(®)); + + isync(); + mtmsr(msr); + + critical_exit(); + + if (reg & FPSCR_ZX){ + ucode = FPE_FLTDIV; + printf("%s:%d FPE_FLTDIV\n", __func__, __LINE__); + } + else if (reg & FPSCR_OX) { + ucode = FPE_FLTOVF; + printf("%s:%d FPE_FLTOVF\n", __func__, __LINE__); + } + else if (reg & FPSCR_UX) { + ucode = FPE_FLTUND; + printf("%s:%d FPE_FLTUND\n", __func__, __LINE__); + } + else if (reg & FPSCR_XX) { + ucode = FPE_FLTRES; + printf("%s:%d FPE_FLTRES\n", __func__, __LINE__); + } + else { + ucode = FPE_FLTINV; + printf("%s:%d FPE_FLTINV\n", __func__, __LINE__); + } + + return ucode; +} + Index: sys/powerpc/powerpc/trap.c =================================================================== --- sys/powerpc/powerpc/trap.c +++ sys/powerpc/powerpc/trap.c @@ -153,6 +153,11 @@ { EXC_LAST, NULL } }; +static int uprintf_signal; +SYSCTL_INT(_machdep, OID_AUTO, uprintf_signal, CTLFLAG_RWTUN, + &uprintf_signal, 0, + "Print debugging information on trap signal to ctty"); + #define ESR_BITMASK \ "\20" \ "\040b0\037b1\036b2\035b3\034PIL\033PRR\032PTR\031FP" \ @@ -401,16 +406,23 @@ #endif sig = SIGTRAP; ucode = TRAP_BRKPT; - } else { - sig = ppc_instr_emulate(frame, td); - if (sig == SIGILL) { - if (frame->srr1 & EXC_PGM_PRIV) - ucode = ILL_PRVOPC; - else if (frame->srr1 & EXC_PGM_ILLEGAL) - ucode = ILL_ILLOPC; - } else if (sig == SIGFPE) - ucode = FPE_FLTINV; /* Punt for now, invalid operation. */ + break; } + + if ((frame->srr1 & EXC_PGM_FPENABLED) && + (td->td_pcb->pcb_flags & PCB_FPU)) + sig = SIGFPE; + else + sig = ppc_instr_emulate(frame, td); + + if (sig == SIGILL) { + if (frame->srr1 & EXC_PGM_PRIV) + ucode = ILL_PRVOPC; + else if (frame->srr1 & EXC_PGM_ILLEGAL) + ucode = ILL_ILLOPC; + } else if (sig == SIGFPE) + ucode = get_fpu_exception(td); + break; case EXC_MCHK: @@ -490,6 +502,15 @@ ksi.ksi_code = (int) ucode; /* XXX, not POSIX */ ksi.ksi_addr = (void *)addr; ksi.ksi_trapno = type; + if (uprintf_signal) { + uprintf("pid %d comm %s: signal %d code %d type %d " + "addr 0x%lx\n", + p->p_pid, p->p_comm, sig, ucode, type, addr); + + + } + + trapsignal(td, &ksi); } @@ -501,6 +522,7 @@ { #ifdef KDB bool handled; + #endif printtrap(frame->exc, frame, 1, (frame->srr1 & PSL_PR));