diff options
author | Andrew Waterman <waterman@s141.Millennium.Berkeley.EDU> | 2011-02-04 16:09:01 -0800 |
---|---|---|
committer | Andrew Waterman <waterman@s141.Millennium.Berkeley.EDU> | 2011-02-04 16:09:01 -0800 |
commit | af2d471a4e6c2e4551238a2cc209f9c0d997c82f (patch) | |
tree | 324c10ad4431e08b28b3166169a1ccd3833b0d50 /pk | |
parent | 83cdb2063f62d4d535aebbaff484e068808e097b (diff) | |
download | riscv-pk-af2d471a4e6c2e4551238a2cc209f9c0d997c82f.zip riscv-pk-af2d471a4e6c2e4551238a2cc209f9c0d997c82f.tar.gz riscv-pk-af2d471a4e6c2e4551238a2cc209f9c0d997c82f.tar.bz2 |
[pk] fixed FP emulation bug
kernel would erroneously trap on FP disabled
Diffstat (limited to 'pk')
-rw-r--r-- | pk/fp.c | 10 | ||||
-rw-r--r-- | pk/handlers.c | 5 | ||||
-rw-r--r-- | pk/pk.h | 2 |
3 files changed, 10 insertions, 7 deletions
@@ -27,7 +27,11 @@ validate_address(trapframe_t* tf, long addr, int size, int store) int emulate_fp(trapframe_t* tf) { if(have_fp) + { + if(!(mfpcr(PCR_SR) & SR_EF)) + init_fp(); fp_state.fsr = get_fp_state(fp_state.fpr); + } if(noisy) printk("FPU emulation at pc %lx, insn %x\n",tf->epc,(uint32_t)tf->insn); @@ -257,10 +261,12 @@ get_fp_reg(unsigned int which, unsigned int dp) #endif -void init_fp_regs() +void init_fp(trapframe_t* tf) { long sr = mfpcr(PCR_SR); mtpcr(sr | SR_EF, PCR_SR); + put_fp_state(fp_state.fpr,fp_state.fsr); - mtpcr(sr, PCR_SR); + + tf->sr |= SR_EF; } diff --git a/pk/handlers.c b/pk/handlers.c index 2947903..cb580e6 100644 --- a/pk/handlers.c +++ b/pk/handlers.c @@ -13,10 +13,7 @@ void handle_breakpoint(trapframe_t* tf) void handle_fp_disabled(trapframe_t* tf) { if(have_fp) - { - init_fp_regs(); - tf->sr |= SR_EF; - } + init_fp(); else { #ifdef PK_ENABLE_FP_EMULATION @@ -26,7 +26,7 @@ extern "C" { extern int have_fp; int emulate_fp(trapframe_t*); -void init_fp_regs(); +void init_fp(); void printk(const char* s, ...); void init_tf(trapframe_t*, long pc, long sp); |