diff options
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.S | 90 |
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 |
