diff --git a/port/threadx/inc/tx_port.h b/port/threadx/inc/tx_port.h index 98b46d9..1b9f9d8 100644 --- a/port/threadx/inc/tx_port.h +++ b/port/threadx/inc/tx_port.h @@ -68,6 +68,54 @@ #endif #define REGBYTES (1 << LOG_REGBYTES) +#define TX_CONTEXT_ALIGN(size) (((size) + 15) & -16) + +/* Keep the existing hard-float enable policy. Save the full hardware register + * width, even when the calling convention uses narrower floating-point values. + */ +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) +#define TX_CONTEXT_FP_ENABLED 1 +#if __riscv_flen == 64 +#define TX_FP_BYTES 8 +#define TX_FP_LOAD fld +#define TX_FP_STORE fsd +#elif __riscv_flen == 32 +#define TX_FP_BYTES 4 +#define TX_FP_LOAD flw +#define TX_FP_STORE fsw +#else +#error "Unsupported RISC-V floating-point register width" +#endif +#else +#define TX_CONTEXT_FP_ENABLED 0 +#define TX_FP_BYTES 0 +#endif + +/* Integer slots 0..30 contain the interrupt context; slot 31 is padding. + * Voluntary switches use slots 0..14; slot 15 is padding. Starting the FP + * areas at these boundaries aligns double registers on RV32 as well as RV64. + */ +#define TX_INTERRUPT_FP_BASE (32 * REGBYTES) +#define TX_SOLICITED_FP_BASE (16 * REGBYTES) +#define TX_INTERRUPT_FP_OFFSET(n) (TX_INTERRUPT_FP_BASE + (n) * TX_FP_BYTES) +/* Solicited FP indices: fs0, fs1, fs2, ... fs11 (not architectural numbers). */ +#define TX_SOLICITED_FP_OFFSET(n) (TX_SOLICITED_FP_BASE + (n) * TX_FP_BYTES) +#define TX_INTERRUPT_FCSR_OFFSET TX_INTERRUPT_FP_OFFSET(32) +#define TX_SOLICITED_FCSR_OFFSET TX_SOLICITED_FP_OFFSET(12) + +/* fcsr follows the FP registers and occupies one REGBYTES slot because + * it is accessed with integer LOAD/STORE. Round the complete frame up to + * 16 bytes so allocating or releasing it preserves stack alignment. Without + * FP support, the frame contains only the integer slots and their padding. + */ +#if TX_CONTEXT_FP_ENABLED +#define TX_INTERRUPT_FRAME_SIZE TX_CONTEXT_ALIGN(TX_INTERRUPT_FCSR_OFFSET + REGBYTES) +#define TX_SOLICITED_FRAME_SIZE TX_CONTEXT_ALIGN(TX_SOLICITED_FCSR_OFFSET + REGBYTES) +#else +#define TX_INTERRUPT_FRAME_SIZE TX_INTERRUPT_FP_BASE +#define TX_SOLICITED_FRAME_SIZE TX_SOLICITED_FP_BASE +#endif + #else /*not __ASSEMBLER__ */ /* Determine if the optional ThreadX user define file should be used. */ diff --git a/port/threadx/src/trap_entry.S b/port/threadx/src/trap_entry.S index 5c2f456..50d2dc5 100644 --- a/port/threadx/src/trap_entry.S +++ b/port/threadx/src/trap_entry.S @@ -62,11 +62,7 @@ .global trap_entry .extern _tx_thread_context_restore trap_entry: -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi sp, sp, -65*REGBYTES // Allocate space for all registers - with floating point enabled -#else - addi sp, sp, -32*REGBYTES // Allocate space for all registers - without floating point enabled -#endif + addi sp, sp, -TX_INTERRUPT_FRAME_SIZE STORE x1, 28*REGBYTES(sp) // Store RA, 28*REGBYTES(because call will override ra [ra is a calle register in riscv]) @@ -75,11 +71,11 @@ csrr a0, mcause csrr a1, mepc csrr a2, mtval - addi sp, sp, -8 + addi sp, sp, -16 // Keep the C handler stack aligned STORE ra, 0(sp) call trap_handler LOAD ra, 0(sp) - addi sp, sp, 8 + addi sp, sp, 16 call _tx_thread_context_restore // it will nerver return .weak trap_handler diff --git a/port/threadx/src/tx_thread_context_restore.S b/port/threadx/src/tx_thread_context_restore.S index 29f9452..8792a76 100644 --- a/port/threadx/src/tx_thread_context_restore.S +++ b/port/threadx/src/tx_thread_context_restore.S @@ -91,51 +91,28 @@ _tx_thread_context_restore: interrupt. */ /* Recover floating point registers. */ -#if defined(__riscv_float_abi_single) - flw f0, 31*REGBYTES(sp) // Recover ft0 - flw f1, 32*REGBYTES(sp) // Recover ft1 - flw f2, 33*REGBYTES(sp) // Recover ft2 - flw f3, 34*REGBYTES(sp) // Recover ft3 - flw f4, 35*REGBYTES(sp) // Recover ft4 - flw f5, 36*REGBYTES(sp) // Recover ft5 - flw f6, 37*REGBYTES(sp) // Recover ft6 - flw f7, 38*REGBYTES(sp) // Recover ft7 - flw f10,41*REGBYTES(sp) // Recover fa0 - flw f11,42*REGBYTES(sp) // Recover fa1 - flw f12,43*REGBYTES(sp) // Recover fa2 - flw f13,44*REGBYTES(sp) // Recover fa3 - flw f14,45*REGBYTES(sp) // Recover fa4 - flw f15,46*REGBYTES(sp) // Recover fa5 - flw f16,47*REGBYTES(sp) // Recover fa6 - flw f17,48*REGBYTES(sp) // Recover fa7 - flw f28,59*REGBYTES(sp) // Recover ft8 - flw f29,60*REGBYTES(sp) // Recover ft9 - flw f30,61*REGBYTES(sp) // Recover ft10 - flw f31,62*REGBYTES(sp) // Recover ft11 - lw t0, 63*REGBYTES(sp) // Recover fcsr - csrw fcsr, t0 // -#elif defined(__riscv_float_abi_double) - fld f0, 31*REGBYTES(sp) // Recover ft0 - fld f1, 32*REGBYTES(sp) // Recover ft1 - fld f2, 33*REGBYTES(sp) // Recover ft2 - fld f3, 34*REGBYTES(sp) // Recover ft3 - fld f4, 35*REGBYTES(sp) // Recover ft4 - fld f5, 36*REGBYTES(sp) // Recover ft5 - fld f6, 37*REGBYTES(sp) // Recover ft6 - fld f7, 38*REGBYTES(sp) // Recover ft7 - fld f10,41*REGBYTES(sp) // Recover fa0 - fld f11,42*REGBYTES(sp) // Recover fa1 - fld f12,43*REGBYTES(sp) // Recover fa2 - fld f13,44*REGBYTES(sp) // Recover fa3 - fld f14,45*REGBYTES(sp) // Recover fa4 - fld f15,46*REGBYTES(sp) // Recover fa5 - fld f16,47*REGBYTES(sp) // Recover fa6 - fld f17,48*REGBYTES(sp) // Recover fa7 - fld f28,59*REGBYTES(sp) // Recover ft8 - fld f29,60*REGBYTES(sp) // Recover ft9 - fld f30,61*REGBYTES(sp) // Recover ft10 - fld f31,62*REGBYTES(sp) // Recover ft11 - LOAD t0, 63*REGBYTES(sp) // Recover fcsr +#if TX_CONTEXT_FP_ENABLED + TX_FP_LOAD f0, TX_INTERRUPT_FP_OFFSET(0)(sp) // Recover ft0 + TX_FP_LOAD f1, TX_INTERRUPT_FP_OFFSET(1)(sp) // Recover ft1 + TX_FP_LOAD f2, TX_INTERRUPT_FP_OFFSET(2)(sp) // Recover ft2 + TX_FP_LOAD f3, TX_INTERRUPT_FP_OFFSET(3)(sp) // Recover ft3 + TX_FP_LOAD f4, TX_INTERRUPT_FP_OFFSET(4)(sp) // Recover ft4 + TX_FP_LOAD f5, TX_INTERRUPT_FP_OFFSET(5)(sp) // Recover ft5 + TX_FP_LOAD f6, TX_INTERRUPT_FP_OFFSET(6)(sp) // Recover ft6 + TX_FP_LOAD f7, TX_INTERRUPT_FP_OFFSET(7)(sp) // Recover ft7 + TX_FP_LOAD f10, TX_INTERRUPT_FP_OFFSET(10)(sp) // Recover fa0 + TX_FP_LOAD f11, TX_INTERRUPT_FP_OFFSET(11)(sp) // Recover fa1 + TX_FP_LOAD f12, TX_INTERRUPT_FP_OFFSET(12)(sp) // Recover fa2 + TX_FP_LOAD f13, TX_INTERRUPT_FP_OFFSET(13)(sp) // Recover fa3 + TX_FP_LOAD f14, TX_INTERRUPT_FP_OFFSET(14)(sp) // Recover fa4 + TX_FP_LOAD f15, TX_INTERRUPT_FP_OFFSET(15)(sp) // Recover fa5 + TX_FP_LOAD f16, TX_INTERRUPT_FP_OFFSET(16)(sp) // Recover fa6 + TX_FP_LOAD f17, TX_INTERRUPT_FP_OFFSET(17)(sp) // Recover fa7 + TX_FP_LOAD f28, TX_INTERRUPT_FP_OFFSET(28)(sp) // Recover ft8 + TX_FP_LOAD f29, TX_INTERRUPT_FP_OFFSET(29)(sp) // Recover ft9 + TX_FP_LOAD f30, TX_INTERRUPT_FP_OFFSET(30)(sp) // Recover ft10 + TX_FP_LOAD f31, TX_INTERRUPT_FP_OFFSET(31)(sp) // Recover ft11 + LOAD t0, TX_INTERRUPT_FCSR_OFFSET(sp) // Recover fcsr csrw fcsr, t0 // #endif @@ -149,7 +126,7 @@ _tx_thread_context_restore: LOAD t0, 30*REGBYTES(sp) // Recover mepc csrw mepc, t0 // Setup mepc li t0, 0x1880 // Prepare MPIP -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) +#if TX_CONTEXT_FP_ENABLED li t1, 1<<13 or t0, t1, t0 #endif @@ -173,11 +150,7 @@ _tx_thread_context_restore: LOAD x30, 14*REGBYTES(sp) // Recover t5 LOAD x31, 13*REGBYTES(sp) // Recover t6 -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi sp, sp, 65*REGBYTES // Recover stack frame - with floating point enabled -#else - addi sp, sp, 32*REGBYTES // Recover stack frame - without floating point enabled -#endif + addi sp, sp, TX_INTERRUPT_FRAME_SIZE mret // Return to point of interrupt /* } */ @@ -206,51 +179,28 @@ _tx_thread_no_preempt_restore: LOAD sp, 2*REGBYTES(t1) // Switch back to thread's stack /* Recover floating point registers. */ -#if defined(__riscv_float_abi_single) - flw f0, 31*REGBYTES(sp) // Recover ft0 - flw f1, 32*REGBYTES(sp) // Recover ft1 - flw f2, 33*REGBYTES(sp) // Recover ft2 - flw f3, 34*REGBYTES(sp) // Recover ft3 - flw f4, 35*REGBYTES(sp) // Recover ft4 - flw f5, 36*REGBYTES(sp) // Recover ft5 - flw f6, 37*REGBYTES(sp) // Recover ft6 - flw f7, 38*REGBYTES(sp) // Recover ft7 - flw f10,41*REGBYTES(sp) // Recover fa0 - flw f11,42*REGBYTES(sp) // Recover fa1 - flw f12,43*REGBYTES(sp) // Recover fa2 - flw f13,44*REGBYTES(sp) // Recover fa3 - flw f14,45*REGBYTES(sp) // Recover fa4 - flw f15,46*REGBYTES(sp) // Recover fa5 - flw f16,47*REGBYTES(sp) // Recover fa6 - flw f17,48*REGBYTES(sp) // Recover fa7 - flw f28,59*REGBYTES(sp) // Recover ft8 - flw f29,60*REGBYTES(sp) // Recover ft9 - flw f30,61*REGBYTES(sp) // Recover ft10 - flw f31,62*REGBYTES(sp) // Recover ft11 - lw t0, 63*REGBYTES(sp) // Recover fcsr - csrw fcsr, t0 // -#elif defined(__riscv_float_abi_double) - fld f0, 31*REGBYTES(sp) // Recover ft0 - fld f1, 32*REGBYTES(sp) // Recover ft1 - fld f2, 33*REGBYTES(sp) // Recover ft2 - fld f3, 34*REGBYTES(sp) // Recover ft3 - fld f4, 35*REGBYTES(sp) // Recover ft4 - fld f5, 36*REGBYTES(sp) // Recover ft5 - fld f6, 37*REGBYTES(sp) // Recover ft6 - fld f7, 38*REGBYTES(sp) // Recover ft7 - fld f10,41*REGBYTES(sp) // Recover fa0 - fld f11,42*REGBYTES(sp) // Recover fa1 - fld f12,43*REGBYTES(sp) // Recover fa2 - fld f13,44*REGBYTES(sp) // Recover fa3 - fld f14,45*REGBYTES(sp) // Recover fa4 - fld f15,46*REGBYTES(sp) // Recover fa5 - fld f16,47*REGBYTES(sp) // Recover fa6 - fld f17,48*REGBYTES(sp) // Recover fa7 - fld f28,59*REGBYTES(sp) // Recover ft8 - fld f29,60*REGBYTES(sp) // Recover ft9 - fld f30,61*REGBYTES(sp) // Recover ft10 - fld f31,62*REGBYTES(sp) // Recover ft11 - LOAD t0, 63*REGBYTES(sp) // Recover fcsr +#if TX_CONTEXT_FP_ENABLED + TX_FP_LOAD f0, TX_INTERRUPT_FP_OFFSET(0)(sp) // Recover ft0 + TX_FP_LOAD f1, TX_INTERRUPT_FP_OFFSET(1)(sp) // Recover ft1 + TX_FP_LOAD f2, TX_INTERRUPT_FP_OFFSET(2)(sp) // Recover ft2 + TX_FP_LOAD f3, TX_INTERRUPT_FP_OFFSET(3)(sp) // Recover ft3 + TX_FP_LOAD f4, TX_INTERRUPT_FP_OFFSET(4)(sp) // Recover ft4 + TX_FP_LOAD f5, TX_INTERRUPT_FP_OFFSET(5)(sp) // Recover ft5 + TX_FP_LOAD f6, TX_INTERRUPT_FP_OFFSET(6)(sp) // Recover ft6 + TX_FP_LOAD f7, TX_INTERRUPT_FP_OFFSET(7)(sp) // Recover ft7 + TX_FP_LOAD f10, TX_INTERRUPT_FP_OFFSET(10)(sp) // Recover fa0 + TX_FP_LOAD f11, TX_INTERRUPT_FP_OFFSET(11)(sp) // Recover fa1 + TX_FP_LOAD f12, TX_INTERRUPT_FP_OFFSET(12)(sp) // Recover fa2 + TX_FP_LOAD f13, TX_INTERRUPT_FP_OFFSET(13)(sp) // Recover fa3 + TX_FP_LOAD f14, TX_INTERRUPT_FP_OFFSET(14)(sp) // Recover fa4 + TX_FP_LOAD f15, TX_INTERRUPT_FP_OFFSET(15)(sp) // Recover fa5 + TX_FP_LOAD f16, TX_INTERRUPT_FP_OFFSET(16)(sp) // Recover fa6 + TX_FP_LOAD f17, TX_INTERRUPT_FP_OFFSET(17)(sp) // Recover fa7 + TX_FP_LOAD f28, TX_INTERRUPT_FP_OFFSET(28)(sp) // Recover ft8 + TX_FP_LOAD f29, TX_INTERRUPT_FP_OFFSET(29)(sp) // Recover ft9 + TX_FP_LOAD f30, TX_INTERRUPT_FP_OFFSET(30)(sp) // Recover ft10 + TX_FP_LOAD f31, TX_INTERRUPT_FP_OFFSET(31)(sp) // Recover ft11 + LOAD t0, TX_INTERRUPT_FCSR_OFFSET(sp) // Recover fcsr csrw fcsr, t0 // #endif @@ -263,7 +213,7 @@ _tx_thread_no_preempt_restore: LOAD t0, 30*REGBYTES(sp) // Recover mepc csrw mepc, t0 // Setup mepc li t0, 0x1880 // Prepare MPIP -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) +#if TX_CONTEXT_FP_ENABLED li t1, 1<<13 or t0, t1, t0 #endif @@ -287,11 +237,7 @@ _tx_thread_no_preempt_restore: LOAD x30, 14*REGBYTES(sp) // Recover t5 LOAD x31, 13*REGBYTES(sp) // Recover t6 -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi sp, sp, 65*REGBYTES // Recover stack frame - with floating point enabled -#else - addi sp, sp, 32*REGBYTES // Recover stack frame - without floating point enabled -#endif + addi sp, sp, TX_INTERRUPT_FRAME_SIZE mret // Return to point of interrupt /* } @@ -306,32 +252,19 @@ _tx_thread_preempt_restore: STORE t3, 0(t0) // Store stack type /* Store floating point preserved registers. */ -#ifdef __riscv_float_abi_single - fsw f8, 39*REGBYTES(t0) // Store fs0 - fsw f9, 40*REGBYTES(t0) // Store fs1 - fsw f18, 49*REGBYTES(t0) // Store fs2 - fsw f19, 50*REGBYTES(t0) // Store fs3 - fsw f20, 51*REGBYTES(t0) // Store fs4 - fsw f21, 52*REGBYTES(t0) // Store fs5 - fsw f22, 53*REGBYTES(t0) // Store fs6 - fsw f23, 54*REGBYTES(t0) // Store fs7 - fsw f24, 55*REGBYTES(t0) // Store fs8 - fsw f25, 56*REGBYTES(t0) // Store fs9 - fsw f26, 57*REGBYTES(t0) // Store fs10 - fsw f27, 58*REGBYTES(t0) // Store fs11 -#elif defined(__riscv_float_abi_double) - fsd f8, 39*REGBYTES(t0) // Store fs0 - fsd f9, 40*REGBYTES(t0) // Store fs1 - fsd f18, 49*REGBYTES(t0) // Store fs2 - fsd f19, 50*REGBYTES(t0) // Store fs3 - fsd f20, 51*REGBYTES(t0) // Store fs4 - fsd f21, 52*REGBYTES(t0) // Store fs5 - fsd f22, 53*REGBYTES(t0) // Store fs6 - fsd f23, 54*REGBYTES(t0) // Store fs7 - fsd f24, 55*REGBYTES(t0) // Store fs8 - fsd f25, 56*REGBYTES(t0) // Store fs9 - fsd f26, 57*REGBYTES(t0) // Store fs10 - fsd f27, 58*REGBYTES(t0) // Store fs11 +#if TX_CONTEXT_FP_ENABLED + TX_FP_STORE f8, TX_INTERRUPT_FP_OFFSET(8)(t0) // Store fs0 + TX_FP_STORE f9, TX_INTERRUPT_FP_OFFSET(9)(t0) // Store fs1 + TX_FP_STORE f18, TX_INTERRUPT_FP_OFFSET(18)(t0) // Store fs2 + TX_FP_STORE f19, TX_INTERRUPT_FP_OFFSET(19)(t0) // Store fs3 + TX_FP_STORE f20, TX_INTERRUPT_FP_OFFSET(20)(t0) // Store fs4 + TX_FP_STORE f21, TX_INTERRUPT_FP_OFFSET(21)(t0) // Store fs5 + TX_FP_STORE f22, TX_INTERRUPT_FP_OFFSET(22)(t0) // Store fs6 + TX_FP_STORE f23, TX_INTERRUPT_FP_OFFSET(23)(t0) // Store fs7 + TX_FP_STORE f24, TX_INTERRUPT_FP_OFFSET(24)(t0) // Store fs8 + TX_FP_STORE f25, TX_INTERRUPT_FP_OFFSET(25)(t0) // Store fs9 + TX_FP_STORE f26, TX_INTERRUPT_FP_OFFSET(26)(t0) // Store fs10 + TX_FP_STORE f27, TX_INTERRUPT_FP_OFFSET(27)(t0) // Store fs11 #endif /* Store standard preserved registers. */ diff --git a/port/threadx/src/tx_thread_context_save.S b/port/threadx/src/tx_thread_context_save.S index c07ecf0..a8070a1 100644 --- a/port/threadx/src/tx_thread_context_save.S +++ b/port/threadx/src/tx_thread_context_save.S @@ -105,52 +105,29 @@ _tx_thread_context_save: STORE t0, 30*REGBYTES(sp) // Save it on the stack /* Save floating point scratch registers. */ -#if defined(__riscv_float_abi_single) - fsw f0, 31*REGBYTES(sp) // Store ft0 - fsw f1, 32*REGBYTES(sp) // Store ft1 - fsw f2, 33*REGBYTES(sp) // Store ft2 - fsw f3, 34*REGBYTES(sp) // Store ft3 - fsw f4, 35*REGBYTES(sp) // Store ft4 - fsw f5, 36*REGBYTES(sp) // Store ft5 - fsw f6, 37*REGBYTES(sp) // Store ft6 - fsw f7, 38*REGBYTES(sp) // Store ft7 - fsw f10,41*REGBYTES(sp) // Store fa0 - fsw f11,42*REGBYTES(sp) // Store fa1 - fsw f12,43*REGBYTES(sp) // Store fa2 - fsw f13,44*REGBYTES(sp) // Store fa3 - fsw f14,45*REGBYTES(sp) // Store fa4 - fsw f15,46*REGBYTES(sp) // Store fa5 - fsw f16,47*REGBYTES(sp) // Store fa6 - fsw f17,48*REGBYTES(sp) // Store fa7 - fsw f28,59*REGBYTES(sp) // Store ft8 - fsw f29,60*REGBYTES(sp) // Store ft9 - fsw f30,61*REGBYTES(sp) // Store ft10 - fsw f31,62*REGBYTES(sp) // Store ft11 +#if TX_CONTEXT_FP_ENABLED + TX_FP_STORE f0, TX_INTERRUPT_FP_OFFSET(0)(sp) // Store ft0 + TX_FP_STORE f1, TX_INTERRUPT_FP_OFFSET(1)(sp) // Store ft1 + TX_FP_STORE f2, TX_INTERRUPT_FP_OFFSET(2)(sp) // Store ft2 + TX_FP_STORE f3, TX_INTERRUPT_FP_OFFSET(3)(sp) // Store ft3 + TX_FP_STORE f4, TX_INTERRUPT_FP_OFFSET(4)(sp) // Store ft4 + TX_FP_STORE f5, TX_INTERRUPT_FP_OFFSET(5)(sp) // Store ft5 + TX_FP_STORE f6, TX_INTERRUPT_FP_OFFSET(6)(sp) // Store ft6 + TX_FP_STORE f7, TX_INTERRUPT_FP_OFFSET(7)(sp) // Store ft7 + TX_FP_STORE f10, TX_INTERRUPT_FP_OFFSET(10)(sp) // Store fa0 + TX_FP_STORE f11, TX_INTERRUPT_FP_OFFSET(11)(sp) // Store fa1 + TX_FP_STORE f12, TX_INTERRUPT_FP_OFFSET(12)(sp) // Store fa2 + TX_FP_STORE f13, TX_INTERRUPT_FP_OFFSET(13)(sp) // Store fa3 + TX_FP_STORE f14, TX_INTERRUPT_FP_OFFSET(14)(sp) // Store fa4 + TX_FP_STORE f15, TX_INTERRUPT_FP_OFFSET(15)(sp) // Store fa5 + TX_FP_STORE f16, TX_INTERRUPT_FP_OFFSET(16)(sp) // Store fa6 + TX_FP_STORE f17, TX_INTERRUPT_FP_OFFSET(17)(sp) // Store fa7 + TX_FP_STORE f28, TX_INTERRUPT_FP_OFFSET(28)(sp) // Store ft8 + TX_FP_STORE f29, TX_INTERRUPT_FP_OFFSET(29)(sp) // Store ft9 + TX_FP_STORE f30, TX_INTERRUPT_FP_OFFSET(30)(sp) // Store ft10 + TX_FP_STORE f31, TX_INTERRUPT_FP_OFFSET(31)(sp) // Store ft11 csrr t0, fcsr - STORE t0, 63*REGBYTES(sp) // Store fcsr -#elif defined(__riscv_float_abi_double) - fsd f0, 31*REGBYTES(sp) // Store ft0 - fsd f1, 32*REGBYTES(sp) // Store ft1 - fsd f2, 33*REGBYTES(sp) // Store ft2 - fsd f3, 34*REGBYTES(sp) // Store ft3 - fsd f4, 35*REGBYTES(sp) // Store ft4 - fsd f5, 36*REGBYTES(sp) // Store ft5 - fsd f6, 37*REGBYTES(sp) // Store ft6 - fsd f7, 38*REGBYTES(sp) // Store ft7 - fsd f10,41*REGBYTES(sp) // Store fa0 - fsd f11,42*REGBYTES(sp) // Store fa1 - fsd f12,43*REGBYTES(sp) // Store fa2 - fsd f13,44*REGBYTES(sp) // Store fa3 - fsd f14,45*REGBYTES(sp) // Store fa4 - fsd f15,46*REGBYTES(sp) // Store fa5 - fsd f16,47*REGBYTES(sp) // Store fa6 - fsd f17,48*REGBYTES(sp) // Store fa7 - fsd f28,59*REGBYTES(sp) // Store ft8 - fsd f29,60*REGBYTES(sp) // Store ft9 - fsd f30,61*REGBYTES(sp) // Store ft10 - fsd f31,62*REGBYTES(sp) // Store ft11 - csrr t0, fcsr - STORE t0, 63*REGBYTES(sp) // Store fcsr + STORE t0, TX_INTERRUPT_FCSR_OFFSET(sp) // Store fcsr #endif #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY @@ -194,52 +171,29 @@ _tx_thread_not_nested_save: STORE t0, 30*REGBYTES(sp) // Save it on the stack /* Save floating point scratch registers. */ -#if defined(__riscv_float_abi_single) - fsw f0, 31*REGBYTES(sp) // Store ft0 - fsw f1, 32*REGBYTES(sp) // Store ft1 - fsw f2, 33*REGBYTES(sp) // Store ft2 - fsw f3, 34*REGBYTES(sp) // Store ft3 - fsw f4, 35*REGBYTES(sp) // Store ft4 - fsw f5, 36*REGBYTES(sp) // Store ft5 - fsw f6, 37*REGBYTES(sp) // Store ft6 - fsw f7, 38*REGBYTES(sp) // Store ft7 - fsw f10,41*REGBYTES(sp) // Store fa0 - fsw f11,42*REGBYTES(sp) // Store fa1 - fsw f12,43*REGBYTES(sp) // Store fa2 - fsw f13,44*REGBYTES(sp) // Store fa3 - fsw f14,45*REGBYTES(sp) // Store fa4 - fsw f15,46*REGBYTES(sp) // Store fa5 - fsw f16,47*REGBYTES(sp) // Store fa6 - fsw f17,48*REGBYTES(sp) // Store fa7 - fsw f28,59*REGBYTES(sp) // Store ft8 - fsw f29,60*REGBYTES(sp) // Store ft9 - fsw f30,61*REGBYTES(sp) // Store ft10 - fsw f31,62*REGBYTES(sp) // Store ft11 +#if TX_CONTEXT_FP_ENABLED + TX_FP_STORE f0, TX_INTERRUPT_FP_OFFSET(0)(sp) // Store ft0 + TX_FP_STORE f1, TX_INTERRUPT_FP_OFFSET(1)(sp) // Store ft1 + TX_FP_STORE f2, TX_INTERRUPT_FP_OFFSET(2)(sp) // Store ft2 + TX_FP_STORE f3, TX_INTERRUPT_FP_OFFSET(3)(sp) // Store ft3 + TX_FP_STORE f4, TX_INTERRUPT_FP_OFFSET(4)(sp) // Store ft4 + TX_FP_STORE f5, TX_INTERRUPT_FP_OFFSET(5)(sp) // Store ft5 + TX_FP_STORE f6, TX_INTERRUPT_FP_OFFSET(6)(sp) // Store ft6 + TX_FP_STORE f7, TX_INTERRUPT_FP_OFFSET(7)(sp) // Store ft7 + TX_FP_STORE f10, TX_INTERRUPT_FP_OFFSET(10)(sp) // Store fa0 + TX_FP_STORE f11, TX_INTERRUPT_FP_OFFSET(11)(sp) // Store fa1 + TX_FP_STORE f12, TX_INTERRUPT_FP_OFFSET(12)(sp) // Store fa2 + TX_FP_STORE f13, TX_INTERRUPT_FP_OFFSET(13)(sp) // Store fa3 + TX_FP_STORE f14, TX_INTERRUPT_FP_OFFSET(14)(sp) // Store fa4 + TX_FP_STORE f15, TX_INTERRUPT_FP_OFFSET(15)(sp) // Store fa5 + TX_FP_STORE f16, TX_INTERRUPT_FP_OFFSET(16)(sp) // Store fa6 + TX_FP_STORE f17, TX_INTERRUPT_FP_OFFSET(17)(sp) // Store fa7 + TX_FP_STORE f28, TX_INTERRUPT_FP_OFFSET(28)(sp) // Store ft8 + TX_FP_STORE f29, TX_INTERRUPT_FP_OFFSET(29)(sp) // Store ft9 + TX_FP_STORE f30, TX_INTERRUPT_FP_OFFSET(30)(sp) // Store ft10 + TX_FP_STORE f31, TX_INTERRUPT_FP_OFFSET(31)(sp) // Store ft11 csrr t0, fcsr - STORE t0, 63*REGBYTES(sp) // Store fcsr -#elif defined(__riscv_float_abi_double) - fsd f0, 31*REGBYTES(sp) // Store ft0 - fsd f1, 32*REGBYTES(sp) // Store ft1 - fsd f2, 33*REGBYTES(sp) // Store ft2 - fsd f3, 34*REGBYTES(sp) // Store ft3 - fsd f4, 35*REGBYTES(sp) // Store ft4 - fsd f5, 36*REGBYTES(sp) // Store ft5 - fsd f6, 37*REGBYTES(sp) // Store ft6 - fsd f7, 38*REGBYTES(sp) // Store ft7 - fsd f10,41*REGBYTES(sp) // Store fa0 - fsd f11,42*REGBYTES(sp) // Store fa1 - fsd f12,43*REGBYTES(sp) // Store fa2 - fsd f13,44*REGBYTES(sp) // Store fa3 - fsd f14,45*REGBYTES(sp) // Store fa4 - fsd f15,46*REGBYTES(sp) // Store fa5 - fsd f16,47*REGBYTES(sp) // Store fa6 - fsd f17,48*REGBYTES(sp) // Store fa7 - fsd f28,59*REGBYTES(sp) // Store ft8 - fsd f29,60*REGBYTES(sp) // Store ft9 - fsd f30,61*REGBYTES(sp) // Store ft10 - fsd f31,62*REGBYTES(sp) // Store ft11 - csrr t0, fcsr - STORE t0, 63*REGBYTES(sp) // Store fcsr + STORE t0, TX_INTERRUPT_FCSR_OFFSET(sp) // Store fcsr #endif /* Save the current stack pointer in the thread's control block. */ @@ -275,9 +229,5 @@ _tx_thread_idle_system_save: /* } } */ -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi sp, sp, 65*REGBYTES // Recover stack frame - with floating point enabled -#else - addi sp, sp, 32*REGBYTES // Recover the reserved stack space -#endif + addi sp, sp, TX_INTERRUPT_FRAME_SIZE ret // Return to calling ISR diff --git a/port/threadx/src/tx_thread_schedule.S b/port/threadx/src/tx_thread_schedule.S index b029ad1..bf0cf12 100644 --- a/port/threadx/src/tx_thread_schedule.S +++ b/port/threadx/src/tx_thread_schedule.S @@ -126,75 +126,41 @@ scheduler_found_thread: /* Determine if floating point registers need to be recovered. */ -#if defined(__riscv_float_abi_single) - flw f0, 31*REGBYTES(sp) // Recover ft0 - flw f1, 32*REGBYTES(sp) // Recover ft1 - flw f2, 33*REGBYTES(sp) // Recover ft2 - flw f3, 34*REGBYTES(sp) // Recover ft3 - flw f4, 35*REGBYTES(sp) // Recover ft4 - flw f5, 36*REGBYTES(sp) // Recover ft5 - flw f6, 37*REGBYTES(sp) // Recover ft6 - flw f7, 38*REGBYTES(sp) // Recover ft7 - flw f8, 39*REGBYTES(sp) // Recover fs0 - flw f9, 40*REGBYTES(sp) // Recover fs1 - flw f10,41*REGBYTES(sp) // Recover fa0 - flw f11,42*REGBYTES(sp) // Recover fa1 - flw f12,43*REGBYTES(sp) // Recover fa2 - flw f13,44*REGBYTES(sp) // Recover fa3 - flw f14,45*REGBYTES(sp) // Recover fa4 - flw f15,46*REGBYTES(sp) // Recover fa5 - flw f16,47*REGBYTES(sp) // Recover fa6 - flw f17,48*REGBYTES(sp) // Recover fa7 - flw f18,49*REGBYTES(sp) // Recover fs2 - flw f19,50*REGBYTES(sp) // Recover fs3 - flw f20,51*REGBYTES(sp) // Recover fs4 - flw f21,52*REGBYTES(sp) // Recover fs5 - flw f22,53*REGBYTES(sp) // Recover fs6 - flw f23,54*REGBYTES(sp) // Recover fs7 - flw f24,55*REGBYTES(sp) // Recover fs8 - flw f25,56*REGBYTES(sp) // Recover fs9 - flw f26,57*REGBYTES(sp) // Recover fs10 - flw f27,58*REGBYTES(sp) // Recover fs11 - flw f28,59*REGBYTES(sp) // Recover ft8 - flw f29,60*REGBYTES(sp) // Recover ft9 - flw f30,61*REGBYTES(sp) // Recover ft10 - flw f31,62*REGBYTES(sp) // Recover ft11 - LOAD t0, 63*REGBYTES(sp) // Recover fcsr +#if TX_CONTEXT_FP_ENABLED + TX_FP_LOAD f0, TX_INTERRUPT_FP_OFFSET(0)(sp) // Recover ft0 + TX_FP_LOAD f1, TX_INTERRUPT_FP_OFFSET(1)(sp) // Recover ft1 + TX_FP_LOAD f2, TX_INTERRUPT_FP_OFFSET(2)(sp) // Recover ft2 + TX_FP_LOAD f3, TX_INTERRUPT_FP_OFFSET(3)(sp) // Recover ft3 + TX_FP_LOAD f4, TX_INTERRUPT_FP_OFFSET(4)(sp) // Recover ft4 + TX_FP_LOAD f5, TX_INTERRUPT_FP_OFFSET(5)(sp) // Recover ft5 + TX_FP_LOAD f6, TX_INTERRUPT_FP_OFFSET(6)(sp) // Recover ft6 + TX_FP_LOAD f7, TX_INTERRUPT_FP_OFFSET(7)(sp) // Recover ft7 + TX_FP_LOAD f8, TX_INTERRUPT_FP_OFFSET(8)(sp) // Recover fs0 + TX_FP_LOAD f9, TX_INTERRUPT_FP_OFFSET(9)(sp) // Recover fs1 + TX_FP_LOAD f10, TX_INTERRUPT_FP_OFFSET(10)(sp) // Recover fa0 + TX_FP_LOAD f11, TX_INTERRUPT_FP_OFFSET(11)(sp) // Recover fa1 + TX_FP_LOAD f12, TX_INTERRUPT_FP_OFFSET(12)(sp) // Recover fa2 + TX_FP_LOAD f13, TX_INTERRUPT_FP_OFFSET(13)(sp) // Recover fa3 + TX_FP_LOAD f14, TX_INTERRUPT_FP_OFFSET(14)(sp) // Recover fa4 + TX_FP_LOAD f15, TX_INTERRUPT_FP_OFFSET(15)(sp) // Recover fa5 + TX_FP_LOAD f16, TX_INTERRUPT_FP_OFFSET(16)(sp) // Recover fa6 + TX_FP_LOAD f17, TX_INTERRUPT_FP_OFFSET(17)(sp) // Recover fa7 + TX_FP_LOAD f18, TX_INTERRUPT_FP_OFFSET(18)(sp) // Recover fs2 + TX_FP_LOAD f19, TX_INTERRUPT_FP_OFFSET(19)(sp) // Recover fs3 + TX_FP_LOAD f20, TX_INTERRUPT_FP_OFFSET(20)(sp) // Recover fs4 + TX_FP_LOAD f21, TX_INTERRUPT_FP_OFFSET(21)(sp) // Recover fs5 + TX_FP_LOAD f22, TX_INTERRUPT_FP_OFFSET(22)(sp) // Recover fs6 + TX_FP_LOAD f23, TX_INTERRUPT_FP_OFFSET(23)(sp) // Recover fs7 + TX_FP_LOAD f24, TX_INTERRUPT_FP_OFFSET(24)(sp) // Recover fs8 + TX_FP_LOAD f25, TX_INTERRUPT_FP_OFFSET(25)(sp) // Recover fs9 + TX_FP_LOAD f26, TX_INTERRUPT_FP_OFFSET(26)(sp) // Recover fs10 + TX_FP_LOAD f27, TX_INTERRUPT_FP_OFFSET(27)(sp) // Recover fs11 + TX_FP_LOAD f28, TX_INTERRUPT_FP_OFFSET(28)(sp) // Recover ft8 + TX_FP_LOAD f29, TX_INTERRUPT_FP_OFFSET(29)(sp) // Recover ft9 + TX_FP_LOAD f30, TX_INTERRUPT_FP_OFFSET(30)(sp) // Recover ft10 + TX_FP_LOAD f31, TX_INTERRUPT_FP_OFFSET(31)(sp) // Recover ft11 + LOAD t0, TX_INTERRUPT_FCSR_OFFSET(sp) // Recover fcsr csrw fcsr, t0 // -#elif defined(__riscv_float_abi_double) - fld f0, 31*REGBYTES(sp) // Recover ft0 - fld f1, 32*REGBYTES(sp) // Recover ft1 - fld f2, 33*REGBYTES(sp) // Recover ft2 - fld f3, 34*REGBYTES(sp) // Recover ft3 - fld f4, 35*REGBYTES(sp) // Recover ft4 - fld f5, 36*REGBYTES(sp) // Recover ft5 - fld f6, 37*REGBYTES(sp) // Recover ft6 - fld f7, 38*REGBYTES(sp) // Recover ft7 - fld f8, 39*REGBYTES(sp) // Recover fs0 - fld f9, 40*REGBYTES(sp) // Recover fs1 - fld f10,41*REGBYTES(sp) // Recover fa0 - fld f11,42*REGBYTES(sp) // Recover fa1 - fld f12,43*REGBYTES(sp) // Recover fa2 - fld f13,44*REGBYTES(sp) // Recover fa3 - fld f14,45*REGBYTES(sp) // Recover fa4 - fld f15,46*REGBYTES(sp) // Recover fa5 - fld f16,47*REGBYTES(sp) // Recover fa6 - fld f17,48*REGBYTES(sp) // Recover fa7 - fld f18,49*REGBYTES(sp) // Recover fs2 - fld f19,50*REGBYTES(sp) // Recover fs3 - fld f20,51*REGBYTES(sp) // Recover fs4 - fld f21,52*REGBYTES(sp) // Recover fs5 - fld f22,53*REGBYTES(sp) // Recover fs6 - fld f23,54*REGBYTES(sp) // Recover fs7 - fld f24,55*REGBYTES(sp) // Recover fs8 - fld f25,56*REGBYTES(sp) // Recover fs9 - fld f26,57*REGBYTES(sp) // Recover fs10 - fld f27,58*REGBYTES(sp) // Recover fs11 - fld f28,59*REGBYTES(sp) // Recover ft8 - fld f29,60*REGBYTES(sp) // Recover ft9 - fld f30,61*REGBYTES(sp) // Recover ft10 - fld f31,62*REGBYTES(sp) // Recover ft11 - LOAD t0, 63*REGBYTES(sp) // Recover fcsr #endif /* Recover standard registers. */ @@ -202,7 +168,7 @@ scheduler_found_thread: LOAD t0, 30*REGBYTES(sp) // Recover mepc csrw mepc, t0 // Store mepc li t0, 0x1880 // Prepare MPIP -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) +#if TX_CONTEXT_FP_ENABLED li t1, 1<<13 or t0, t1, t0 #endif @@ -237,44 +203,25 @@ scheduler_found_thread: LOAD x30, 14*REGBYTES(sp) // Recover t5 LOAD x31, 13*REGBYTES(sp) // Recover t6 -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi sp, sp, 65*REGBYTES // Recover stack frame - with floating point registers -#else - addi sp, sp, 32*REGBYTES // Recover stack frame - without floating point registers -#endif + addi sp, sp, TX_INTERRUPT_FRAME_SIZE mret // Return to point of interrupt _tx_thread_synch_return: -#if defined(__riscv_float_abi_single) - flw f8, 15*REGBYTES(sp) // Recover fs0 - flw f9, 16*REGBYTES(sp) // Recover fs1 - flw f18,17*REGBYTES(sp) // Recover fs2 - flw f19,18*REGBYTES(sp) // Recover fs3 - flw f20,19*REGBYTES(sp) // Recover fs4 - flw f21,20*REGBYTES(sp) // Recover fs5 - flw f22,21*REGBYTES(sp) // Recover fs6 - flw f23,22*REGBYTES(sp) // Recover fs7 - flw f24,23*REGBYTES(sp) // Recover fs8 - flw f25,24*REGBYTES(sp) // Recover fs9 - flw f26,25*REGBYTES(sp) // Recover fs10 - flw f27,26*REGBYTES(sp) // Recover fs11 - LOAD t0, 27*REGBYTES(sp) // Recover fcsr - csrw fcsr, t0 // -#elif defined(__riscv_float_abi_double) - fld f8, 15*REGBYTES(sp) // Recover fs0 - fld f9, 16*REGBYTES(sp) // Recover fs1 - fld f18,17*REGBYTES(sp) // Recover fs2 - fld f19,18*REGBYTES(sp) // Recover fs3 - fld f20,19*REGBYTES(sp) // Recover fs4 - fld f21,20*REGBYTES(sp) // Recover fs5 - fld f22,21*REGBYTES(sp) // Recover fs6 - fld f23,22*REGBYTES(sp) // Recover fs7 - fld f24,23*REGBYTES(sp) // Recover fs8 - fld f25,24*REGBYTES(sp) // Recover fs9 - fld f26,25*REGBYTES(sp) // Recover fs10 - fld f27,26*REGBYTES(sp) // Recover fs11 - LOAD t0, 27*REGBYTES(sp) // Recover fcsr +#if TX_CONTEXT_FP_ENABLED + TX_FP_LOAD f8, TX_SOLICITED_FP_OFFSET(0)(sp) // Recover fs0 + TX_FP_LOAD f9, TX_SOLICITED_FP_OFFSET(1)(sp) // Recover fs1 + TX_FP_LOAD f18, TX_SOLICITED_FP_OFFSET(2)(sp) // Recover fs2 + TX_FP_LOAD f19, TX_SOLICITED_FP_OFFSET(3)(sp) // Recover fs3 + TX_FP_LOAD f20, TX_SOLICITED_FP_OFFSET(4)(sp) // Recover fs4 + TX_FP_LOAD f21, TX_SOLICITED_FP_OFFSET(5)(sp) // Recover fs5 + TX_FP_LOAD f22, TX_SOLICITED_FP_OFFSET(6)(sp) // Recover fs6 + TX_FP_LOAD f23, TX_SOLICITED_FP_OFFSET(7)(sp) // Recover fs7 + TX_FP_LOAD f24, TX_SOLICITED_FP_OFFSET(8)(sp) // Recover fs8 + TX_FP_LOAD f25, TX_SOLICITED_FP_OFFSET(9)(sp) // Recover fs9 + TX_FP_LOAD f26, TX_SOLICITED_FP_OFFSET(10)(sp) // Recover fs10 + TX_FP_LOAD f27, TX_SOLICITED_FP_OFFSET(11)(sp) // Recover fs11 + LOAD t0, TX_SOLICITED_FCSR_OFFSET(sp) // Recover fcsr csrw fcsr, t0 // #endif @@ -296,11 +243,7 @@ _tx_thread_synch_return: LOAD x27, 1*REGBYTES(sp) // Recover s11 LOAD t0, 14*REGBYTES(sp) // Recover mstatus csrw mstatus, t0 // Store mstatus, enables interrupt -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi sp, sp, 29*REGBYTES // Recover stack frame -#else - addi sp, sp, 16*REGBYTES // Recover stack frame -#endif + addi sp, sp, TX_SOLICITED_FRAME_SIZE synch_return_exit_label: ret // Return to thread diff --git a/port/threadx/src/tx_thread_stack_build.S b/port/threadx/src/tx_thread_stack_build.S index d7d54f3..4d5e291 100644 --- a/port/threadx/src/tx_thread_stack_build.S +++ b/port/threadx/src/tx_thread_stack_build.S @@ -67,9 +67,10 @@ .global _tx_thread_stack_build _tx_thread_stack_build: - /* Build a fake interrupt frame. The form of the fake interrupt stack - on the RISC-V should look like the following after it is built: - Reg Index + /* Build a fake interrupt frame using this port's inc/tx_context_layout.h, + included through tx_port.h. Integer slot indices below are multiplied + by REGBYTES to obtain byte offsets from the saved stack pointer. + Reg Integer slot Stack Top: 1 0 Interrupt stack frame type x27 1 Initial s11 x26 2 Initial s10 @@ -101,122 +102,37 @@ _tx_thread_stack_build: x1 28 Initial ra -- 29 reserved mepc 30 Initial mepc -If floating point support: - f0 31 Inital ft0 - f1 32 Inital ft1 - f2 33 Inital ft2 - f3 34 Inital ft3 - f4 35 Inital ft4 - f5 36 Inital ft5 - f6 37 Inital ft6 - f7 38 Inital ft7 - f8 39 Inital fs0 - f9 40 Inital fs1 - f10 41 Inital fa0 - f11 42 Inital fa1 - f12 43 Inital fa2 - f13 44 Inital fa3 - f14 45 Inital fa4 - f15 46 Inital fa5 - f16 47 Inital fa6 - f17 48 Inital fa7 - f18 49 Inital fs2 - f19 50 Inital fs3 - f20 51 Inital fs4 - f21 52 Inital fs5 - f22 53 Inital fs6 - f23 54 Inital fs7 - f24 55 Inital fs8 - f25 56 Inital fs9 - f26 57 Inital fs10 - f27 58 Inital fs11 - f28 59 Inital ft8 - f29 60 Inital ft9 - f30 61 Inital ft10 - f31 62 Inital ft11 - fscr 63 Inital fscr + -- 31 Alignment padding - Stack Bottom: (higher memory address) */ + With FP support, f0..f31 follow at TX_INTERRUPT_FP_BASE. Each register + occupies TX_FP_BYTES bytes; fN is at TX_INTERRUPT_FP_OFFSET(N). The + fcsr slot is at TX_INTERRUPT_FCSR_OFFSET and occupies REGBYTES bytes. + Trailing padding rounds the frame size up to a multiple of 16 bytes. + Without FP support, the frame ends after integer slot 31. + + Stack Bottom: saved stack pointer + TX_INTERRUPT_FRAME_SIZE + (higher memory address) */ LOAD t0, 4*REGBYTES(a0) // Pickup end of stack area andi t0, t0, -16 // Ensure 16-byte alignment /* Actually build the stack frame. */ -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi t0, t0, -65*REGBYTES -#else - addi t0, t0, -32*REGBYTES // Allocate space for the stack frame -#endif + addi t0, t0, -TX_INTERRUPT_FRAME_SIZE + /* Clear the whole frame, including both halves of RV32D FP slots. */ + mv t1, t0 + addi t2, t0, TX_INTERRUPT_FRAME_SIZE +.Lclear_initial_context: + STORE x0, 0(t1) + addi t1, t1, REGBYTES + bltu t1, t2, .Lclear_initial_context + li t1, 1 // Build stack type STORE t1, 0*REGBYTES(t0) // Place stack type on the top - STORE x0, 1*REGBYTES(t0) // Initial s11 - STORE x0, 2*REGBYTES(t0) // Initial s10 - STORE x0, 3*REGBYTES(t0) // Initial s9 - STORE x0, 4*REGBYTES(t0) // Initial s8 - STORE x0, 5*REGBYTES(t0) // Initial s7 - STORE x0, 6*REGBYTES(t0) // Initial s6 - STORE x0, 7*REGBYTES(t0) // Initial s5 - STORE x0, 8*REGBYTES(t0) // Initial s4 - STORE x0, 9*REGBYTES(t0) // Initial s3 - STORE x0, 10*REGBYTES(t0) // Initial s2 - STORE x0, 11*REGBYTES(t0) // Initial s1 - STORE x0, 12*REGBYTES(t0) // Initial s0 - STORE x0, 13*REGBYTES(t0) // Initial t6 - STORE x0, 14*REGBYTES(t0) // Initial t5 - STORE x0, 15*REGBYTES(t0) // Initial t4 - STORE x0, 16*REGBYTES(t0) // Initial t3 - STORE x0, 17*REGBYTES(t0) // Initial t2 - STORE x0, 18*REGBYTES(t0) // Initial t1 - STORE x0, 19*REGBYTES(t0) // Initial t0 - STORE x0, 20*REGBYTES(t0) // Initial a7 - STORE x0, 21*REGBYTES(t0) // Initial a6 - STORE x0, 22*REGBYTES(t0) // Initial a5 - STORE x0, 23*REGBYTES(t0) // Initial a4 - STORE x0, 24*REGBYTES(t0) // Initial a3 - STORE x0, 25*REGBYTES(t0) // Initial a2 - STORE x0, 26*REGBYTES(t0) // Initial a1 - STORE x0, 27*REGBYTES(t0) // Initial a0 - STORE x0, 28*REGBYTES(t0) // Initial ra STORE a1, 30*REGBYTES(t0) // Initial mepc -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - STORE x0, 31*REGBYTES(t0) // Inital ft0 - STORE x0, 32*REGBYTES(t0) // Inital ft1 - STORE x0, 33*REGBYTES(t0) // Inital ft2 - STORE x0, 34*REGBYTES(t0) // Inital ft3 - STORE x0, 35*REGBYTES(t0) // Inital ft4 - STORE x0, 36*REGBYTES(t0) // Inital ft5 - STORE x0, 37*REGBYTES(t0) // Inital ft6 - STORE x0, 38*REGBYTES(t0) // Inital ft7 - STORE x0, 39*REGBYTES(t0) // Inital fs0 - STORE x0, 40*REGBYTES(t0) // Inital fs1 - STORE x0, 41*REGBYTES(t0) // Inital fa0 - STORE x0, 42*REGBYTES(t0) // Inital fa1 - STORE x0, 43*REGBYTES(t0) // Inital fa2 - STORE x0, 44*REGBYTES(t0) // Inital fa3 - STORE x0, 45*REGBYTES(t0) // Inital fa4 - STORE x0, 46*REGBYTES(t0) // Inital fa5 - STORE x0, 47*REGBYTES(t0) // Inital fa6 - STORE x0, 48*REGBYTES(t0) // Inital fa7 - STORE x0, 49*REGBYTES(t0) // Inital fs2 - STORE x0, 50*REGBYTES(t0) // Inital fs3 - STORE x0, 51*REGBYTES(t0) // Inital fs4 - STORE x0, 52*REGBYTES(t0) // Inital fs5 - STORE x0, 53*REGBYTES(t0) // Inital fs6 - STORE x0, 54*REGBYTES(t0) // Inital fs7 - STORE x0, 55*REGBYTES(t0) // Inital fs8 - STORE x0, 56*REGBYTES(t0) // Inital fs9 - STORE x0, 57*REGBYTES(t0) // Inital fs10 - STORE x0, 58*REGBYTES(t0) // Inital fs11 - STORE x0, 59*REGBYTES(t0) // Inital ft8 - STORE x0, 60*REGBYTES(t0) // Inital ft9 - STORE x0, 61*REGBYTES(t0) // Inital ft10 - STORE x0, 62*REGBYTES(t0) // Inital ft11 - csrr a1, fcsr // Read fcsr and use it for initial value for each thread - STORE a1, 63*REGBYTES(t0) // Initial fscr - STORE x0, 64*REGBYTES(t0) // Reserved word (0) -#else - STORE x0, 31*REGBYTES(t0) // Reserved word (0) +#if TX_CONTEXT_FP_ENABLED + csrr a1, fcsr + STORE a1, TX_INTERRUPT_FCSR_OFFSET(t0) // Initial fcsr #endif /* Setup stack pointer. */ diff --git a/port/threadx/src/tx_thread_system_return.S b/port/threadx/src/tx_thread_system_return.S index 2b05c2a..7b9dbd3 100644 --- a/port/threadx/src/tx_thread_system_return.S +++ b/port/threadx/src/tx_thread_system_return.S @@ -69,43 +69,24 @@ _tx_thread_system_return: /* Save minimal context on the stack. */ -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi sp, sp, -29*REGBYTES // Allocate space on the stack - with floating point enabled -#else - addi sp, sp, -16*REGBYTES // Allocate space on the stack - without floating point enabled -#endif + addi sp, sp, -TX_SOLICITED_FRAME_SIZE /* Store floating point preserved registers. */ -#if defined(__riscv_float_abi_single) - fsw f8, 15*REGBYTES(sp) // Store fs0 - fsw f9, 16*REGBYTES(sp) // Store fs1 - fsw f18, 17*REGBYTES(sp) // Store fs2 - fsw f19, 18*REGBYTES(sp) // Store fs3 - fsw f20, 19*REGBYTES(sp) // Store fs4 - fsw f21, 20*REGBYTES(sp) // Store fs5 - fsw f22, 21*REGBYTES(sp) // Store fs6 - fsw f23, 22*REGBYTES(sp) // Store fs7 - fsw f24, 23*REGBYTES(sp) // Store fs8 - fsw f25, 24*REGBYTES(sp) // Store fs9 - fsw f26, 25*REGBYTES(sp) // Store fs10 - fsw f27, 26*REGBYTES(sp) // Store fs11 +#if TX_CONTEXT_FP_ENABLED + TX_FP_STORE f8, TX_SOLICITED_FP_OFFSET(0)(sp) // Store fs0 + TX_FP_STORE f9, TX_SOLICITED_FP_OFFSET(1)(sp) // Store fs1 + TX_FP_STORE f18, TX_SOLICITED_FP_OFFSET(2)(sp) // Store fs2 + TX_FP_STORE f19, TX_SOLICITED_FP_OFFSET(3)(sp) // Store fs3 + TX_FP_STORE f20, TX_SOLICITED_FP_OFFSET(4)(sp) // Store fs4 + TX_FP_STORE f21, TX_SOLICITED_FP_OFFSET(5)(sp) // Store fs5 + TX_FP_STORE f22, TX_SOLICITED_FP_OFFSET(6)(sp) // Store fs6 + TX_FP_STORE f23, TX_SOLICITED_FP_OFFSET(7)(sp) // Store fs7 + TX_FP_STORE f24, TX_SOLICITED_FP_OFFSET(8)(sp) // Store fs8 + TX_FP_STORE f25, TX_SOLICITED_FP_OFFSET(9)(sp) // Store fs9 + TX_FP_STORE f26, TX_SOLICITED_FP_OFFSET(10)(sp) // Store fs10 + TX_FP_STORE f27, TX_SOLICITED_FP_OFFSET(11)(sp) // Store fs11 csrr t0, fcsr - STORE t0, 27*REGBYTES(sp) // Store fcsr -#elif defined(__riscv_float_abi_double) - fsd f8, 15*REGBYTES(sp) // Store fs0 - fsd f9, 16*REGBYTES(sp) // Store fs1 - fsd f18, 17*REGBYTES(sp) // Store fs2 - fsd f19, 18*REGBYTES(sp) // Store fs3 - fsd f20, 19*REGBYTES(sp) // Store fs4 - fsd f21, 20*REGBYTES(sp) // Store fs5 - fsd f22, 21*REGBYTES(sp) // Store fs6 - fsd f23, 22*REGBYTES(sp) // Store fs7 - fsd f24, 23*REGBYTES(sp) // Store fs8 - fsd f25, 24*REGBYTES(sp) // Store fs9 - fsd f26, 25*REGBYTES(sp) // Store fs10 - fsd f27, 26*REGBYTES(sp) // Store fs11 - csrr t0, fcsr - STORE t0, 27*REGBYTES(sp) // Store fcsr + STORE t0, TX_SOLICITED_FCSR_OFFSET(sp) // Store fcsr #endif STORE x0, 0(sp) // Solicited stack type diff --git a/port/threadx_smp/inc/tx_port.h b/port/threadx_smp/inc/tx_port.h index 1b0f0c2..a0729c2 100644 --- a/port/threadx_smp/inc/tx_port.h +++ b/port/threadx_smp/inc/tx_port.h @@ -77,6 +77,54 @@ #endif #define REGBYTES (1 << LOG_REGBYTES) +#define TX_CONTEXT_ALIGN(size) (((size) + 15) & -16) + +/* Keep the existing hard-float enable policy. Save the full hardware register + * width, even when the calling convention uses narrower floating-point values. + */ +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) +#define TX_CONTEXT_FP_ENABLED 1 +#if __riscv_flen == 64 +#define TX_FP_BYTES 8 +#define TX_FP_LOAD fld +#define TX_FP_STORE fsd +#elif __riscv_flen == 32 +#define TX_FP_BYTES 4 +#define TX_FP_LOAD flw +#define TX_FP_STORE fsw +#else +#error "Unsupported RISC-V floating-point register width" +#endif +#else +#define TX_CONTEXT_FP_ENABLED 0 +#define TX_FP_BYTES 0 +#endif + +/* Integer slots 0..30 contain the interrupt context; slot 31 is padding. + * Voluntary switches use slots 0..14; slot 15 is padding. Starting the FP + * areas at these boundaries aligns double registers on RV32 as well as RV64. + */ +#define TX_INTERRUPT_FP_BASE (32 * REGBYTES) +#define TX_SOLICITED_FP_BASE (16 * REGBYTES) +#define TX_INTERRUPT_FP_OFFSET(n) (TX_INTERRUPT_FP_BASE + (n) * TX_FP_BYTES) +/* Solicited FP indices: fs0, fs1, fs2, ... fs11 (not architectural numbers). */ +#define TX_SOLICITED_FP_OFFSET(n) (TX_SOLICITED_FP_BASE + (n) * TX_FP_BYTES) +#define TX_INTERRUPT_FCSR_OFFSET TX_INTERRUPT_FP_OFFSET(32) +#define TX_SOLICITED_FCSR_OFFSET TX_SOLICITED_FP_OFFSET(12) + +/* fcsr follows the FP registers and occupies one REGBYTES slot because + * it is accessed with integer LOAD/STORE. Round the complete frame up to + * 16 bytes so allocating or releasing it preserves stack alignment. Without + * FP support, the frame contains only the integer slots and their padding. + */ +#if TX_CONTEXT_FP_ENABLED +#define TX_INTERRUPT_FRAME_SIZE TX_CONTEXT_ALIGN(TX_INTERRUPT_FCSR_OFFSET + REGBYTES) +#define TX_SOLICITED_FRAME_SIZE TX_CONTEXT_ALIGN(TX_SOLICITED_FCSR_OFFSET + REGBYTES) +#else +#define TX_INTERRUPT_FRAME_SIZE TX_INTERRUPT_FP_BASE +#define TX_SOLICITED_FRAME_SIZE TX_SOLICITED_FP_BASE +#endif + #else /*not __ASSEMBLER__ */ /************* Define ThreadX SMP constants. *************/ diff --git a/port/threadx_smp/src/trap_entry.S b/port/threadx_smp/src/trap_entry.S index d7ae196..cf99576 100644 --- a/port/threadx_smp/src/trap_entry.S +++ b/port/threadx_smp/src/trap_entry.S @@ -62,11 +62,7 @@ .global trap_entry .extern _tx_thread_context_restore trap_entry: -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi sp, sp, -65*REGBYTES // Allocate space for all registers - with floating point enabled -#else - addi sp, sp, -32*REGBYTES // Allocate space for all registers - without floating point enabled -#endif + addi sp, sp, -TX_INTERRUPT_FRAME_SIZE STORE x1, 28*REGBYTES(sp) // Store RA, 28*REGBYTES(because call will override ra [ra is a calle register in riscv]) @@ -75,11 +71,11 @@ csrr a0, mcause csrr a1, mepc csrr a2, mtval - addi sp, sp, -8 + addi sp, sp, -16 // Keep the C handler stack aligned STORE ra, 0(sp) call trap_handler LOAD ra, 0(sp) - addi sp, sp, 8 + addi sp, sp, 16 call _tx_thread_context_restore // it will nerver return .weak trap_handler diff --git a/port/threadx_smp/src/tx_thread_context_restore.S b/port/threadx_smp/src/tx_thread_context_restore.S index 0335047..d236a05 100644 --- a/port/threadx_smp/src/tx_thread_context_restore.S +++ b/port/threadx_smp/src/tx_thread_context_restore.S @@ -95,51 +95,28 @@ _tx_thread_context_restore: interrupt. */ /* Recover floating point registers. */ -#if defined(__riscv_float_abi_single) - flw f0, 31*REGBYTES(sp) // Recover ft0 - flw f1, 32*REGBYTES(sp) // Recover ft1 - flw f2, 33*REGBYTES(sp) // Recover ft2 - flw f3, 34*REGBYTES(sp) // Recover ft3 - flw f4, 35*REGBYTES(sp) // Recover ft4 - flw f5, 36*REGBYTES(sp) // Recover ft5 - flw f6, 37*REGBYTES(sp) // Recover ft6 - flw f7, 38*REGBYTES(sp) // Recover ft7 - flw f10,41*REGBYTES(sp) // Recover fa0 - flw f11,42*REGBYTES(sp) // Recover fa1 - flw f12,43*REGBYTES(sp) // Recover fa2 - flw f13,44*REGBYTES(sp) // Recover fa3 - flw f14,45*REGBYTES(sp) // Recover fa4 - flw f15,46*REGBYTES(sp) // Recover fa5 - flw f16,47*REGBYTES(sp) // Recover fa6 - flw f17,48*REGBYTES(sp) // Recover fa7 - flw f28,59*REGBYTES(sp) // Recover ft8 - flw f29,60*REGBYTES(sp) // Recover ft9 - flw f30,61*REGBYTES(sp) // Recover ft10 - flw f31,62*REGBYTES(sp) // Recover ft11 - lw t0, 63*REGBYTES(sp) // Recover fcsr - csrw fcsr, t0 // -#elif defined(__riscv_float_abi_double) - fld f0, 31*REGBYTES(sp) // Recover ft0 - fld f1, 32*REGBYTES(sp) // Recover ft1 - fld f2, 33*REGBYTES(sp) // Recover ft2 - fld f3, 34*REGBYTES(sp) // Recover ft3 - fld f4, 35*REGBYTES(sp) // Recover ft4 - fld f5, 36*REGBYTES(sp) // Recover ft5 - fld f6, 37*REGBYTES(sp) // Recover ft6 - fld f7, 38*REGBYTES(sp) // Recover ft7 - fld f10,41*REGBYTES(sp) // Recover fa0 - fld f11,42*REGBYTES(sp) // Recover fa1 - fld f12,43*REGBYTES(sp) // Recover fa2 - fld f13,44*REGBYTES(sp) // Recover fa3 - fld f14,45*REGBYTES(sp) // Recover fa4 - fld f15,46*REGBYTES(sp) // Recover fa5 - fld f16,47*REGBYTES(sp) // Recover fa6 - fld f17,48*REGBYTES(sp) // Recover fa7 - fld f28,59*REGBYTES(sp) // Recover ft8 - fld f29,60*REGBYTES(sp) // Recover ft9 - fld f30,61*REGBYTES(sp) // Recover ft10 - fld f31,62*REGBYTES(sp) // Recover ft11 - LOAD t0, 63*REGBYTES(sp) // Recover fcsr +#if TX_CONTEXT_FP_ENABLED + TX_FP_LOAD f0, TX_INTERRUPT_FP_OFFSET(0)(sp) // Recover ft0 + TX_FP_LOAD f1, TX_INTERRUPT_FP_OFFSET(1)(sp) // Recover ft1 + TX_FP_LOAD f2, TX_INTERRUPT_FP_OFFSET(2)(sp) // Recover ft2 + TX_FP_LOAD f3, TX_INTERRUPT_FP_OFFSET(3)(sp) // Recover ft3 + TX_FP_LOAD f4, TX_INTERRUPT_FP_OFFSET(4)(sp) // Recover ft4 + TX_FP_LOAD f5, TX_INTERRUPT_FP_OFFSET(5)(sp) // Recover ft5 + TX_FP_LOAD f6, TX_INTERRUPT_FP_OFFSET(6)(sp) // Recover ft6 + TX_FP_LOAD f7, TX_INTERRUPT_FP_OFFSET(7)(sp) // Recover ft7 + TX_FP_LOAD f10, TX_INTERRUPT_FP_OFFSET(10)(sp) // Recover fa0 + TX_FP_LOAD f11, TX_INTERRUPT_FP_OFFSET(11)(sp) // Recover fa1 + TX_FP_LOAD f12, TX_INTERRUPT_FP_OFFSET(12)(sp) // Recover fa2 + TX_FP_LOAD f13, TX_INTERRUPT_FP_OFFSET(13)(sp) // Recover fa3 + TX_FP_LOAD f14, TX_INTERRUPT_FP_OFFSET(14)(sp) // Recover fa4 + TX_FP_LOAD f15, TX_INTERRUPT_FP_OFFSET(15)(sp) // Recover fa5 + TX_FP_LOAD f16, TX_INTERRUPT_FP_OFFSET(16)(sp) // Recover fa6 + TX_FP_LOAD f17, TX_INTERRUPT_FP_OFFSET(17)(sp) // Recover fa7 + TX_FP_LOAD f28, TX_INTERRUPT_FP_OFFSET(28)(sp) // Recover ft8 + TX_FP_LOAD f29, TX_INTERRUPT_FP_OFFSET(29)(sp) // Recover ft9 + TX_FP_LOAD f30, TX_INTERRUPT_FP_OFFSET(30)(sp) // Recover ft10 + TX_FP_LOAD f31, TX_INTERRUPT_FP_OFFSET(31)(sp) // Recover ft11 + LOAD t0, TX_INTERRUPT_FCSR_OFFSET(sp) // Recover fcsr csrw fcsr, t0 // #endif @@ -153,7 +130,7 @@ _tx_thread_context_restore: LOAD t0, 30*REGBYTES(sp) // Recover mepc csrw mepc, t0 // Setup mepc li t0, 0x1880 // Prepare MPIP -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) +#if TX_CONTEXT_FP_ENABLED li t1, 1<<13 or t0, t1, t0 #endif @@ -177,11 +154,7 @@ _tx_thread_context_restore: LOAD x30, 14*REGBYTES(sp) // Recover t5 LOAD x31, 13*REGBYTES(sp) // Recover t6 -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi sp, sp, 65*REGBYTES // Recover stack frame - with floating point enabled -#else - addi sp, sp, 32*REGBYTES // Recover stack frame - without floating point enabled -#endif + addi sp, sp, TX_INTERRUPT_FRAME_SIZE mret // Return to point of interrupt /* } */ @@ -218,51 +191,28 @@ _tx_thread_no_preempt_restore: LOAD sp, 2*REGBYTES(t1) // Switch back to thread's stack /* Recover floating point registers. */ -#if defined(__riscv_float_abi_single) - flw f0, 31*REGBYTES(sp) // Recover ft0 - flw f1, 32*REGBYTES(sp) // Recover ft1 - flw f2, 33*REGBYTES(sp) // Recover ft2 - flw f3, 34*REGBYTES(sp) // Recover ft3 - flw f4, 35*REGBYTES(sp) // Recover ft4 - flw f5, 36*REGBYTES(sp) // Recover ft5 - flw f6, 37*REGBYTES(sp) // Recover ft6 - flw f7, 38*REGBYTES(sp) // Recover ft7 - flw f10,41*REGBYTES(sp) // Recover fa0 - flw f11,42*REGBYTES(sp) // Recover fa1 - flw f12,43*REGBYTES(sp) // Recover fa2 - flw f13,44*REGBYTES(sp) // Recover fa3 - flw f14,45*REGBYTES(sp) // Recover fa4 - flw f15,46*REGBYTES(sp) // Recover fa5 - flw f16,47*REGBYTES(sp) // Recover fa6 - flw f17,48*REGBYTES(sp) // Recover fa7 - flw f28,59*REGBYTES(sp) // Recover ft8 - flw f29,60*REGBYTES(sp) // Recover ft9 - flw f30,61*REGBYTES(sp) // Recover ft10 - flw f31,62*REGBYTES(sp) // Recover ft11 - lw t0, 63*REGBYTES(sp) // Recover fcsr - csrw fcsr, t0 // -#elif defined(__riscv_float_abi_double) - fld f0, 31*REGBYTES(sp) // Recover ft0 - fld f1, 32*REGBYTES(sp) // Recover ft1 - fld f2, 33*REGBYTES(sp) // Recover ft2 - fld f3, 34*REGBYTES(sp) // Recover ft3 - fld f4, 35*REGBYTES(sp) // Recover ft4 - fld f5, 36*REGBYTES(sp) // Recover ft5 - fld f6, 37*REGBYTES(sp) // Recover ft6 - fld f7, 38*REGBYTES(sp) // Recover ft7 - fld f10,41*REGBYTES(sp) // Recover fa0 - fld f11,42*REGBYTES(sp) // Recover fa1 - fld f12,43*REGBYTES(sp) // Recover fa2 - fld f13,44*REGBYTES(sp) // Recover fa3 - fld f14,45*REGBYTES(sp) // Recover fa4 - fld f15,46*REGBYTES(sp) // Recover fa5 - fld f16,47*REGBYTES(sp) // Recover fa6 - fld f17,48*REGBYTES(sp) // Recover fa7 - fld f28,59*REGBYTES(sp) // Recover ft8 - fld f29,60*REGBYTES(sp) // Recover ft9 - fld f30,61*REGBYTES(sp) // Recover ft10 - fld f31,62*REGBYTES(sp) // Recover ft11 - LOAD t0, 63*REGBYTES(sp) // Recover fcsr +#if TX_CONTEXT_FP_ENABLED + TX_FP_LOAD f0, TX_INTERRUPT_FP_OFFSET(0)(sp) // Recover ft0 + TX_FP_LOAD f1, TX_INTERRUPT_FP_OFFSET(1)(sp) // Recover ft1 + TX_FP_LOAD f2, TX_INTERRUPT_FP_OFFSET(2)(sp) // Recover ft2 + TX_FP_LOAD f3, TX_INTERRUPT_FP_OFFSET(3)(sp) // Recover ft3 + TX_FP_LOAD f4, TX_INTERRUPT_FP_OFFSET(4)(sp) // Recover ft4 + TX_FP_LOAD f5, TX_INTERRUPT_FP_OFFSET(5)(sp) // Recover ft5 + TX_FP_LOAD f6, TX_INTERRUPT_FP_OFFSET(6)(sp) // Recover ft6 + TX_FP_LOAD f7, TX_INTERRUPT_FP_OFFSET(7)(sp) // Recover ft7 + TX_FP_LOAD f10, TX_INTERRUPT_FP_OFFSET(10)(sp) // Recover fa0 + TX_FP_LOAD f11, TX_INTERRUPT_FP_OFFSET(11)(sp) // Recover fa1 + TX_FP_LOAD f12, TX_INTERRUPT_FP_OFFSET(12)(sp) // Recover fa2 + TX_FP_LOAD f13, TX_INTERRUPT_FP_OFFSET(13)(sp) // Recover fa3 + TX_FP_LOAD f14, TX_INTERRUPT_FP_OFFSET(14)(sp) // Recover fa4 + TX_FP_LOAD f15, TX_INTERRUPT_FP_OFFSET(15)(sp) // Recover fa5 + TX_FP_LOAD f16, TX_INTERRUPT_FP_OFFSET(16)(sp) // Recover fa6 + TX_FP_LOAD f17, TX_INTERRUPT_FP_OFFSET(17)(sp) // Recover fa7 + TX_FP_LOAD f28, TX_INTERRUPT_FP_OFFSET(28)(sp) // Recover ft8 + TX_FP_LOAD f29, TX_INTERRUPT_FP_OFFSET(29)(sp) // Recover ft9 + TX_FP_LOAD f30, TX_INTERRUPT_FP_OFFSET(30)(sp) // Recover ft10 + TX_FP_LOAD f31, TX_INTERRUPT_FP_OFFSET(31)(sp) // Recover ft11 + LOAD t0, TX_INTERRUPT_FCSR_OFFSET(sp) // Recover fcsr csrw fcsr, t0 // #endif @@ -275,7 +225,7 @@ _tx_thread_no_preempt_restore: LOAD t0, 30*REGBYTES(sp) // Recover mepc csrw mepc, t0 // Setup mepc li t0, 0x1880 // Prepare MPIP -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) +#if TX_CONTEXT_FP_ENABLED li t1, 1<<13 or t0, t1, t0 #endif @@ -299,11 +249,7 @@ _tx_thread_no_preempt_restore: LOAD x30, 14*REGBYTES(sp) // Recover t5 LOAD x31, 13*REGBYTES(sp) // Recover t6 -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi sp, sp, 65*REGBYTES // Recover stack frame - with floating point enabled -#else - addi sp, sp, 32*REGBYTES // Recover stack frame - without floating point enabled -#endif + addi sp, sp, TX_INTERRUPT_FRAME_SIZE mret // Return to point of interrupt /* } @@ -318,32 +264,19 @@ _tx_thread_preempt_restore: STORE t3, 0(t0) // Store stack type /* Store floating point preserved registers. */ -#ifdef __riscv_float_abi_single - fsw f8, 39*REGBYTES(t0) // Store fs0 - fsw f9, 40*REGBYTES(t0) // Store fs1 - fsw f18, 49*REGBYTES(t0) // Store fs2 - fsw f19, 50*REGBYTES(t0) // Store fs3 - fsw f20, 51*REGBYTES(t0) // Store fs4 - fsw f21, 52*REGBYTES(t0) // Store fs5 - fsw f22, 53*REGBYTES(t0) // Store fs6 - fsw f23, 54*REGBYTES(t0) // Store fs7 - fsw f24, 55*REGBYTES(t0) // Store fs8 - fsw f25, 56*REGBYTES(t0) // Store fs9 - fsw f26, 57*REGBYTES(t0) // Store fs10 - fsw f27, 58*REGBYTES(t0) // Store fs11 -#elif defined(__riscv_float_abi_double) - fsd f8, 39*REGBYTES(t0) // Store fs0 - fsd f9, 40*REGBYTES(t0) // Store fs1 - fsd f18, 49*REGBYTES(t0) // Store fs2 - fsd f19, 50*REGBYTES(t0) // Store fs3 - fsd f20, 51*REGBYTES(t0) // Store fs4 - fsd f21, 52*REGBYTES(t0) // Store fs5 - fsd f22, 53*REGBYTES(t0) // Store fs6 - fsd f23, 54*REGBYTES(t0) // Store fs7 - fsd f24, 55*REGBYTES(t0) // Store fs8 - fsd f25, 56*REGBYTES(t0) // Store fs9 - fsd f26, 57*REGBYTES(t0) // Store fs10 - fsd f27, 58*REGBYTES(t0) // Store fs11 +#if TX_CONTEXT_FP_ENABLED + TX_FP_STORE f8, TX_INTERRUPT_FP_OFFSET(8)(t0) // Store fs0 + TX_FP_STORE f9, TX_INTERRUPT_FP_OFFSET(9)(t0) // Store fs1 + TX_FP_STORE f18, TX_INTERRUPT_FP_OFFSET(18)(t0) // Store fs2 + TX_FP_STORE f19, TX_INTERRUPT_FP_OFFSET(19)(t0) // Store fs3 + TX_FP_STORE f20, TX_INTERRUPT_FP_OFFSET(20)(t0) // Store fs4 + TX_FP_STORE f21, TX_INTERRUPT_FP_OFFSET(21)(t0) // Store fs5 + TX_FP_STORE f22, TX_INTERRUPT_FP_OFFSET(22)(t0) // Store fs6 + TX_FP_STORE f23, TX_INTERRUPT_FP_OFFSET(23)(t0) // Store fs7 + TX_FP_STORE f24, TX_INTERRUPT_FP_OFFSET(24)(t0) // Store fs8 + TX_FP_STORE f25, TX_INTERRUPT_FP_OFFSET(25)(t0) // Store fs9 + TX_FP_STORE f26, TX_INTERRUPT_FP_OFFSET(26)(t0) // Store fs10 + TX_FP_STORE f27, TX_INTERRUPT_FP_OFFSET(27)(t0) // Store fs11 #endif /* Store standard preserved registers. */ diff --git a/port/threadx_smp/src/tx_thread_context_save.S b/port/threadx_smp/src/tx_thread_context_save.S index 13b8d28..ca1d0f1 100644 --- a/port/threadx_smp/src/tx_thread_context_save.S +++ b/port/threadx_smp/src/tx_thread_context_save.S @@ -109,52 +109,29 @@ _tx_thread_context_save: STORE t0, 30*REGBYTES(sp) // Save it on the stack /* Save floating point scratch registers. */ -#if defined(__riscv_float_abi_single) - fsw f0, 31*REGBYTES(sp) // Store ft0 - fsw f1, 32*REGBYTES(sp) // Store ft1 - fsw f2, 33*REGBYTES(sp) // Store ft2 - fsw f3, 34*REGBYTES(sp) // Store ft3 - fsw f4, 35*REGBYTES(sp) // Store ft4 - fsw f5, 36*REGBYTES(sp) // Store ft5 - fsw f6, 37*REGBYTES(sp) // Store ft6 - fsw f7, 38*REGBYTES(sp) // Store ft7 - fsw f10,41*REGBYTES(sp) // Store fa0 - fsw f11,42*REGBYTES(sp) // Store fa1 - fsw f12,43*REGBYTES(sp) // Store fa2 - fsw f13,44*REGBYTES(sp) // Store fa3 - fsw f14,45*REGBYTES(sp) // Store fa4 - fsw f15,46*REGBYTES(sp) // Store fa5 - fsw f16,47*REGBYTES(sp) // Store fa6 - fsw f17,48*REGBYTES(sp) // Store fa7 - fsw f28,59*REGBYTES(sp) // Store ft8 - fsw f29,60*REGBYTES(sp) // Store ft9 - fsw f30,61*REGBYTES(sp) // Store ft10 - fsw f31,62*REGBYTES(sp) // Store ft11 +#if TX_CONTEXT_FP_ENABLED + TX_FP_STORE f0, TX_INTERRUPT_FP_OFFSET(0)(sp) // Store ft0 + TX_FP_STORE f1, TX_INTERRUPT_FP_OFFSET(1)(sp) // Store ft1 + TX_FP_STORE f2, TX_INTERRUPT_FP_OFFSET(2)(sp) // Store ft2 + TX_FP_STORE f3, TX_INTERRUPT_FP_OFFSET(3)(sp) // Store ft3 + TX_FP_STORE f4, TX_INTERRUPT_FP_OFFSET(4)(sp) // Store ft4 + TX_FP_STORE f5, TX_INTERRUPT_FP_OFFSET(5)(sp) // Store ft5 + TX_FP_STORE f6, TX_INTERRUPT_FP_OFFSET(6)(sp) // Store ft6 + TX_FP_STORE f7, TX_INTERRUPT_FP_OFFSET(7)(sp) // Store ft7 + TX_FP_STORE f10, TX_INTERRUPT_FP_OFFSET(10)(sp) // Store fa0 + TX_FP_STORE f11, TX_INTERRUPT_FP_OFFSET(11)(sp) // Store fa1 + TX_FP_STORE f12, TX_INTERRUPT_FP_OFFSET(12)(sp) // Store fa2 + TX_FP_STORE f13, TX_INTERRUPT_FP_OFFSET(13)(sp) // Store fa3 + TX_FP_STORE f14, TX_INTERRUPT_FP_OFFSET(14)(sp) // Store fa4 + TX_FP_STORE f15, TX_INTERRUPT_FP_OFFSET(15)(sp) // Store fa5 + TX_FP_STORE f16, TX_INTERRUPT_FP_OFFSET(16)(sp) // Store fa6 + TX_FP_STORE f17, TX_INTERRUPT_FP_OFFSET(17)(sp) // Store fa7 + TX_FP_STORE f28, TX_INTERRUPT_FP_OFFSET(28)(sp) // Store ft8 + TX_FP_STORE f29, TX_INTERRUPT_FP_OFFSET(29)(sp) // Store ft9 + TX_FP_STORE f30, TX_INTERRUPT_FP_OFFSET(30)(sp) // Store ft10 + TX_FP_STORE f31, TX_INTERRUPT_FP_OFFSET(31)(sp) // Store ft11 csrr t0, fcsr - STORE t0, 63*REGBYTES(sp) // Store fcsr -#elif defined(__riscv_float_abi_double) - fsd f0, 31*REGBYTES(sp) // Store ft0 - fsd f1, 32*REGBYTES(sp) // Store ft1 - fsd f2, 33*REGBYTES(sp) // Store ft2 - fsd f3, 34*REGBYTES(sp) // Store ft3 - fsd f4, 35*REGBYTES(sp) // Store ft4 - fsd f5, 36*REGBYTES(sp) // Store ft5 - fsd f6, 37*REGBYTES(sp) // Store ft6 - fsd f7, 38*REGBYTES(sp) // Store ft7 - fsd f10,41*REGBYTES(sp) // Store fa0 - fsd f11,42*REGBYTES(sp) // Store fa1 - fsd f12,43*REGBYTES(sp) // Store fa2 - fsd f13,44*REGBYTES(sp) // Store fa3 - fsd f14,45*REGBYTES(sp) // Store fa4 - fsd f15,46*REGBYTES(sp) // Store fa5 - fsd f16,47*REGBYTES(sp) // Store fa6 - fsd f17,48*REGBYTES(sp) // Store fa7 - fsd f28,59*REGBYTES(sp) // Store ft8 - fsd f29,60*REGBYTES(sp) // Store ft9 - fsd f30,61*REGBYTES(sp) // Store ft10 - fsd f31,62*REGBYTES(sp) // Store ft11 - csrr t0, fcsr - STORE t0, 63*REGBYTES(sp) // Store fcsr + STORE t0, TX_INTERRUPT_FCSR_OFFSET(sp) // Store fcsr #endif #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY @@ -197,52 +174,29 @@ _tx_thread_not_nested_save: STORE t0, 30*REGBYTES(sp) // Save it on the stack /* Save floating point scratch registers. */ -#if defined(__riscv_float_abi_single) - fsw f0, 31*REGBYTES(sp) // Store ft0 - fsw f1, 32*REGBYTES(sp) // Store ft1 - fsw f2, 33*REGBYTES(sp) // Store ft2 - fsw f3, 34*REGBYTES(sp) // Store ft3 - fsw f4, 35*REGBYTES(sp) // Store ft4 - fsw f5, 36*REGBYTES(sp) // Store ft5 - fsw f6, 37*REGBYTES(sp) // Store ft6 - fsw f7, 38*REGBYTES(sp) // Store ft7 - fsw f10,41*REGBYTES(sp) // Store fa0 - fsw f11,42*REGBYTES(sp) // Store fa1 - fsw f12,43*REGBYTES(sp) // Store fa2 - fsw f13,44*REGBYTES(sp) // Store fa3 - fsw f14,45*REGBYTES(sp) // Store fa4 - fsw f15,46*REGBYTES(sp) // Store fa5 - fsw f16,47*REGBYTES(sp) // Store fa6 - fsw f17,48*REGBYTES(sp) // Store fa7 - fsw f28,59*REGBYTES(sp) // Store ft8 - fsw f29,60*REGBYTES(sp) // Store ft9 - fsw f30,61*REGBYTES(sp) // Store ft10 - fsw f31,62*REGBYTES(sp) // Store ft11 +#if TX_CONTEXT_FP_ENABLED + TX_FP_STORE f0, TX_INTERRUPT_FP_OFFSET(0)(sp) // Store ft0 + TX_FP_STORE f1, TX_INTERRUPT_FP_OFFSET(1)(sp) // Store ft1 + TX_FP_STORE f2, TX_INTERRUPT_FP_OFFSET(2)(sp) // Store ft2 + TX_FP_STORE f3, TX_INTERRUPT_FP_OFFSET(3)(sp) // Store ft3 + TX_FP_STORE f4, TX_INTERRUPT_FP_OFFSET(4)(sp) // Store ft4 + TX_FP_STORE f5, TX_INTERRUPT_FP_OFFSET(5)(sp) // Store ft5 + TX_FP_STORE f6, TX_INTERRUPT_FP_OFFSET(6)(sp) // Store ft6 + TX_FP_STORE f7, TX_INTERRUPT_FP_OFFSET(7)(sp) // Store ft7 + TX_FP_STORE f10, TX_INTERRUPT_FP_OFFSET(10)(sp) // Store fa0 + TX_FP_STORE f11, TX_INTERRUPT_FP_OFFSET(11)(sp) // Store fa1 + TX_FP_STORE f12, TX_INTERRUPT_FP_OFFSET(12)(sp) // Store fa2 + TX_FP_STORE f13, TX_INTERRUPT_FP_OFFSET(13)(sp) // Store fa3 + TX_FP_STORE f14, TX_INTERRUPT_FP_OFFSET(14)(sp) // Store fa4 + TX_FP_STORE f15, TX_INTERRUPT_FP_OFFSET(15)(sp) // Store fa5 + TX_FP_STORE f16, TX_INTERRUPT_FP_OFFSET(16)(sp) // Store fa6 + TX_FP_STORE f17, TX_INTERRUPT_FP_OFFSET(17)(sp) // Store fa7 + TX_FP_STORE f28, TX_INTERRUPT_FP_OFFSET(28)(sp) // Store ft8 + TX_FP_STORE f29, TX_INTERRUPT_FP_OFFSET(29)(sp) // Store ft9 + TX_FP_STORE f30, TX_INTERRUPT_FP_OFFSET(30)(sp) // Store ft10 + TX_FP_STORE f31, TX_INTERRUPT_FP_OFFSET(31)(sp) // Store ft11 csrr t0, fcsr - STORE t0, 63*REGBYTES(sp) // Store fcsr -#elif defined(__riscv_float_abi_double) - fsd f0, 31*REGBYTES(sp) // Store ft0 - fsd f1, 32*REGBYTES(sp) // Store ft1 - fsd f2, 33*REGBYTES(sp) // Store ft2 - fsd f3, 34*REGBYTES(sp) // Store ft3 - fsd f4, 35*REGBYTES(sp) // Store ft4 - fsd f5, 36*REGBYTES(sp) // Store ft5 - fsd f6, 37*REGBYTES(sp) // Store ft6 - fsd f7, 38*REGBYTES(sp) // Store ft7 - fsd f10,41*REGBYTES(sp) // Store fa0 - fsd f11,42*REGBYTES(sp) // Store fa1 - fsd f12,43*REGBYTES(sp) // Store fa2 - fsd f13,44*REGBYTES(sp) // Store fa3 - fsd f14,45*REGBYTES(sp) // Store fa4 - fsd f15,46*REGBYTES(sp) // Store fa5 - fsd f16,47*REGBYTES(sp) // Store fa6 - fsd f17,48*REGBYTES(sp) // Store fa7 - fsd f28,59*REGBYTES(sp) // Store ft8 - fsd f29,60*REGBYTES(sp) // Store ft9 - fsd f30,61*REGBYTES(sp) // Store ft10 - fsd f31,62*REGBYTES(sp) // Store ft11 - csrr t0, fcsr - STORE t0, 63*REGBYTES(sp) // Store fcsr + STORE t0, TX_INTERRUPT_FCSR_OFFSET(sp) // Store fcsr #endif /* Save the current stack pointer in the thread's control block. */ @@ -281,9 +235,5 @@ _tx_thread_idle_system_save: /* } } */ -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi sp, sp, 65*REGBYTES // Recover stack frame - with floating point enabled -#else - addi sp, sp, 32*REGBYTES // Recover the reserved stack space -#endif + addi sp, sp, TX_INTERRUPT_FRAME_SIZE ret // Return to calling ISR diff --git a/port/threadx_smp/src/tx_thread_schedule.S b/port/threadx_smp/src/tx_thread_schedule.S index f1d5bf6..a386c5c 100644 --- a/port/threadx_smp/src/tx_thread_schedule.S +++ b/port/threadx_smp/src/tx_thread_schedule.S @@ -153,75 +153,41 @@ _execute_pointer_did_not_change: /* Determine if floating point registers need to be recovered. */ -#if defined(__riscv_float_abi_single) - flw f0, 31*REGBYTES(sp) // Recover ft0 - flw f1, 32*REGBYTES(sp) // Recover ft1 - flw f2, 33*REGBYTES(sp) // Recover ft2 - flw f3, 34*REGBYTES(sp) // Recover ft3 - flw f4, 35*REGBYTES(sp) // Recover ft4 - flw f5, 36*REGBYTES(sp) // Recover ft5 - flw f6, 37*REGBYTES(sp) // Recover ft6 - flw f7, 38*REGBYTES(sp) // Recover ft7 - flw f8, 39*REGBYTES(sp) // Recover fs0 - flw f9, 40*REGBYTES(sp) // Recover fs1 - flw f10,41*REGBYTES(sp) // Recover fa0 - flw f11,42*REGBYTES(sp) // Recover fa1 - flw f12,43*REGBYTES(sp) // Recover fa2 - flw f13,44*REGBYTES(sp) // Recover fa3 - flw f14,45*REGBYTES(sp) // Recover fa4 - flw f15,46*REGBYTES(sp) // Recover fa5 - flw f16,47*REGBYTES(sp) // Recover fa6 - flw f17,48*REGBYTES(sp) // Recover fa7 - flw f18,49*REGBYTES(sp) // Recover fs2 - flw f19,50*REGBYTES(sp) // Recover fs3 - flw f20,51*REGBYTES(sp) // Recover fs4 - flw f21,52*REGBYTES(sp) // Recover fs5 - flw f22,53*REGBYTES(sp) // Recover fs6 - flw f23,54*REGBYTES(sp) // Recover fs7 - flw f24,55*REGBYTES(sp) // Recover fs8 - flw f25,56*REGBYTES(sp) // Recover fs9 - flw f26,57*REGBYTES(sp) // Recover fs10 - flw f27,58*REGBYTES(sp) // Recover fs11 - flw f28,59*REGBYTES(sp) // Recover ft8 - flw f29,60*REGBYTES(sp) // Recover ft9 - flw f30,61*REGBYTES(sp) // Recover ft10 - flw f31,62*REGBYTES(sp) // Recover ft11 - LOAD t0, 63*REGBYTES(sp) // Recover fcsr +#if TX_CONTEXT_FP_ENABLED + TX_FP_LOAD f0, TX_INTERRUPT_FP_OFFSET(0)(sp) // Recover ft0 + TX_FP_LOAD f1, TX_INTERRUPT_FP_OFFSET(1)(sp) // Recover ft1 + TX_FP_LOAD f2, TX_INTERRUPT_FP_OFFSET(2)(sp) // Recover ft2 + TX_FP_LOAD f3, TX_INTERRUPT_FP_OFFSET(3)(sp) // Recover ft3 + TX_FP_LOAD f4, TX_INTERRUPT_FP_OFFSET(4)(sp) // Recover ft4 + TX_FP_LOAD f5, TX_INTERRUPT_FP_OFFSET(5)(sp) // Recover ft5 + TX_FP_LOAD f6, TX_INTERRUPT_FP_OFFSET(6)(sp) // Recover ft6 + TX_FP_LOAD f7, TX_INTERRUPT_FP_OFFSET(7)(sp) // Recover ft7 + TX_FP_LOAD f8, TX_INTERRUPT_FP_OFFSET(8)(sp) // Recover fs0 + TX_FP_LOAD f9, TX_INTERRUPT_FP_OFFSET(9)(sp) // Recover fs1 + TX_FP_LOAD f10, TX_INTERRUPT_FP_OFFSET(10)(sp) // Recover fa0 + TX_FP_LOAD f11, TX_INTERRUPT_FP_OFFSET(11)(sp) // Recover fa1 + TX_FP_LOAD f12, TX_INTERRUPT_FP_OFFSET(12)(sp) // Recover fa2 + TX_FP_LOAD f13, TX_INTERRUPT_FP_OFFSET(13)(sp) // Recover fa3 + TX_FP_LOAD f14, TX_INTERRUPT_FP_OFFSET(14)(sp) // Recover fa4 + TX_FP_LOAD f15, TX_INTERRUPT_FP_OFFSET(15)(sp) // Recover fa5 + TX_FP_LOAD f16, TX_INTERRUPT_FP_OFFSET(16)(sp) // Recover fa6 + TX_FP_LOAD f17, TX_INTERRUPT_FP_OFFSET(17)(sp) // Recover fa7 + TX_FP_LOAD f18, TX_INTERRUPT_FP_OFFSET(18)(sp) // Recover fs2 + TX_FP_LOAD f19, TX_INTERRUPT_FP_OFFSET(19)(sp) // Recover fs3 + TX_FP_LOAD f20, TX_INTERRUPT_FP_OFFSET(20)(sp) // Recover fs4 + TX_FP_LOAD f21, TX_INTERRUPT_FP_OFFSET(21)(sp) // Recover fs5 + TX_FP_LOAD f22, TX_INTERRUPT_FP_OFFSET(22)(sp) // Recover fs6 + TX_FP_LOAD f23, TX_INTERRUPT_FP_OFFSET(23)(sp) // Recover fs7 + TX_FP_LOAD f24, TX_INTERRUPT_FP_OFFSET(24)(sp) // Recover fs8 + TX_FP_LOAD f25, TX_INTERRUPT_FP_OFFSET(25)(sp) // Recover fs9 + TX_FP_LOAD f26, TX_INTERRUPT_FP_OFFSET(26)(sp) // Recover fs10 + TX_FP_LOAD f27, TX_INTERRUPT_FP_OFFSET(27)(sp) // Recover fs11 + TX_FP_LOAD f28, TX_INTERRUPT_FP_OFFSET(28)(sp) // Recover ft8 + TX_FP_LOAD f29, TX_INTERRUPT_FP_OFFSET(29)(sp) // Recover ft9 + TX_FP_LOAD f30, TX_INTERRUPT_FP_OFFSET(30)(sp) // Recover ft10 + TX_FP_LOAD f31, TX_INTERRUPT_FP_OFFSET(31)(sp) // Recover ft11 + LOAD t0, TX_INTERRUPT_FCSR_OFFSET(sp) // Recover fcsr csrw fcsr, t0 // -#elif defined(__riscv_float_abi_double) - fld f0, 31*REGBYTES(sp) // Recover ft0 - fld f1, 32*REGBYTES(sp) // Recover ft1 - fld f2, 33*REGBYTES(sp) // Recover ft2 - fld f3, 34*REGBYTES(sp) // Recover ft3 - fld f4, 35*REGBYTES(sp) // Recover ft4 - fld f5, 36*REGBYTES(sp) // Recover ft5 - fld f6, 37*REGBYTES(sp) // Recover ft6 - fld f7, 38*REGBYTES(sp) // Recover ft7 - fld f8, 39*REGBYTES(sp) // Recover fs0 - fld f9, 40*REGBYTES(sp) // Recover fs1 - fld f10,41*REGBYTES(sp) // Recover fa0 - fld f11,42*REGBYTES(sp) // Recover fa1 - fld f12,43*REGBYTES(sp) // Recover fa2 - fld f13,44*REGBYTES(sp) // Recover fa3 - fld f14,45*REGBYTES(sp) // Recover fa4 - fld f15,46*REGBYTES(sp) // Recover fa5 - fld f16,47*REGBYTES(sp) // Recover fa6 - fld f17,48*REGBYTES(sp) // Recover fa7 - fld f18,49*REGBYTES(sp) // Recover fs2 - fld f19,50*REGBYTES(sp) // Recover fs3 - fld f20,51*REGBYTES(sp) // Recover fs4 - fld f21,52*REGBYTES(sp) // Recover fs5 - fld f22,53*REGBYTES(sp) // Recover fs6 - fld f23,54*REGBYTES(sp) // Recover fs7 - fld f24,55*REGBYTES(sp) // Recover fs8 - fld f25,56*REGBYTES(sp) // Recover fs9 - fld f26,57*REGBYTES(sp) // Recover fs10 - fld f27,58*REGBYTES(sp) // Recover fs11 - fld f28,59*REGBYTES(sp) // Recover ft8 - fld f29,60*REGBYTES(sp) // Recover ft9 - fld f30,61*REGBYTES(sp) // Recover ft10 - fld f31,62*REGBYTES(sp) // Recover ft11 - LOAD t0, 63*REGBYTES(sp) // Recover fcsr #endif /* Recover standard registers. */ @@ -229,7 +195,7 @@ _execute_pointer_did_not_change: LOAD t0, 30*REGBYTES(sp) // Recover mepc csrw mepc, t0 // Store mepc li t0, 0x1880 // Prepare MPIP -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) +#if TX_CONTEXT_FP_ENABLED li t1, 1<<13 or t0, t1, t0 #endif @@ -264,44 +230,25 @@ _execute_pointer_did_not_change: LOAD x30, 14*REGBYTES(sp) // Recover t5 LOAD x31, 13*REGBYTES(sp) // Recover t6 -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi sp, sp, 65*REGBYTES // Recover stack frame - with floating point registers -#else - addi sp, sp, 32*REGBYTES // Recover stack frame - without floating point registers -#endif + addi sp, sp, TX_INTERRUPT_FRAME_SIZE mret // Return to point of interrupt _tx_thread_synch_return: -#if defined(__riscv_float_abi_single) - flw f8, 15*REGBYTES(sp) // Recover fs0 - flw f9, 16*REGBYTES(sp) // Recover fs1 - flw f18,17*REGBYTES(sp) // Recover fs2 - flw f19,18*REGBYTES(sp) // Recover fs3 - flw f20,19*REGBYTES(sp) // Recover fs4 - flw f21,20*REGBYTES(sp) // Recover fs5 - flw f22,21*REGBYTES(sp) // Recover fs6 - flw f23,22*REGBYTES(sp) // Recover fs7 - flw f24,23*REGBYTES(sp) // Recover fs8 - flw f25,24*REGBYTES(sp) // Recover fs9 - flw f26,25*REGBYTES(sp) // Recover fs10 - flw f27,26*REGBYTES(sp) // Recover fs11 - LOAD t0, 27*REGBYTES(sp) // Recover fcsr - csrw fcsr, t0 // -#elif defined(__riscv_float_abi_double) - fld f8, 15*REGBYTES(sp) // Recover fs0 - fld f9, 16*REGBYTES(sp) // Recover fs1 - fld f18,17*REGBYTES(sp) // Recover fs2 - fld f19,18*REGBYTES(sp) // Recover fs3 - fld f20,19*REGBYTES(sp) // Recover fs4 - fld f21,20*REGBYTES(sp) // Recover fs5 - fld f22,21*REGBYTES(sp) // Recover fs6 - fld f23,22*REGBYTES(sp) // Recover fs7 - fld f24,23*REGBYTES(sp) // Recover fs8 - fld f25,24*REGBYTES(sp) // Recover fs9 - fld f26,25*REGBYTES(sp) // Recover fs10 - fld f27,26*REGBYTES(sp) // Recover fs11 - LOAD t0, 27*REGBYTES(sp) // Recover fcsr +#if TX_CONTEXT_FP_ENABLED + TX_FP_LOAD f8, TX_SOLICITED_FP_OFFSET(0)(sp) // Recover fs0 + TX_FP_LOAD f9, TX_SOLICITED_FP_OFFSET(1)(sp) // Recover fs1 + TX_FP_LOAD f18, TX_SOLICITED_FP_OFFSET(2)(sp) // Recover fs2 + TX_FP_LOAD f19, TX_SOLICITED_FP_OFFSET(3)(sp) // Recover fs3 + TX_FP_LOAD f20, TX_SOLICITED_FP_OFFSET(4)(sp) // Recover fs4 + TX_FP_LOAD f21, TX_SOLICITED_FP_OFFSET(5)(sp) // Recover fs5 + TX_FP_LOAD f22, TX_SOLICITED_FP_OFFSET(6)(sp) // Recover fs6 + TX_FP_LOAD f23, TX_SOLICITED_FP_OFFSET(7)(sp) // Recover fs7 + TX_FP_LOAD f24, TX_SOLICITED_FP_OFFSET(8)(sp) // Recover fs8 + TX_FP_LOAD f25, TX_SOLICITED_FP_OFFSET(9)(sp) // Recover fs9 + TX_FP_LOAD f26, TX_SOLICITED_FP_OFFSET(10)(sp) // Recover fs10 + TX_FP_LOAD f27, TX_SOLICITED_FP_OFFSET(11)(sp) // Recover fs11 + LOAD t0, TX_SOLICITED_FCSR_OFFSET(sp) // Recover fcsr csrw fcsr, t0 // #endif @@ -323,11 +270,7 @@ _tx_thread_synch_return: LOAD x27, 1*REGBYTES(sp) // Recover s11 LOAD t0, 14*REGBYTES(sp) // Recover mstatus csrw mstatus, t0 // Store mstatus, enables interrupt -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi sp, sp, 29*REGBYTES // Recover stack frame -#else - addi sp, sp, 16*REGBYTES // Recover stack frame -#endif + addi sp, sp, TX_SOLICITED_FRAME_SIZE synch_return_exit_label: ret // Return to thread diff --git a/port/threadx_smp/src/tx_thread_stack_build.S b/port/threadx_smp/src/tx_thread_stack_build.S index 8eef6dd..eb9e6c1 100644 --- a/port/threadx_smp/src/tx_thread_stack_build.S +++ b/port/threadx_smp/src/tx_thread_stack_build.S @@ -67,9 +67,10 @@ .global _tx_thread_stack_build _tx_thread_stack_build: - /* Build a fake interrupt frame. The form of the fake interrupt stack - on the RISC-V should look like the following after it is built: - Reg Index + /* Build a fake interrupt frame using this port's inc/tx_context_layout.h, + included through tx_port.h. Integer slot indices below are multiplied + by REGBYTES to obtain byte offsets from the saved stack pointer. + Reg Integer slot Stack Top: 1 0 Interrupt stack frame type x27 1 Initial s11 x26 2 Initial s10 @@ -101,122 +102,37 @@ _tx_thread_stack_build: x1 28 Initial ra -- 29 reserved mepc 30 Initial mepc -If floating point support: - f0 31 Inital ft0 - f1 32 Inital ft1 - f2 33 Inital ft2 - f3 34 Inital ft3 - f4 35 Inital ft4 - f5 36 Inital ft5 - f6 37 Inital ft6 - f7 38 Inital ft7 - f8 39 Inital fs0 - f9 40 Inital fs1 - f10 41 Inital fa0 - f11 42 Inital fa1 - f12 43 Inital fa2 - f13 44 Inital fa3 - f14 45 Inital fa4 - f15 46 Inital fa5 - f16 47 Inital fa6 - f17 48 Inital fa7 - f18 49 Inital fs2 - f19 50 Inital fs3 - f20 51 Inital fs4 - f21 52 Inital fs5 - f22 53 Inital fs6 - f23 54 Inital fs7 - f24 55 Inital fs8 - f25 56 Inital fs9 - f26 57 Inital fs10 - f27 58 Inital fs11 - f28 59 Inital ft8 - f29 60 Inital ft9 - f30 61 Inital ft10 - f31 62 Inital ft11 - fscr 63 Inital fscr + -- 31 Alignment padding - Stack Bottom: (higher memory address) */ + With FP support, f0..f31 follow at TX_INTERRUPT_FP_BASE. Each register + occupies TX_FP_BYTES bytes; fN is at TX_INTERRUPT_FP_OFFSET(N). The + fcsr slot is at TX_INTERRUPT_FCSR_OFFSET and occupies REGBYTES bytes. + Trailing padding rounds the frame size up to a multiple of 16 bytes. + Without FP support, the frame ends after integer slot 31. + + Stack Bottom: saved stack pointer + TX_INTERRUPT_FRAME_SIZE + (higher memory address) */ LOAD t0, 4*REGBYTES(a0) // Pickup end of stack area andi t0, t0, -16 // Ensure 16-byte alignment /* Actually build the stack frame. */ -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi t0, t0, -65*REGBYTES -#else - addi t0, t0, -32*REGBYTES // Allocate space for the stack frame -#endif + addi t0, t0, -TX_INTERRUPT_FRAME_SIZE + /* Clear the whole frame, including both halves of RV32D FP slots. */ + mv t1, t0 + addi t2, t0, TX_INTERRUPT_FRAME_SIZE +.Lclear_initial_context: + STORE x0, 0(t1) + addi t1, t1, REGBYTES + bltu t1, t2, .Lclear_initial_context + li t1, 1 // Build stack type STORE t1, 0*REGBYTES(t0) // Place stack type on the top - STORE x0, 1*REGBYTES(t0) // Initial s11 - STORE x0, 2*REGBYTES(t0) // Initial s10 - STORE x0, 3*REGBYTES(t0) // Initial s9 - STORE x0, 4*REGBYTES(t0) // Initial s8 - STORE x0, 5*REGBYTES(t0) // Initial s7 - STORE x0, 6*REGBYTES(t0) // Initial s6 - STORE x0, 7*REGBYTES(t0) // Initial s5 - STORE x0, 8*REGBYTES(t0) // Initial s4 - STORE x0, 9*REGBYTES(t0) // Initial s3 - STORE x0, 10*REGBYTES(t0) // Initial s2 - STORE x0, 11*REGBYTES(t0) // Initial s1 - STORE x0, 12*REGBYTES(t0) // Initial s0 - STORE x0, 13*REGBYTES(t0) // Initial t6 - STORE x0, 14*REGBYTES(t0) // Initial t5 - STORE x0, 15*REGBYTES(t0) // Initial t4 - STORE x0, 16*REGBYTES(t0) // Initial t3 - STORE x0, 17*REGBYTES(t0) // Initial t2 - STORE x0, 18*REGBYTES(t0) // Initial t1 - STORE x0, 19*REGBYTES(t0) // Initial t0 - STORE x0, 20*REGBYTES(t0) // Initial a7 - STORE x0, 21*REGBYTES(t0) // Initial a6 - STORE x0, 22*REGBYTES(t0) // Initial a5 - STORE x0, 23*REGBYTES(t0) // Initial a4 - STORE x0, 24*REGBYTES(t0) // Initial a3 - STORE x0, 25*REGBYTES(t0) // Initial a2 - STORE x0, 26*REGBYTES(t0) // Initial a1 - STORE x0, 27*REGBYTES(t0) // Initial a0 - STORE x0, 28*REGBYTES(t0) // Initial ra STORE a1, 30*REGBYTES(t0) // Initial mepc -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - STORE x0, 31*REGBYTES(t0) // Inital ft0 - STORE x0, 32*REGBYTES(t0) // Inital ft1 - STORE x0, 33*REGBYTES(t0) // Inital ft2 - STORE x0, 34*REGBYTES(t0) // Inital ft3 - STORE x0, 35*REGBYTES(t0) // Inital ft4 - STORE x0, 36*REGBYTES(t0) // Inital ft5 - STORE x0, 37*REGBYTES(t0) // Inital ft6 - STORE x0, 38*REGBYTES(t0) // Inital ft7 - STORE x0, 39*REGBYTES(t0) // Inital fs0 - STORE x0, 40*REGBYTES(t0) // Inital fs1 - STORE x0, 41*REGBYTES(t0) // Inital fa0 - STORE x0, 42*REGBYTES(t0) // Inital fa1 - STORE x0, 43*REGBYTES(t0) // Inital fa2 - STORE x0, 44*REGBYTES(t0) // Inital fa3 - STORE x0, 45*REGBYTES(t0) // Inital fa4 - STORE x0, 46*REGBYTES(t0) // Inital fa5 - STORE x0, 47*REGBYTES(t0) // Inital fa6 - STORE x0, 48*REGBYTES(t0) // Inital fa7 - STORE x0, 49*REGBYTES(t0) // Inital fs2 - STORE x0, 50*REGBYTES(t0) // Inital fs3 - STORE x0, 51*REGBYTES(t0) // Inital fs4 - STORE x0, 52*REGBYTES(t0) // Inital fs5 - STORE x0, 53*REGBYTES(t0) // Inital fs6 - STORE x0, 54*REGBYTES(t0) // Inital fs7 - STORE x0, 55*REGBYTES(t0) // Inital fs8 - STORE x0, 56*REGBYTES(t0) // Inital fs9 - STORE x0, 57*REGBYTES(t0) // Inital fs10 - STORE x0, 58*REGBYTES(t0) // Inital fs11 - STORE x0, 59*REGBYTES(t0) // Inital ft8 - STORE x0, 60*REGBYTES(t0) // Inital ft9 - STORE x0, 61*REGBYTES(t0) // Inital ft10 - STORE x0, 62*REGBYTES(t0) // Inital ft11 - csrr a1, fcsr // Read fcsr and use it for initial value for each thread - STORE a1, 63*REGBYTES(t0) // Initial fscr - STORE x0, 64*REGBYTES(t0) // Reserved word (0) -#else - STORE x0, 31*REGBYTES(t0) // Reserved word (0) +#if TX_CONTEXT_FP_ENABLED + csrr a1, fcsr + STORE a1, TX_INTERRUPT_FCSR_OFFSET(t0) // Initial fcsr #endif /* Setup stack pointer. */ diff --git a/port/threadx_smp/src/tx_thread_system_return.S b/port/threadx_smp/src/tx_thread_system_return.S index f752462..2e23386 100644 --- a/port/threadx_smp/src/tx_thread_system_return.S +++ b/port/threadx_smp/src/tx_thread_system_return.S @@ -69,43 +69,24 @@ _tx_thread_system_return: /* Save minimal context on the stack. */ -#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - addi sp, sp, -29*REGBYTES // Allocate space on the stack - with floating point enabled -#else - addi sp, sp, -16*REGBYTES // Allocate space on the stack - without floating point enabled -#endif + addi sp, sp, -TX_SOLICITED_FRAME_SIZE /* Store floating point preserved registers. */ -#if defined(__riscv_float_abi_single) - fsw f8, 15*REGBYTES(sp) // Store fs0 - fsw f9, 16*REGBYTES(sp) // Store fs1 - fsw f18, 17*REGBYTES(sp) // Store fs2 - fsw f19, 18*REGBYTES(sp) // Store fs3 - fsw f20, 19*REGBYTES(sp) // Store fs4 - fsw f21, 20*REGBYTES(sp) // Store fs5 - fsw f22, 21*REGBYTES(sp) // Store fs6 - fsw f23, 22*REGBYTES(sp) // Store fs7 - fsw f24, 23*REGBYTES(sp) // Store fs8 - fsw f25, 24*REGBYTES(sp) // Store fs9 - fsw f26, 25*REGBYTES(sp) // Store fs10 - fsw f27, 26*REGBYTES(sp) // Store fs11 +#if TX_CONTEXT_FP_ENABLED + TX_FP_STORE f8, TX_SOLICITED_FP_OFFSET(0)(sp) // Store fs0 + TX_FP_STORE f9, TX_SOLICITED_FP_OFFSET(1)(sp) // Store fs1 + TX_FP_STORE f18, TX_SOLICITED_FP_OFFSET(2)(sp) // Store fs2 + TX_FP_STORE f19, TX_SOLICITED_FP_OFFSET(3)(sp) // Store fs3 + TX_FP_STORE f20, TX_SOLICITED_FP_OFFSET(4)(sp) // Store fs4 + TX_FP_STORE f21, TX_SOLICITED_FP_OFFSET(5)(sp) // Store fs5 + TX_FP_STORE f22, TX_SOLICITED_FP_OFFSET(6)(sp) // Store fs6 + TX_FP_STORE f23, TX_SOLICITED_FP_OFFSET(7)(sp) // Store fs7 + TX_FP_STORE f24, TX_SOLICITED_FP_OFFSET(8)(sp) // Store fs8 + TX_FP_STORE f25, TX_SOLICITED_FP_OFFSET(9)(sp) // Store fs9 + TX_FP_STORE f26, TX_SOLICITED_FP_OFFSET(10)(sp) // Store fs10 + TX_FP_STORE f27, TX_SOLICITED_FP_OFFSET(11)(sp) // Store fs11 csrr t0, fcsr - STORE t0, 27*REGBYTES(sp) // Store fcsr -#elif defined(__riscv_float_abi_double) - fsd f8, 15*REGBYTES(sp) // Store fs0 - fsd f9, 16*REGBYTES(sp) // Store fs1 - fsd f18, 17*REGBYTES(sp) // Store fs2 - fsd f19, 18*REGBYTES(sp) // Store fs3 - fsd f20, 19*REGBYTES(sp) // Store fs4 - fsd f21, 20*REGBYTES(sp) // Store fs5 - fsd f22, 21*REGBYTES(sp) // Store fs6 - fsd f23, 22*REGBYTES(sp) // Store fs7 - fsd f24, 23*REGBYTES(sp) // Store fs8 - fsd f25, 24*REGBYTES(sp) // Store fs9 - fsd f26, 25*REGBYTES(sp) // Store fs10 - fsd f27, 26*REGBYTES(sp) // Store fs11 - csrr t0, fcsr - STORE t0, 27*REGBYTES(sp) // Store fcsr + STORE t0, TX_SOLICITED_FCSR_OFFSET(sp) // Store fcsr #endif STORE x0, 0(sp) // Solicited stack type