aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZihao Yu <19884013+sashimi-yzh@users.noreply.github.com>2018-05-22 02:16:01 +0800
committerAndrew Waterman <aswaterman@gmail.com>2018-05-21 11:16:01 -0700
commit9ffedde3d747a9b6f559041cc69478df6d647135 (patch)
tree9b83afd83aa57c95fa7221d548c4f684025fd701
parent94bcafff6abe9d17e3f4d99680f0e6488c4acc15 (diff)
downloadriscv-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.c4
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;