summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshuta.lst <[email protected]>2026-03-04 10:51:20 +0800
committershuta.lst <[email protected]>2026-04-07 11:41:33 +0800
commit2f1fc5291827ee1b4279237646a2bc808a299896 (patch)
tree1861850e672b492b3dc274a4bb2c2f5a0aeb75bb
parent0c92f48d500c12240dd11af1e3a66b51a7c6a926 (diff)
RISC-V64 arch. port support RVV Extension;
-rw-r--r--ports/risc-v64/gnu/inc/tx_port.h12
-rw-r--r--ports/risc-v64/gnu/src/tx_thread_context_restore.S124
-rw-r--r--ports/risc-v64/gnu/src/tx_thread_context_save.S75
-rw-r--r--ports/risc-v64/gnu/src/tx_thread_schedule.S80
-rw-r--r--ports/risc-v64/gnu/src/tx_thread_stack_build.S46
-rw-r--r--ports/risc-v64/gnu/src/tx_thread_system_return.S36
6 files changed, 369 insertions, 4 deletions
diff --git a/ports/risc-v64/gnu/inc/tx_port.h b/ports/risc-v64/gnu/inc/tx_port.h
index ed985072..b146529b 100644
--- a/ports/risc-v64/gnu/inc/tx_port.h
+++ b/ports/risc-v64/gnu/inc/tx_port.h
@@ -105,7 +105,11 @@ typedef unsigned short USHORT;
thread creation is less than this value, the thread create call will return an error. */
#ifndef TX_MINIMUM_STACK
-#define TX_MINIMUM_STACK 1024 /* Minimum stack size for this port */
+#if defined(__riscv_vector)
+#define TX_MINIMUM_STACK (1024 + 16448) /* Minimum stack size for this port */
+#else
+#define TX_MINIMUM_STACK 1024 /* Minimum stack size for this port */
+#endif
#endif
@@ -113,7 +117,11 @@ typedef unsigned short USHORT;
if TX_TIMER_PROCESS_IN_ISR is not defined. */
#ifndef TX_TIMER_THREAD_STACK_SIZE
-#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
+#if defined(__riscv_vector)
+#define TX_TIMER_THREAD_STACK_SIZE (1024 + 16448) /* Default timer thread stack size */
+#else
+#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
+#endif
#endif
#ifndef TX_TIMER_THREAD_PRIORITY
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 1080e617..7abd6651 100644
--- a/ports/risc-v64/gnu/src/tx_thread_context_restore.S
+++ b/ports/risc-v64/gnu/src/tx_thread_context_restore.S
@@ -138,6 +138,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,
@@ -169,6 +197,10 @@ _tx_thread_context_restore:
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
ld ra, 28*8(sp) // Recover return address
@@ -194,6 +226,21 @@ _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
mret // Return to point of interrupt
/* } */
@@ -273,6 +320,34 @@ _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. */
@@ -295,6 +370,10 @@ _tx_thread_no_preempt_restore:
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
ld ra, 28*8(sp) // Recover return address
@@ -320,6 +399,21 @@ _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
mret // Return to point of interrupt
/* }
@@ -362,6 +456,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
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 b9aa13c9..5e2b2592 100644
--- a/ports/risc-v64/gnu/src/tx_thread_context_save.S
+++ b/ports/risc-v64/gnu/src/tx_thread_context_save.S
@@ -151,6 +151,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
@@ -241,6 +271,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; */
@@ -280,4 +340,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_schedule.S b/ports/risc-v64/gnu/src/tx_thread_schedule.S
index 2618e98b..947d288d 100644
--- a/ports/risc-v64/gnu/src/tx_thread_schedule.S
+++ b/ports/risc-v64/gnu/src/tx_thread_schedule.S
@@ -211,6 +211,34 @@ _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
@@ -220,6 +248,10 @@ _tx_thread_schedule_loop:
li t1, 0x2000 // Set FS bits for FP state
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
ld ra, 28*8(sp) // Recover return address
@@ -256,6 +288,20 @@ _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
mret // Return to point of interrupt
_tx_thread_synch_return:
@@ -292,6 +338,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. */
@@ -315,6 +389,12 @@ _tx_thread_synch_return:
#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 eecfbfec..4dcc30bf 100644
--- a/ports/risc-v64/gnu/src/tx_thread_stack_build.S
+++ b/ports/risc-v64/gnu/src/tx_thread_stack_build.S
@@ -133,6 +133,15 @@ 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) */
@@ -147,6 +156,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
@@ -213,9 +233,31 @@ 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. */
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 b7dc9f3a..2c7a2c01 100644
--- a/ports/risc-v64/gnu/src/tx_thread_system_return.S
+++ b/ports/risc-v64/gnu/src/tx_thread_system_return.S
@@ -73,6 +73,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)
@@ -107,6 +113,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