diff options
| author | Frédéric Desbiens <[email protected]> | 2026-06-08 10:01:32 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-06-08 10:01:32 +0200 |
| commit | 87ab09cce305eb9cd4aacac4e8c62af72f665bff (patch) | |
| tree | dd062ebbea5235d1921c64b396bf7e4ce79e9e15 /ports/risc-v64/gnu/src | |
| parent | 9ab0cf9683f832cdb48e2099533a5b06a3afcd64 (diff) | |
| parent | 730b61874bc5cf40768987605ae5187fde0fa1e2 (diff) | |
Merge pull request #544 from eclipse-threadx/devv6.5.1.202602_rel
Merging changes for the v.6.5.1.202602 release
Diffstat (limited to 'ports/risc-v64/gnu/src')
| -rw-r--r-- | ports/risc-v64/gnu/src/tx_thread_context_restore.S | 218 | ||||
| -rw-r--r-- | ports/risc-v64/gnu/src/tx_thread_context_save.S | 85 | ||||
| -rw-r--r-- | ports/risc-v64/gnu/src/tx_thread_interrupt_control.S | 19 | ||||
| -rw-r--r-- | ports/risc-v64/gnu/src/tx_thread_schedule.S | 137 | ||||
| -rw-r--r-- | ports/risc-v64/gnu/src/tx_thread_stack_build.S | 52 | ||||
| -rw-r--r-- | ports/risc-v64/gnu/src/tx_thread_system_return.S | 56 | ||||
| -rw-r--r-- | ports/risc-v64/gnu/src/tx_timer_interrupt.S | 8 |
7 files changed, 518 insertions, 57 deletions
diff --git a/ports/risc-v64/gnu/src/tx_thread_context_restore.S b/ports/risc-v64/gnu/src/tx_thread_context_restore.S index 6aae3981..cebc8a06 100644 --- a/ports/risc-v64/gnu/src/tx_thread_context_restore.S +++ b/ports/risc-v64/gnu/src/tx_thread_context_restore.S @@ -63,7 +63,11 @@ _tx_thread_context_restore: /* Lockout interrupts. */ +#ifdef TX_RISCV_SMODE + csrci sstatus, 0x02 // Disable interrupts (SIE bit 1) +#else csrci mstatus, 0x08 // Disable interrupts (MIE bit 3) +#endif #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY call _tx_execution_isr_exit // Call the ISR execution exit function @@ -74,9 +78,9 @@ _tx_thread_context_restore: { */ la t0, _tx_thread_system_state // Pickup addr of nested interrupt count - ld t1, 0(t0) // Pickup nested interrupt count + lw t1, 0(t0) // Pickup nested interrupt count addi t1, t1, -1 // Decrement the nested interrupt counter - sd t1, 0(t0) // Store new nested count + sw t1, 0(t0) // Store new nested count beqz t1, _tx_thread_not_nested_restore // If 0, not nested restore /* Interrupts are nested. */ @@ -133,6 +137,34 @@ _tx_thread_context_restore: csrw fcsr, t0 #endif +#if defined(__riscv_vector) + /* Recover vector registers v0-v31 */ +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) + addi t1, sp, 64*8 +#else + addi t1, sp, 31*8 +#endif + addi t2, t1, 4*8 + vsetvli t3, zero, e8, m8, ta, ma + vle8.v v0, (t2) // Recover v0 ~ v7 + add t2, t2, t3 + vle8.v v8, (t2) // Recover v8 ~ v15 + add t2, t2, t3 + vle8.v v16, (t2) // Recover v16 ~ v23 + add t2, t2, t3 + vle8.v v24, (t2) // Recover v24 ~ v31 + add t2, t2, t3 + + /* Recover vector CSRs */ + ld t2, 0*8(t1) + ld t3, 1*8(t1) + ld t4, 2*8(t1) + vsetvl zero, t4, t3 + csrw vstart, t2 + ld t4, 3*8(t1) + csrw vcsr, t4 +#endif + /* Recover standard registers. */ /* Restore registers, @@ -140,31 +172,46 @@ _tx_thread_context_restore: Also skip the saved registers since they have been restored by any function we called, except s0 since we use it ourselves. */ - ld t0, 30*8(sp) // Recover mepc + ld t0, 30*8(sp) // Recover exception PC +#ifdef TX_RISCV_SMODE + csrw sepc, t0 // Setup sepc + + /* Compose sstatus via read/modify/write to avoid clobbering unrelated bits. + Set SPIE and restore SPP to Supervisor, preserve other fields. */ + + csrr t1, sstatus + li t4, ~0x122 // Clear mask for SPP/SPIE/SIE + and t1, t1, t4 + li t3, 0x120 // Set SPP=Supervisor(0x100) + SPIE(0x20) so sret re-enables SIE + or t1, t1, t3 + +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) + li t0, 0x6000 // Set FS=Dirty (bits 14:13) for FP state + or t1, t1, t0 +#endif + csrw sstatus, t1 // Update sstatus safely +#else csrw mepc, t0 // Setup mepc /* Compose mstatus via read/modify/write to avoid clobbering unrelated bits. Set MPIE and restore MPP to Machine, preserve other fields. */ csrr t1, mstatus + li t2, 0x1880 // Set MPP(0x1800) | MPIE(0x80) - /* Clear MPP/MPIE/MIE bits in t1 then set desired values. */ - - li t2, 0x1888 // MPP(0x1800) | MPIE(0x80) | MIE(0x08) - li t3, 0x1800 // Set MPP to Machine mode (bits 12:11) - - /* Construct new mstatus in t1: clear mask bits, set MPP/MPIE and optionally FP bit, - preserve everything except the bits we will modify. */ - - li t4, ~0x1888 // Clear mask for MPP/MPIE/MIE - and t1, t1, t4 - or t1, t1, t3 + or t1, t1, t2 // MPP and MPIE are now set. All other bits are preserved + andi t1, t1, ~0x8 // Clear MIE, Hardware will restore it from MPIE #if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) li t0, 0x2000 // Set FS bits (bits 14:13 to 01) for FP state or t1, t1, t0 #endif +#if defined(__riscv_vector) + li t0, 0x0200 // Set VS bits (bits 10:9 to 01) for vector state + or t1, t1, t0 +#endif csrw mstatus, t1 // Update mstatus safely +#endif ld ra, 28*8(sp) // Recover return address ld t0, 19*8(sp) // Recover t0 @@ -189,7 +236,26 @@ _tx_thread_context_restore: #else addi sp, sp, 32*8 // Recover stack frame - without floating point enabled #endif + +#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 + 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 + add sp, sp, t1 // Recover vector stack frame + + ld t1, 18*8(t0) // Recover t1 + ld t0, 19*8(t0) // Recover t0 +#endif +#ifdef TX_RISCV_SMODE + sret // Return to point of interrupt +#else mret // Return to point of interrupt +#endif /* } */ _tx_thread_not_nested_restore: @@ -217,7 +283,7 @@ _tx_thread_no_preempt_restore: /* Pickup the saved stack pointer. */ /* sp = _tx_thread_current_ptr -> tx_thread_stack_ptr; */ - ld sp, 16(t1) // Switch back to thread's stack + ld sp, 8(t1) // Switch back to thread's stack /* Recover floating point registers. */ #if defined(__riscv_float_abi_single) @@ -268,29 +334,80 @@ _tx_thread_no_preempt_restore: csrw fcsr, t0 // Restore fcsr #endif +#if defined(__riscv_vector) + /* Recover vector registers v0-v31 */ +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) + addi t1, sp, 64*8 +#else + addi t1, sp, 31*8 +#endif + addi t2, t1, 4*8 + vsetvli t3, zero, e8, m8, ta, ma + vle8.v v0, (t2) // Recover v0 ~ v7 + add t2, t2, t3 + vle8.v v8, (t2) // Recover v8 ~ v15 + add t2, t2, t3 + vle8.v v16, (t2) // Recover v16 ~ v23 + add t2, t2, t3 + vle8.v v24, (t2) // Recover v24 ~ v31 + add t2, t2, t3 + + /* Recover vector CSRs */ + ld t2, 0*8(t1) + ld t3, 1*8(t1) + ld t4, 2*8(t1) + vsetvl zero, t4, t3 + csrw vstart, t2 + ld t4, 3*8(t1) + csrw vcsr, t4 +#endif + /* Recover the saved context and return to the point of interrupt. */ /* Recover standard registers. */ /* Restore registers, Skip global pointer because that does not change */ - ld t0, 30*8(sp) // Recover mepc - csrw mepc, t0 // Setup mepc + ld t0, 30*8(sp) // Recover exception PC +#ifdef TX_RISCV_SMODE + csrw sepc, t0 // Setup sepc - /* Compose mstatus via read/modify/write to avoid clobbering unrelated bits. */ + /* Compose sstatus via read/modify/write to avoid clobbering unrelated bits. */ - csrr t1, mstatus - li t2, 0x1888 // MPP(0x1800) | MPIE(0x80) | MIE(0x08) - li t3, 0x1800 // Set MPP to Machine mode - li t4, ~0x1888 // Clear mask for MPP/MPIE/MIE + csrr t1, sstatus + li t4, ~0x122 // Clear mask for SPP/SPIE/SIE and t1, t1, t4 + li t3, 0x120 // Set SPP=Supervisor(0x100) + SPIE(0x20) so sret re-enables SIE or t1, t1, t3 #if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) + li t0, 0x6000 // Set FS=Dirty (bits 14:13) for FP state + or t1, t1, t0 +#endif + csrw sstatus, t1 // Update sstatus safely +#else + csrw mepc, t0 // Setup mepc + + + /* Compose mstatus via read/modify/write to avoid clobbering unrelated bits. + Set MPIE and restore MPP to Machine, preserve other fields. */ + + csrr t1, mstatus + li t2, 0x1880 // Set MPP(0x1800) | MPIE(0x80) + + or t1, t1, t2 // MPP and MPIE are now set. All other bits are preserved + andi t1, t1, ~0x8 // Clear MIE, Hardware will restore it from MPIE + +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) li t0, 0x2000 // Set FS bits for FP state or t1, t1, t0 #endif +#if defined(__riscv_vector) + li t0, 0x0200 // Set VS bits (bits 10:9 to 01) for vector state + or t1, t1, t0 +#endif csrw mstatus, t1 // Update mstatus safely +#endif ld ra, 28*8(sp) // Recover return address ld t0, 19*8(sp) // Recover t0 @@ -315,7 +432,26 @@ _tx_thread_no_preempt_restore: #else addi sp, sp, 32*8 // Recover stack frame - without floating point enabled #endif + +#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 + 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 + add sp, sp, t1 // Recover vector stack frame + + ld t1, 18*8(t0) // Recover t1 + ld t0, 19*8(t0) // Recover t0 +#endif +#ifdef TX_RISCV_SMODE + sret // Return to point of interrupt +#else mret // Return to point of interrupt +#endif /* } else @@ -324,7 +460,7 @@ _tx_thread_preempt_restore: /* Instead of directly activating the thread again, ensure we save the entire stack frame by saving the remaining registers. */ - ld t0, 16(t1) // Pickup thread's stack pointer + ld t0, 8(t1) // Pickup thread's stack pointer ori t3, zero, 1 // Build interrupt stack type sd t3, 0(t0) // Store stack type @@ -357,6 +493,36 @@ _tx_thread_preempt_restore: fsd f27, 58*8(t0) // Store fs11 #endif +#if defined(__riscv_vector) + /* Store vector registers and CSRs */ +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) + addi t1, t0, 64*8 +#else + addi t1, t0, 31*8 +#endif + /* Store vector CSRs */ + csrr t2, vstart // Store vstart + sd t2, 0*8(t1) + csrr t2, vtype // Store vtype + sd t2, 1*8(t1) + csrr t2, vl // Store vl + sd t2, 2*8(t1) + csrr t2, vcsr // Store vcsr + sd t2, 3*8(t1) + + /* Store vector registers v0-v31 */ + addi t2, t1, 4*8 + vsetvli t3, zero, e8, m8, ta, ma + vse8.v v0, 0(t2) // Store v0 ~ v7 + add t2, t2, t3 + vse8.v v8, 0(t2) // Store v8 ~ v15 + add t2, t2, t3 + vse8.v v16, 0(t2) // Store v16 ~ v23 + add t2, t2, t3 + vse8.v v24, 0(t2) // Store v24 ~ v31 + add t2, t2, t3 +#endif + /* Store standard preserved registers. */ sd x9, 11*8(t0) // Store s1 @@ -377,14 +543,14 @@ _tx_thread_preempt_restore: { */ la t0, _tx_timer_time_slice // Pickup time slice variable address - ld t2, 0(t0) // Pickup time slice + lw t2, 0(t0) // Pickup time slice beqz t2, _tx_thread_dont_save_ts // If 0, skip time slice processing /* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice _tx_timer_time_slice = 0; */ - sd t2, 48(t1) // Save current time slice - sd x0, 0(t0) // Clear global time slice + sw t2, 36(t1) // Save current time slice + sw x0, 0(t0) // Clear global time slice /* } */ 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 df6f2c9a..7935bfee 100644 --- a/ports/risc-v64/gnu/src/tx_thread_context_save.S +++ b/ports/risc-v64/gnu/src/tx_thread_context_save.S @@ -94,7 +94,11 @@ _tx_thread_context_save: sd t4, 15*8(sp) // Store t4 sd t5, 14*8(sp) // Store t5 sd t6, 13*8(sp) // Store t6 +#ifdef TX_RISCV_SMODE + csrr t0, sepc // Load exception program counter +#else csrr t0, mepc // Load exception program counter +#endif sd t0, 30*8(sp) // Save it on the stack /* Save floating point scratch registers if floating point is enabled. */ @@ -146,6 +150,36 @@ _tx_thread_context_save: sd t0, 63*8(sp) // Store fcsr #endif +#if defined(__riscv_vector) + /* Store vector registers and CSRs */ +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) + addi t1, sp, 64*8 +#else + addi t1, sp, 31*8 +#endif + /* Store vector CSRs */ + csrr t2, vstart // Store vstart + sd t2, 0*8(t1) + csrr t2, vtype // Store vtype + sd t2, 1*8(t1) + csrr t2, vl // Store vl + sd t2, 2*8(t1) + csrr t2, vcsr // Store vcsr + sd t2, 3*8(t1) + + /* Store vector registers v0-v31 */ + addi t2, t1, 4*8 + vsetvli t3, zero, e8, m8, ta, ma + vse8.v v0, 0(t2) // Store v0 ~ v7 + add t2, t2, t3 + vse8.v v8, 0(t2) // Store v8 ~ v15 + add t2, t2, t3 + vse8.v v16, 0(t2) // Store v16 ~ v23 + add t2, t2, t3 + vse8.v v24, 0(t2) // Store v24 ~ v31 + add t2, t2, t3 +#endif + #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY call _tx_execution_isr_enter // Call the ISR execution enter function #endif @@ -184,7 +218,11 @@ _tx_thread_not_nested_save: sd t5, 14*8(sp) // Store t5 sd t6, 13*8(sp) // Store t6 +#ifdef TX_RISCV_SMODE + csrr t1, sepc // Load exception program counter +#else csrr t1, mepc // Load exception program counter +#endif sd t1, 30*8(sp) // Save it on the stack /* Save floating point scratch registers if floating point is enabled. */ @@ -236,6 +274,36 @@ _tx_thread_not_nested_save: sd t0, 63*8(sp) // Store fcsr #endif +#if defined(__riscv_vector) + /* Store vector registers and CSRs */ +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) + addi t1, sp, 64*8 +#else + addi t1, sp, 31*8 +#endif + /* Store vector CSRs */ + csrr t2, vstart // Store vstart + sd t2, 0*8(t1) + csrr t2, vtype // Store vtype + sd t2, 1*8(t1) + csrr t2, vl // Store vl + sd t2, 2*8(t1) + csrr t2, vcsr // Store vcsr + sd t2, 3*8(t1) + + /* Store vector registers v0-v31 */ + addi t2, t1, 4*8 + vsetvli t3, zero, e8, m8, ta, ma + vse8.v v0, 0(t2) // Store v0 ~ v7 + add t2, t2, t3 + vse8.v v8, 0(t2) // Store v8 ~ v15 + add t2, t2, t3 + vse8.v v16, 0(t2) // Store v16 ~ v23 + add t2, t2, t3 + vse8.v v24, 0(t2) // Store v24 ~ v31 + add t2, t2, t3 +#endif + /* Save the current stack pointer in the thread's control block. */ /* _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; */ @@ -244,7 +312,7 @@ _tx_thread_not_nested_save: la t1, _tx_thread_current_ptr // Pickup current thread pointer address ld t1, 0(t1) // Pickup current thread pointer - sd sp, 16(t1) // Save stack pointer + sd sp, 8(t1) // Save stack pointer #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY /* _tx_execution_isr_enter is called with thread stack pointer */ @@ -275,4 +343,19 @@ _tx_thread_idle_system_save: #else addi sp, sp, 32*8 // Recover the reserved stack space #endif + +#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 + 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 + add sp, sp, t1 // Recover vector stack frame + + ld t1, 18*8(t0) // Recover t1 + ld t0, 19*8(t0) // Recover t0 +#endif ret // Return to calling ISR diff --git a/ports/risc-v64/gnu/src/tx_thread_interrupt_control.S b/ports/risc-v64/gnu/src/tx_thread_interrupt_control.S index dfcb6b47..b43d9558 100644 --- a/ports/risc-v64/gnu/src/tx_thread_interrupt_control.S +++ b/ports/risc-v64/gnu/src/tx_thread_interrupt_control.S @@ -59,20 +59,25 @@ .global _tx_thread_interrupt_control _tx_thread_interrupt_control: /* Pickup current interrupt lockout posture. */ - /* old_mstatus = mstatus; */ +#ifdef TX_RISCV_SMODE + csrr t0, sstatus + mv t1, t0 // Save original sstatus for return + li t2, ~0x02 // Build mask to clear SIE (bit 1) + and t0, t0, t2 // Clear SIE bit + andi a0, a0, 0x02 // Mask incoming to only SIE bit + or t0, t0, a0 // Set requested SIE state + csrw sstatus, t0 + andi a0, t1, 0x02 // Return original SIE bit +#else csrr t0, mstatus mv t1, t0 // Save original mstatus for return - - /* Apply the new interrupt posture while preserving unrelated mstatus bits. */ - /* Only modify the MIE bit (bit 3) */ - /* mstatus = (mstatus & ~MIE) | (new_posture & MIE); */ - li t2, ~0x08 // Build mask to clear MIE and t0, t0, t2 // Clear MIE bit - and a0, a0, 0x08 // Mask incoming to only MIE bit + andi a0, a0, 0x08 // Mask incoming to only MIE bit or t0, t0, a0 // Set requested MIE state csrw mstatus, t0 andi a0, t1, 0x08 // Return original MIE bit +#endif ret /* } */ diff --git a/ports/risc-v64/gnu/src/tx_thread_schedule.S b/ports/risc-v64/gnu/src/tx_thread_schedule.S index d3332896..860adf0b 100644 --- a/ports/risc-v64/gnu/src/tx_thread_schedule.S +++ b/ports/risc-v64/gnu/src/tx_thread_schedule.S @@ -62,7 +62,11 @@ _tx_thread_schedule: /* Enable interrupts. */ +#ifdef TX_RISCV_SMODE + csrsi sstatus, 0x02 // Enable interrupts (SIE bit 1) +#else csrsi mstatus, 0x08 // Enable interrupts (MIE bit 3) +#endif /* Wait for a thread to execute. */ /* do @@ -94,7 +98,11 @@ _tx_thread_schedule_loop: /* Yes! We have a thread to execute. Lockout interrupts and transfer control to it. */ +#ifdef TX_RISCV_SMODE + csrci sstatus, 0x02 // Lockout interrupts +#else csrci mstatus, 0x08 // Lockout interrupts +#endif /* Setup the current thread pointer. */ /* _tx_thread_current_ptr = _tx_thread_execute_ptr; */ @@ -105,10 +113,10 @@ _tx_thread_schedule_loop: /* Increment the run count for this thread. */ /* _tx_thread_current_ptr -> tx_thread_run_count++; */ - ld t2, 8(t1) // Pickup run count - ld t3, 48(t1) // Pickup time slice value + lw t2, 4(t1) // Pickup run count + lw t3, 36(t1) // Pickup time slice value addi t2, t2, 1 // Increment run count - sd t2, 8(t1) // Store new run count + sw t2, 4(t1) // Store new run count /* Setup time-slice, if present. */ /* _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; */ @@ -118,8 +126,8 @@ _tx_thread_schedule_loop: /* Switch to the thread's stack. */ /* SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr; */ - ld sp, 16(t1) // Switch to thread's stack - sd t3, 0(t2) // Store new time-slice + ld sp, 8(t1) // Switch to thread's stack + sw t3, 0(t2) // Store new time-slice #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY @@ -206,16 +214,71 @@ _tx_thread_schedule_loop: csrw fcsr, t0 // Restore fcsr #endif +#if defined(__riscv_vector) + /* Recover vector registers v0-v31 */ +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) + addi t1, sp, 64*8 +#else + addi t1, sp, 31*8 +#endif + addi t2, t1, 4*8 + vsetvli t3, zero, e8, m8, ta, ma + vle8.v v0, (t2) // Recover v0 ~ v7 + add t2, t2, t3 + vle8.v v8, (t2) // Recover v8 ~ v15 + add t2, t2, t3 + vle8.v v16, (t2) // Recover v16 ~ v23 + add t2, t2, t3 + vle8.v v24, (t2) // Recover v24 ~ v31 + add t2, t2, t3 + + /* Recover vector CSRs */ + ld t2, 0*8(t1) + ld t3, 1*8(t1) + ld t4, 2*8(t1) + vsetvl zero, t4, t3 + csrw vstart, t2 + ld t4, 3*8(t1) + csrw vcsr, t4 +#endif + /* Recover standard registers. */ - ld t0, 30*8(sp) // Recover mepc + ld t0, 30*8(sp) // Recover mepc/sepc +#ifdef TX_RISCV_SMODE + csrw sepc, t0 // Store sepc + + /* Read/modify/write sstatus to preserve SUM, MXR, UXL, FS, etc. + Only touch SPP, SPIE, SIE — the bits SRET consumes. */ + csrr t0, sstatus + li t1, ~0x122 // Clear mask: SIE(1) | SPIE(5) | SPP(8) + and t0, t0, t1 + li t1, 0x120 // Set SPP=Supervisor(0x100) | SPIE(0x20) + or t0, t0, t1 +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) + li t1, 0x6000 // Set FS=Dirty (bits 14:13) + or t0, t0, t1 +#endif + csrw sstatus, t0 // Update sstatus safely +#else csrw mepc, t0 // Store mepc - li t0, 0x1880 // Prepare mstatus: MPP=Machine(0x1800) | MPIE(0x80) + + /* Read/modify/write mstatus — same principle as S-mode path. */ + csrr t0, mstatus + li t1, ~0x1888 // Clear mask: MIE(3) | MPIE(7) | MPP(11:12) + and t0, t0, t1 + li t1, 0x1880 // Set MPP=Machine(0x1800) | MPIE(0x80) + or t0, t0, t1 #if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) - li t1, 0x2000 // Set FS bits for FP state + li t1, 0x6000 // Set FS=Dirty (bits 14:13) + or t0, t0, t1 +#endif +#if defined(__riscv_vector) + li t1, 0x0200 // Set VS bits (bits 10:9 to 01) for vector state or t0, t0, t1 #endif csrw mstatus, t0 // Set mstatus +#endif ld ra, 28*8(sp) // Recover return address ld t0, 19*8(sp) // Recover t0 @@ -251,7 +314,25 @@ _tx_thread_schedule_loop: #else addi sp, sp, 32*8 // Recover stack frame - without floating point registers #endif +#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 + 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 + add sp, sp, t1 // Recover vector stack frame + + ld t1, 18*8(t0) // Recover t1 + ld t0, 19*8(t0) // Recover t0 +#endif +#ifdef TX_RISCV_SMODE + sret // Return to point of interrupt +#else mret // Return to point of interrupt +#endif _tx_thread_synch_return: @@ -287,6 +368,34 @@ _tx_thread_synch_return: csrw fcsr, t0 // #endif +#if defined(__riscv_vector) + /* Recover vector registers v0-v31 */ +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) + addi t1, sp, 28*8 +#else + addi t1, sp, 15*8 +#endif + addi t2, t1, 4*8 + vsetvli t3, zero, e8, m8, ta, ma + vle8.v v0, (t2) // Recover v0 ~ v7 + add t2, t2, t3 + vle8.v v8, (t2) // Recover v8 ~ v15 + add t2, t2, t3 + vle8.v v16, (t2) // Recover v16 ~ v23 + add t2, t2, t3 + vle8.v v24, (t2) // Recover v24 ~ v31 + add t2, t2, t3 + + /* Recover vector CSRs */ + ld t2, 0*8(t1) + ld t3, 1*8(t1) + ld t4, 2*8(t1) + vsetvl zero, t4, t3 + csrw vstart, t2 + ld t4, 3*8(t1) + csrw vcsr, t4 +#endif + /* Recover standard preserved registers. */ /* Recover standard registers. */ @@ -303,13 +412,23 @@ _tx_thread_synch_return: ld s9, 3*8(sp) // Recover s9 ld s10, 2*8(sp) // Recover s10 ld s11, 1*8(sp) // Recover s11 - ld t0, 14*8(sp) // Recover mstatus + ld t0, 14*8(sp) // Recover status register +#ifdef TX_RISCV_SMODE + csrw sstatus, t0 // Store sstatus, enables interrupt +#else csrw mstatus, t0 // Store mstatus, enables interrupt +#endif #if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) addi sp, sp, 29*8 // Recover stack frame #else addi sp, sp, 16*8 // Recover stack frame #endif +#if defined(__riscv_vector) + 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 + add sp, sp, t1 // Recover vector stack frame +#endif ret // Return to thread /* } */ diff --git a/ports/risc-v64/gnu/src/tx_thread_stack_build.S b/ports/risc-v64/gnu/src/tx_thread_stack_build.S index 8663a6f1..86cab4f0 100644 --- a/ports/risc-v64/gnu/src/tx_thread_stack_build.S +++ b/ports/risc-v64/gnu/src/tx_thread_stack_build.S @@ -128,10 +128,19 @@ If floating point support: f30 61 Inital ft10 f31 62 Inital ft11 fscr 63 Inital fscr +If vector extension support: + vstart 64 Initial vstart + vtype 65 Initial vtype + vl 66 Initial vl + vcsr 67 Initial vcsr + v0 68 Initial v0 + v1 69 Initial v1 + ... + v31 99 Initial v31 Stack Bottom: (higher memory address) */ - ld t0, 32(a0) // Pickup end of stack area + ld t0, 24(a0) // Pickup end of stack area li t1, ~15 // Build 16-byte alignment mask and t0, t0, t1 // Make sure 16-byte alignment @@ -142,6 +151,17 @@ If floating point support: #else addi t0, t0, -32*8 // Allocate space for the stack frame #endif + +#if defined(__riscv_vector) + /* Vector extension support: calculate space based on vlenb */ + csrr t4, vlenb // Get vector register byte length + slli t4, t4, 5 // Multiply by 32 (number of vector registers) + addi t4, t4, 4*8 // Add vector CSR space: vstart, vtype, vl, vcsr + sub t0, t0, t4 // Allocate vector space for the stack frame +#else + li t4, 0 +#endif + li t1, 1 // Build stack type sd t1, 0*8(t0) // Place stack type on the top sd zero, 1*8(t0) // Initial s11 @@ -172,7 +192,7 @@ If floating point support: sd zero, 26*8(t0) // Initial a1 sd zero, 27*8(t0) // Initial a0 sd zero, 28*8(t0) // Initial ra - sd a1, 30*8(t0) // Initial mepc (thread entry point) + 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 sd zero, 32*8(t0) // Initial ft1 @@ -208,14 +228,36 @@ If floating point support: sd zero, 62*8(t0) // Initial ft11 csrr a1, fcsr // Read fcsr for initial value sd a1, 63*8(t0) // Initial fcsr - sd zero, 64*8(t0) // Reserved word (0) +#endif + +#if defined(__riscv_vector) + /* Clear vector register space */ +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) + addi t2, t0, 64*8 // t2 = start of vector registers +#else + addi t2, t0, 31*8 // t2 = start of vector registers +#endif + add t3, t2, t4 // t3 = end of vector registers + +vector_clear_loop: + beq t2, t3, vector_clear_done // Done if reached end + sd zero, 0(t2) // Clear 8 bytes + addi t2, t2, 8 // Move to next 8 bytes + j vector_clear_loop + +vector_clear_done: +#endif + + add t2, t0, t4 +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) + sd zero, 64*8(t2) // Reserved word (0) #else - sd zero, 31*8(t0) // Reserved word (0) + sd zero, 31*8(t2) // Reserved word (0) #endif /* Setup stack pointer. */ /* thread_ptr -> tx_thread_stack_ptr = t0; */ - sd t0, 16(a0) // Save stack pointer in thread's + sd t0, 8(a0) // Save stack pointer in thread's ret // control block and return /* } */ diff --git a/ports/risc-v64/gnu/src/tx_thread_system_return.S b/ports/risc-v64/gnu/src/tx_thread_system_return.S index 4e954ebe..583b3f3e 100644 --- a/ports/risc-v64/gnu/src/tx_thread_system_return.S +++ b/ports/risc-v64/gnu/src/tx_thread_system_return.S @@ -68,6 +68,12 @@ _tx_thread_system_return: #else addi sp, sp, -16*8 // Allocate space on the stack - without floating point enabled #endif +#if defined(__riscv_vector) + 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 + sub sp, sp, t1 // Allocate vector space on the stack +#endif /* Store floating point preserved registers. */ #if defined(__riscv_float_abi_single) @@ -102,6 +108,36 @@ _tx_thread_system_return: sd t0, 27*8(sp) // Store fcsr #endif +#if defined(__riscv_vector) + /* Store vector registers and CSRs */ +#if defined(__riscv_float_abi_single) || defined(__riscv_float_abi_double) + addi t1, sp, 28*8 +#else + addi t1, sp, 15*8 +#endif + /* Store vector CSRs */ + csrr t2, vstart // Store vstart + sd t2, 0*8(t1) + csrr t2, vtype // Store vtype + sd t2, 1*8(t1) + csrr t2, vl // Store vl + sd t2, 2*8(t1) + csrr t2, vcsr // Store vcsr + sd t2, 3*8(t1) + + /* Store vector registers v0-v31 */ + addi t2, t1, 4*8 + vsetvli t3, zero, e8, m8, ta, ma + vse8.v v0, 0(t2) // Store v0 ~ v7 + add t2, t2, t3 + vse8.v v8, 0(t2) // Store v8 ~ v15 + add t2, t2, t3 + vse8.v v16, 0(t2) // Store v16 ~ v23 + add t2, t2, t3 + vse8.v v24, 0(t2) // Store v24 ~ v31 + add t2, t2, t3 +#endif + sd zero, 0(sp) // Solicited stack type sd ra, 13*8(sp) // Save return address sd s0, 12*8(sp) // Save s0 @@ -116,6 +152,15 @@ _tx_thread_system_return: sd s9, 3*8(sp) // Save s9 sd s10, 2*8(sp) // Save s10 sd s11, 1*8(sp) // Save s11 +#ifdef TX_RISCV_SMODE + csrr t0, sstatus // Pickup sstatus + sd t0, 14*8(sp) // Save sstatus + + + /* Lockout interrupts. will be enabled in _tx_thread_schedule */ + + csrci sstatus, 0x02 // Disable interrupts (SIE bit 1) +#else csrr t0, mstatus // Pickup mstatus sd t0, 14*8(sp) // Save mstatus @@ -123,6 +168,7 @@ _tx_thread_system_return: /* Lockout interrupts. will be enabled in _tx_thread_schedule */ csrci mstatus, 0x08 // Disable interrupts (MIE bit 3) +#endif #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY @@ -137,15 +183,15 @@ _tx_thread_system_return: /* _tx_thread_current_ptr -> tx_thread_stack_ptr = SP; SP = _tx_thread_system_stack_ptr; */ - sd sp, 16(t1) // Save stack pointer - ld sp, 0(t2) // Switch to system stack + sd sp, 8(t1) // Save stack pointer + ld sp, 0(t2) // Switch to system stack /* Determine if the time-slice is active. */ /* if (_tx_timer_time_slice) { */ la t4, _tx_timer_time_slice // Pickup time slice variable addr - ld t3, 0(t4) // Pickup time slice value + lw t3, 0(t4) // Pickup time slice value la t2, _tx_thread_schedule // Pickup address of scheduling loop beqz t3, _tx_thread_dont_save_ts // If no time-slice, don't save it @@ -153,8 +199,8 @@ _tx_thread_system_return: /* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; _tx_timer_time_slice = 0; */ - sd t3, 48(t1) // Save current time-slice for thread - sd zero, 0(t4) // Clear time-slice variable + sw t3, 36(t1) // Save current time-slice for thread + sw zero, 0(t4) // Clear time-slice variable /* } */ _tx_thread_dont_save_ts: diff --git a/ports/risc-v64/gnu/src/tx_timer_interrupt.S b/ports/risc-v64/gnu/src/tx_timer_interrupt.S index 02b70461..53e572f3 100644 --- a/ports/risc-v64/gnu/src/tx_timer_interrupt.S +++ b/ports/risc-v64/gnu/src/tx_timer_interrupt.S @@ -66,11 +66,11 @@ _tx_timer_interrupt: /* _tx_timer_system_clock++; */ la t0, _tx_timer_system_clock // Pickup address of system clock - ld t1, 0(t0) // Pickup system clock + lw t1, 0(t0) // Pickup system clock la t2, _tx_timer_time_slice // Pickup address of time slice - ld t3, 0(t2) // Pickup time slice + lw t3, 0(t2) // Pickup time slice addi t1, t1, 1 // Increment system clock - sd t1, 0(t0) // Store new system clock + sw t1, 0(t0) // Store new system clock li t6, 0 // Clear local expired flag /* Test for time-slice expiration. */ @@ -83,7 +83,7 @@ _tx_timer_interrupt: /* Decrement the time_slice. */ /* _tx_timer_time_slice--; */ - sd t3, 0(t2) // Store new time slice + sw t3, 0(t2) // Store new time slice /* Check for expiration. */ /* if (_tx_timer_time_slice == 0) */ |
