Changeset View
Changeset View
Standalone View
Standalone View
head/sys/powerpc/powerpc/fpu.c
Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
#include <machine/fpu.h> | #include <machine/fpu.h> | ||||
#include <machine/pcb.h> | #include <machine/pcb.h> | ||||
#include <machine/psl.h> | #include <machine/psl.h> | ||||
static void | static void | ||||
save_fpu_int(struct thread *td) | save_fpu_int(struct thread *td) | ||||
{ | { | ||||
int msr; | register_t msr; | ||||
struct pcb *pcb; | struct pcb *pcb; | ||||
pcb = td->td_pcb; | pcb = td->td_pcb; | ||||
/* | /* | ||||
* Temporarily re-enable floating-point during the save | * Temporarily re-enable floating-point during the save | ||||
*/ | */ | ||||
msr = mfmsr(); | msr = mfmsr(); | ||||
Show All 37 Lines | save_fpu_int(struct thread *td) | ||||
*/ | */ | ||||
isync(); | isync(); | ||||
mtmsr(msr); | mtmsr(msr); | ||||
} | } | ||||
void | void | ||||
enable_fpu(struct thread *td) | enable_fpu(struct thread *td) | ||||
{ | { | ||||
int msr; | register_t msr; | ||||
struct pcb *pcb; | struct pcb *pcb; | ||||
struct trapframe *tf; | struct trapframe *tf; | ||||
pcb = td->td_pcb; | pcb = td->td_pcb; | ||||
tf = trapframe(td); | tf = trapframe(td); | ||||
/* | /* | ||||
* Save the thread's FPU CPU number, and set the CPU's current | * Save the thread's FPU CPU number, and set the CPU's current | ||||
▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
void | void | ||||
save_fpu_nodrop(struct thread *td) | save_fpu_nodrop(struct thread *td) | ||||
{ | { | ||||
if (td == PCPU_GET(fputhread)) | if (td == PCPU_GET(fputhread)) | ||||
save_fpu_int(td); | save_fpu_int(td); | ||||
} | } | ||||
/* | |||||
* Clear Floating-Point Status and Control Register | |||||
*/ | |||||
void | |||||
cleanup_fpscr() | |||||
{ | |||||
register_t msr; | |||||
msr = mfmsr(); | |||||
mtmsr(msr | PSL_FP | PSL_VSX); | |||||
mtfsf(0); | |||||
isync(); | |||||
mtmsr(msr); | |||||
} | |||||
/* | |||||
* * Returns the current fp exception | |||||
* */ | |||||
u_int | |||||
get_fpu_exception(struct thread *td) | |||||
{ | |||||
register_t msr; | |||||
u_int ucode; | |||||
register_t reg; | |||||
critical_enter(); | |||||
msr = mfmsr(); | |||||
mtmsr(msr | PSL_FP); | |||||
reg = mffs(); | |||||
isync(); | |||||
mtmsr(msr); | |||||
critical_exit(); | |||||
if (reg & FPSCR_ZX) | |||||
ucode = FPE_FLTDIV; | |||||
else if (reg & FPSCR_OX) | |||||
ucode = FPE_FLTOVF; | |||||
else if (reg & FPSCR_UX) | |||||
ucode = FPE_FLTUND; | |||||
else if (reg & FPSCR_XX) | |||||
ucode = FPE_FLTRES; | |||||
else | |||||
ucode = FPE_FLTINV; | |||||
return ucode; | |||||
} | |||||