Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions ports/risc-v64/gnu/src/tx_thread_context_restore.S
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ _tx_thread_context_restore:
/* Just recover the saved registers and return to the point of
interrupt. */

/* Recover the FP state only when the saved mstatus.FS was not Off. The
save side skips the FP stores for a thread that has not touched the
unit, so those slots hold nothing worth loading back. */
#if (__riscv_flen == 32) || (__riscv_flen == 64)
ld t1, 29*8(sp) // Pickup saved mstatus
srli t1, t1, 13
andi t1, t1, 0x3
beqz t1, _tx_thread_skip_fp_restore // Skip if FS was Off
#endif

/* Recover floating point registers. */
#if (__riscv_flen == 32)
flw f0, 31*8(sp) // Recover ft0
Expand Down Expand Up @@ -152,6 +162,7 @@ _tx_thread_context_restore:
ld t0, 63*8(sp) // Recover fcsr
csrw fcsr, t0
#endif
_tx_thread_skip_fp_restore:

#if defined(__riscv_vector)
/* Recover vector registers v0-v31 */
Expand Down Expand Up @@ -297,6 +308,16 @@ _tx_thread_no_preempt_restore:

ld sp, 8(t1) // Switch back to thread's stack

/* Recover the FP state only when the saved mstatus.FS was not Off. The
save side skips the FP stores for a thread that has not touched the
unit, so those slots hold nothing worth loading back. */
#if (__riscv_flen == 32) || (__riscv_flen == 64)
ld t3, 29*8(sp) // Pickup saved mstatus
srli t3, t3, 13
andi t3, t3, 0x3
beqz t3, _tx_thread_no_preempt_skip_fp_restore // Skip if FS was Off
#endif

/* Recover floating point registers. */
#if (__riscv_flen == 32)
flw f0, 31*8(sp) // Recover ft0
Expand Down Expand Up @@ -359,6 +380,7 @@ _tx_thread_no_preempt_restore:
ld t0, 63*8(sp) // Recover fcsr
csrw fcsr, t0 // Restore fcsr
#endif
_tx_thread_no_preempt_skip_fp_restore:

#if defined(__riscv_vector)
/* Recover vector registers v0-v31 */
Expand Down
21 changes: 21 additions & 0 deletions ports/risc-v64/gnu/src/tx_thread_context_save.S
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* Wei-Chen Lai, National Cheng Kung University */
/* */
/* DESCRIPTION */
/* */
Expand Down Expand Up @@ -104,6 +105,15 @@ _tx_thread_context_save:
#endif
sd t0, 30*8(sp) // Save it on the stack

/* Save mstatus and skip FP state if FS is Off. */
csrr t0, mstatus
sd t0, 29*8(sp) // Save mstatus
#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double)
srli t1, t0, 13
andi t1, t1, 0x3
beqz t1, _tx_thread_skip_nested_fpu_save // Skip if FS was Off
#endif

/* Save floating point scratch registers if floating point is enabled. */
#if (__riscv_flen == 32)
fsw f0, 31*8(sp) // Store ft0
Expand Down Expand Up @@ -166,6 +176,7 @@ _tx_thread_context_save:
csrr t0, fcsr
sd t0, 63*8(sp) // Store fcsr
#endif
_tx_thread_skip_nested_fpu_save:

#if defined(__riscv_vector)
/* Store vector registers and CSRs */
Expand Down Expand Up @@ -246,6 +257,15 @@ _tx_thread_not_nested_save:
#endif
sd t1, 30*8(sp) // Save it on the stack

/* Save mstatus and skip FP state if FS is Off. */
csrr t1, mstatus
sd t1, 29*8(sp) // Save mstatus
#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double)
srli t2, t1, 13
andi t2, t2, 0x3
beqz t2, _tx_thread_skip_fpu_save // Skip if FS was Off
#endif

/* Save floating point scratch registers if floating point is enabled. */
#if (__riscv_flen == 32)
fsw f0, 31*8(sp) // Store ft0
Expand Down Expand Up @@ -308,6 +328,7 @@ _tx_thread_not_nested_save:
csrr t0, fcsr
sd t0, 63*8(sp) // Store fcsr
#endif
_tx_thread_skip_fpu_save:

#if defined(__riscv_vector)
/* Store vector registers and CSRs */
Expand Down
12 changes: 11 additions & 1 deletion ports/risc-v64/gnu/src/tx_thread_schedule.S
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,16 @@ _tx_thread_schedule_loop:
ld t2, 0(sp) // Pickup stack type
beqz t2, _tx_thread_synch_return // If 0, solicited thread return

/* Determine if floating point registers need to be recovered. */
/* Determine if floating point registers need to be recovered. This is an
interrupt frame, so _tx_thread_context_save built it and may have
skipped the FP stores when mstatus.FS was Off. Read back the same slot
it wrote rather than reloading whatever those slots happen to hold. */
#if (__riscv_flen == 32) || (__riscv_flen == 64)
ld t1, 29*8(sp) // Pickup saved mstatus
srli t1, t1, 13
andi t1, t1, 0x3
beqz t1, _tx_thread_schedule_skip_fp_restore // Skip if FS was Off
#endif

#if (__riscv_flen == 32)
flw f0, 31*8(sp) // Recover ft0
Expand Down Expand Up @@ -216,6 +225,7 @@ _tx_thread_schedule_loop:
ld t0, 63*8(sp) // Recover fcsr
csrw fcsr, t0 // Restore fcsr
#endif
_tx_thread_schedule_skip_fp_restore:

#if defined(__riscv_vector)
/* Recover vector registers v0-v31 */
Expand Down
5 changes: 4 additions & 1 deletion ports/risc-v64/gnu/src/tx_thread_stack_build.S
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* Wei-Chen Lai, National Cheng Kung University */
/* */
/* DESCRIPTION */
/* */
Expand Down Expand Up @@ -94,7 +95,7 @@ _tx_thread_stack_build:
x11 26 Initial a1
x10 27 Initial a0
x1 28 Initial ra
-- 29 reserved
mstatus 29 Initial mstatus
mepc 30 Initial mepc
If floating point support:
f0 31 Inital ft0
Expand Down Expand Up @@ -193,6 +194,8 @@ If vector extension support:
sd zero, 26*8(t0) // Initial a1
sd zero, 27*8(t0) // Initial a0
sd zero, 28*8(t0) // Initial ra
li t1, 0x2000 // mstatus.FS = Initial
sd t1, 29*8(t0) // Initial mstatus
sd a1, 30*8(t0) // Initial mepc/sepc (thread entry point)
#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double)
sd zero, 31*8(t0) // Initial ft0
Expand Down
8 changes: 8 additions & 0 deletions test/tx/cmake/riscv/regression/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ set(regression_test_cases
# interrupt_save on RISC-V.
)

# Architecture specific tests living next to this file. The RV32 stack
# builder still leaves the mstatus slot of the frame unwritten, so the new
# thread FPU state test only applies to RV64 for now.
if(THREADX_ARCH STREQUAL "risc-v64")
list(APPEND regression_test_cases
${CMAKE_CURRENT_LIST_DIR}/threadx_riscv_new_thread_fpu_state_test.c)
endif()

# Tests that provide their own main() and must NOT link with testcontrol.
set(standalone_test_cases
${SOURCE_DIR}/threadx_initialize_kernel_setup_test.c
Expand Down
Loading