diff options
author | Zihao Yu <19884013+sashimi-yzh@users.noreply.github.com> | 2018-05-22 02:16:01 +0800 |
---|---|---|
committer | Andrew Waterman <aswaterman@gmail.com> | 2018-05-21 11:16:01 -0700 |
commit | 9ffedde3d747a9b6f559041cc69478df6d647135 (patch) | |
tree | 9b83afd83aa57c95fa7221d548c4f684025fd701 | |
parent | 94bcafff6abe9d17e3f4d99680f0e6488c4acc15 (diff) | |
download | riscv-pk-9ffedde3d747a9b6f559041cc69478df6d647135.zip riscv-pk-9ffedde3d747a9b6f559041cc69478df6d647135.tar.gz riscv-pk-9ffedde3d747a9b6f559041cc69478df6d647135.tar.bz2 |
machine,minit: initialize emulated FCSR in enter_supervisor_mode() (#106)
* If BBL emulates the FPU, the trap handler will load emulated FCSR from
x0's save slot into tp. The emulated FCSR should be initialized, else
the field of rounding mode will contain garbage codes. This will
lead to raising SIGABRT for a user mode program which tries to print a
floating point variable. In glibc, __printf_fp_l() (defined in
riscv-glibc/stdio-common/printf_fp.c) will call round_away() (defined
in riscv-glibc/include/rounding-mode.h). With a garbage rounding mode
in emulated FCSR, round_away() may call abort().
-rw-r--r-- | machine/minit.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/machine/minit.c b/machine/minit.c index 0a87633..32c6fd7 100644 --- a/machine/minit.c +++ b/machine/minit.c @@ -197,6 +197,10 @@ void enter_supervisor_mode(void (*fn)(uintptr_t), uintptr_t arg0, uintptr_t arg1 mstatus = INSERT_FIELD(mstatus, MSTATUS_MPIE, 0); write_csr(mstatus, mstatus); write_csr(mscratch, MACHINE_STACK_TOP() - MENTRY_FRAME_SIZE); +#ifndef __riscv_flen + uintptr_t *p_fcsr = MACHINE_STACK_TOP() - MENTRY_FRAME_SIZE; // the x0's save slot + *p_fcsr = 0; +#endif write_csr(mepc, fn); register uintptr_t a0 asm ("a0") = arg0; |