summaryrefslogtreecommitdiff
path: root/ports/risc-v64/gnu/src/tx_thread_context_save.S
diff options
context:
space:
mode:
Diffstat (limited to 'ports/risc-v64/gnu/src/tx_thread_context_save.S')
-rw-r--r--ports/risc-v64/gnu/src/tx_thread_context_save.S90
1 files changed, 73 insertions, 17 deletions
diff --git a/ports/risc-v64/gnu/src/tx_thread_context_save.S b/ports/risc-v64/gnu/src/tx_thread_context_save.S
index 7935bfee..1924bd6e 100644
--- a/ports/risc-v64/gnu/src/tx_thread_context_save.S
+++ b/ports/risc-v64/gnu/src/tx_thread_context_save.S
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -21,6 +22,8 @@
/**************************************************************************/
.section .text
+#include "tx_port.h"
+ .equ TX_TRAP_FRAME_SIZE, TX_RISCV_TRAP_FRAME_SIZE
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
@@ -30,6 +33,7 @@
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
+/* Wei-Chen Lai, National Cheng Kung University */
/* */
/* DESCRIPTION */
/* */
@@ -67,14 +71,14 @@ _tx_thread_context_save:
sd t1, 18*8(sp)
la t0, _tx_thread_system_state // Pickup address of system state
- ld t1, 0(t0) // Pickup system state
+ lw t1, 0(t0) // Pickup system state
/* Check for a nested interrupt condition. */
/* if (_tx_thread_system_state++)
{ */
beqz t1, _tx_thread_not_nested_save // If 0, first interrupt condition
addi t1, t1, 1 // Increment the interrupt counter
- sd t1, 0(t0) // Store the interrupt counter
+ sw t1, 0(t0) // Store the interrupt counter
/* Nested interrupt condition.
Save the rest of the scratch registers on the stack and return to the
@@ -101,8 +105,17 @@ _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. */
-#ifdef __riscv_float_abi_single
+#if (__riscv_flen == 32)
fsw f0, 31*8(sp) // Store ft0
fsw f1, 32*8(sp) // Store ft1
fsw f2, 33*8(sp) // Store ft2
@@ -125,7 +138,7 @@ _tx_thread_context_save:
fsw f31,62*8(sp) // Store ft11
csrr t0, fcsr
sd t0, 63*8(sp) // Store fcsr
-#elif defined(__riscv_float_abi_double)
+#elif (__riscv_flen == 64)
fsd f0, 31*8(sp) // Store ft0
fsd f1, 32*8(sp) // Store ft1
fsd f2, 33*8(sp) // Store ft2
@@ -134,6 +147,20 @@ _tx_thread_context_save:
fsd f5, 36*8(sp) // Store ft5
fsd f6, 37*8(sp) // Store ft6
fsd f7, 38*8(sp) // Store ft7
+#if defined(__riscv_float_abi_single)
+ fsd f8, 39*8(sp) // Store fs0
+ fsd f9, 40*8(sp) // Store fs1
+ fsd f18, 49*8(sp) // Store fs2
+ fsd f19, 50*8(sp) // Store fs3
+ fsd f20, 51*8(sp) // Store fs4
+ fsd f21, 52*8(sp) // Store fs5
+ fsd f22, 53*8(sp) // Store fs6
+ fsd f23, 54*8(sp) // Store fs7
+ fsd f24, 55*8(sp) // Store fs8
+ fsd f25, 56*8(sp) // Store fs9
+ fsd f26, 57*8(sp) // Store fs10
+ fsd f27, 58*8(sp) // Store fs11
+#endif
fsd f10,41*8(sp) // Store fa0
fsd f11,42*8(sp) // Store fa1
fsd f12,43*8(sp) // Store fa2
@@ -149,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 */
@@ -181,7 +209,11 @@ _tx_thread_context_save:
#endif
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ addi sp, sp, -16 // Reserve space to save the return address
+ sd ra, 0(sp) // Save the return address
call _tx_execution_isr_enter // Call the ISR execution enter function
+ ld ra, 0(sp) // Recover the return address
+ addi sp, sp, 16 // Recover the reserved stack space
#endif
ret // Return to calling ISR
@@ -193,7 +225,7 @@ _tx_thread_not_nested_save:
/* else if (_tx_thread_current_ptr)
{ */
addi t1, t1, 1 // Increment the interrupt counter
- sd t1, 0(t0) // Store the interrupt counter
+ sw t1, 0(t0) // Store the interrupt counter
/* Not nested: Find the user thread that was running and load our SP */
@@ -225,8 +257,17 @@ _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. */
-#ifdef __riscv_float_abi_single
+#if (__riscv_flen == 32)
fsw f0, 31*8(sp) // Store ft0
fsw f1, 32*8(sp) // Store ft1
fsw f2, 33*8(sp) // Store ft2
@@ -249,7 +290,7 @@ _tx_thread_not_nested_save:
fsw f31,62*8(sp) // Store ft11
csrr t0, fcsr
sd t0, 63*8(sp) // Store fcsr
-#elif defined(__riscv_float_abi_double)
+#elif (__riscv_flen == 64)
fsd f0, 31*8(sp) // Store ft0
fsd f1, 32*8(sp) // Store ft1
fsd f2, 33*8(sp) // Store ft2
@@ -258,6 +299,20 @@ _tx_thread_not_nested_save:
fsd f5, 36*8(sp) // Store ft5
fsd f6, 37*8(sp) // Store ft6
fsd f7, 38*8(sp) // Store ft7
+#if defined(__riscv_float_abi_single)
+ fsd f8, 39*8(sp) // Store fs0
+ fsd f9, 40*8(sp) // Store fs1
+ fsd f18, 49*8(sp) // Store fs2
+ fsd f19, 50*8(sp) // Store fs3
+ fsd f20, 51*8(sp) // Store fs4
+ fsd f21, 52*8(sp) // Store fs5
+ fsd f22, 53*8(sp) // Store fs6
+ fsd f23, 54*8(sp) // Store fs7
+ fsd f24, 55*8(sp) // Store fs8
+ fsd f25, 56*8(sp) // Store fs9
+ fsd f26, 57*8(sp) // Store fs10
+ fsd f27, 58*8(sp) // Store fs11
+#endif
fsd f10,41*8(sp) // Store fa0
fsd f11,42*8(sp) // Store fa1
fsd f12,43*8(sp) // Store fa2
@@ -273,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 */
@@ -316,7 +372,11 @@ _tx_thread_not_nested_save:
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* _tx_execution_isr_enter is called with thread stack pointer */
+ addi sp, sp, -16 // Reserve space to save the return address
+ sd ra, 0(sp) // Save the return address
call _tx_execution_isr_enter // Call the ISR execution enter function
+ ld ra, 0(sp) // Recover the return address
+ addi sp, sp, 16 // Recover the reserved stack space
#endif
la t0, _tx_thread_system_stack_ptr // Pickup system stack pointer address
@@ -331,25 +391,21 @@ _tx_thread_idle_system_save:
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ addi sp, sp, -16 // Reserve space to save the return address
+ sd ra, 0(sp) // Save the return address
call _tx_execution_isr_enter // Call the ISR execution enter function
+ ld ra, 0(sp) // Recover the return address
+ addi sp, sp, 16 // Recover the reserved stack space
#endif
/* Interrupt occurred in the scheduling loop. */
/* }
} */
-#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double)
- addi sp, sp, 65*8 // Recover stack frame - with floating point enabled
-#else
- addi sp, sp, 32*8 // Recover the reserved stack space
-#endif
+ addi sp, sp, TX_TRAP_FRAME_SIZE // Recover stack frame - with floating point enabled (65*8 data + 8 pad)
#if defined(__riscv_vector)
-#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double)
- addi t0, sp, -65*8
-#else
- addi t0, sp, -32*8
-#endif
+ addi t0, sp, -TX_TRAP_FRAME_SIZE
csrr t1, vlenb // Get vector register byte length
slli t1, t1, 5 // Multiply by 32 (number of vector registers)
addi t1, t1, 4*8 // Add vector CSR space: vstart, vtype, vl, vcsr