Update demo RISCV qemu demo to check the vector context save (#1334)

Demo: RISC-V_RV32_QEMU_VIRT_GCC: Add a test for vector registers
This commit is contained in:
Jonathan Cubides
2025-03-31 17:38:39 +02:00
committed by GitHub
parent 881305dcb8
commit 2625a12c04
7 changed files with 531 additions and 11 deletions

View File

@ -63,7 +63,7 @@ For the RVA23 build:
```
$ qemu-system-riscv64 -nographic -machine virt -net none -chardev stdio,id=con,mux=on \
-serial chardev:con -mon chardev=con,mode=readline -bios none -smp 4 \
-s --kernel build/gcc/output/RTOSDemo.elf
-cpu rv64,zba=true,zbb=true,v=true,vlen=256,vext_spec=v1.0,rvv_ta_all_1s=true,rvv_ma_all_1s=true -s --kernel build/gcc/output/RTOSDemo.elf
```

View File

@ -14,11 +14,10 @@ GCC_VERSION = $(shell $(CC) --version | grep ^$(CC) | sed 's/^.* //g' | awk -F.
GCC_VERSION_NEED_ZICSR = "110100"
ifeq ($(RVA23),1)
# For the time being, we don't include the vector extensions.
MARCH = rv64imafdc_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa_zicclsm_za64rs_zihintpause_zic64b_zicbom_zicbop_zicboz_zfhmin_zkt_zihintntl_zawrs
MARCH = rv64imafdcv_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa_zicclsm_za64rs_zihintpause_zic64b_zicbom_zicbop_zicboz_zfhmin_zkt_zvfhmin_zvbb_zvkt_zihintntl_zawrs
MABI = lp64d
MCMODEL = medany
CFLAGS+=-DconfigENABLE_FPU=1
CFLAGS+=-DconfigENABLE_FPU=1 -DconfigENABLE_VPU=1
$(info Using RVA23 build)
else
ifeq ($(shell test $(GCC_VERSION) -ge $(GCC_VERSION_NEED_ZICSR) && echo true),true)

View File

@ -69,7 +69,7 @@ vRegTest1Implementation:
li x30, 0x1e
li x31, 0x1f
#endif
#if __riscv_flen == 64
#if configENABLE_FPU == 1
li x15, 0xC030000000000000 // -16
fmv.d.x f0, x15
li x15, 0xC02E000000000000 // -15
@ -133,6 +133,44 @@ vRegTest1Implementation:
li x15, 0x402C000000000000 // 14
fmv.d.x f30, x15
#endif
#if configENABLE_VPU == 1
/* Set the vector length to maximum available */
li x15, -1
vsetvli x0, x15, e8, m1, ta, ma /* Use 64-bit elements, mask and tail agnostic */
/* Initialize each vector register with different values */
vid.v v0 // v0 = [0,1,2,3...]
vadd.vi v1, v0, -15 // v1 = [-15, -14, -13, -12...]
vadd.vi v2, v0, -14 // v2 = [-14, -13, -12, -11...]
vadd.vi v3, v0, -13 // v3 = [-13, -12, -11, -10...]
vadd.vi v4, v0, -12 // v4 = [-12, -11, -10, -9...]
vadd.vi v5, v0, -11 // v5 = [-11, -10, -9, -8...]
vadd.vi v6, v0, -10 // v6 = [-10, -9, -8, -7...]
vadd.vi v7, v0, -9 // v7 = [-9, -8, -7, -6...]
vadd.vi v8, v0, -8 // v8 = [-8, -7, -6, -5...]
vadd.vi v9, v0, -7 // v9 = [-7, -6, -5, -4...]
vadd.vi v10, v0, -6 // v10 = [-6, -5, -4, -3...]
vadd.vi v11, v0, -5 // v11 = [-5, -4, -3, -2...]
vadd.vi v12, v0, -4 // v12 = [-4, -3, -2, -1...]
vadd.vi v13, v0, -3 // v13 = [-3, -2, -1, 0...]
vadd.vi v14, v0, -2 // v14 = [-2, -1, 0, 1...]
vadd.vi v15, v0, -1 // v15 = [-1, 0, 1, 2...]
vadd.vi v16, v0, 1 // v16 = [1, 2, 3, 4...]
vadd.vi v17, v0, 2 // v17 = [2, 3, 4, 5...]
vadd.vi v18, v0, 3 // v18 = [3, 4, 5, 6...]
vadd.vi v19, v0, 4 // v19 = [4, 5, 6, 7...]
vadd.vi v20, v0, 5 // v20 = [5, 6, 7, 8...]
vadd.vi v21, v0, 6 // v21 = [6, 7, 8, 9...]
vadd.vi v22, v0, 7 // v22 = [7, 8, 9, 10...]
vadd.vi v23, v0, 8 // v23 = [8, 9, 10, 11...]
vadd.vi v24, v0, 9 // v24 = [9, 10, 11, 12...]
vadd.vi v25, v0, 10 // v25 = [10, 11, 12, 13...]
vadd.vi v26, v0, 11 // v26 = [11, 12, 13, 14...]
vadd.vi v27, v0, 12 // v27 = [12, 13, 14, 15...]
vadd.vi v28, v0, 13 // v28 = [13, 14, 15, 16...]
vadd.vi v29, v0, 14 // v29 = [14, 15, 16, 17...]
vadd.vi v30, v0, 15 // v30 = [15, 16, 17, 18...]
vadd.vi v31, v0, 0 // v31 = [0,1,2,3...]
#endif
reg1_loop:
@ -193,7 +231,7 @@ reg1_loop:
li x15, 0x1f
bne x15, x31, reg1_error_loop
#endif
#if __riscv_flen == 64
#if configENABLE_FPU == 1
li x15, 0xC030000000000000 // -16
fmv.d.x f31, x15
feq.d x15, f0, f31
@ -319,6 +357,224 @@ reg1_loop:
feq.d x15, f30, f31
beqz x15, reg1_error_loop
#endif
#if configENABLE_VPU == 1
vid.v v0 // v0 = [0,1,2,3...]
vadd.vi v0, v0, -15 // v0 = [-15, -14, -13, -12...]
vsub.vv v0, v1, v0 // Compare v1 to the expected value, v0
vredor.vs v0, v0, v0 // Reduce the mask to a single value, 0 if all elements were equal
vmv.x.s x15, v0 // Move the result to a scalar register
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, -14
vsub.vv v0, v2, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, -13
vsub.vv v0, v3, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, -12
vsub.vv v0, v4, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, -11
vsub.vv v0, v5, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, -10
vsub.vv v0, v6, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, -9
vsub.vv v0, v7, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, -8
vsub.vv v0, v8, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, -7
vsub.vv v0, v9, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, -6
vsub.vv v0, v10, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, -5
vsub.vv v0, v11, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, -4
vsub.vv v0, v12, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, -3
vsub.vv v0, v13, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, -2
vsub.vv v0, v14, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, -1
vsub.vv v0, v15, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 1
vsub.vv v0, v16, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 2
vsub.vv v0, v17, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 3
vsub.vv v0, v18, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 4
vsub.vv v0, v19, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 5
vsub.vv v0, v20, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 6
vsub.vv v0, v21, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 7
vsub.vv v0, v22, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 8
vsub.vv v0, v23, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 9
vsub.vv v0, v24, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 10
vsub.vv v0, v25, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 11
vsub.vv v0, v26, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 12
vsub.vv v0, v27, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 13
vsub.vv v0, v28, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 14
vsub.vv v0, v29, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 15
vsub.vv v0, v30, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
vid.v v0
vadd.vi v0, v0, 0
vsub.vv v0, v31, v0
vredor.vs v0, v0, v0
vmv.x.s x15, v0
bnez x15, reg1_error_loop
#endif
/* Everything passed, increment the loop counter. */
#if __riscv_xlen == 64
@ -383,7 +639,7 @@ vRegTest2Implementation:
li x30, 0x2e
li x31, 0x2f
#endif
#if __riscv_flen == 64
#if configENABLE_FPU == 1
li x5, 0x402E000000000000 // 15
fmv.d.x f1, x5
li x5, 0x402C000000000000 // 14
@ -447,6 +703,44 @@ vRegTest2Implementation:
li x5, 0xC02E000000000000 // -15
fmv.d.x f31, x5
#endif
#if configENABLE_VPU == 1
/* Set the vector length to maximum available */
li x5, -1
vsetvli x0, x5, e8, m1, ta, ma /* Use 64-bit elements, mask and tail agnostic */
/* Initialize each vector register with different values */
vid.v v31 // v31 = [0,1,2,3...]
vadd.vi v1, v31, 8 // v1 = [8, 9, 10, 11...]
vadd.vi v2, v31, -8 // v2 = [-8, -7, -6, -5...]
vadd.vi v3, v31, 7 // v3 = [7, 8, 9, 10...]
vadd.vi v4, v31, -7 // v4 = [-7, -6, -5, -4...]
vadd.vi v5, v31, 6 // v5 = [6, 7, 8, 9...]
vadd.vi v6, v31, -6 // v6 = [-6, -5, -4, -3...]
vadd.vi v7, v31, 5 // v7 = [5, 6, 7, 8...]
vadd.vi v8, v31, -5 // v8 = [-5, -4, -3, -2...]
vadd.vi v9, v31, 4 // v9 = [4, 5, 6, 7...]
vadd.vi v10, v31, -4 // v10 = [-4, -3, -2, -1...]
vadd.vi v11, v31, 3 // v11 = [3, 4, 5, 6...]
vadd.vi v12, v31, -3 // v12 = [-3, -2, -1, 0...]
vadd.vi v13, v31, 2 // v13 = [2, 3, 4, 5...]
vadd.vi v14, v31, -2 // v14 = [-2, -1, 0, 1...]
vadd.vi v15, v31, 1 // v15 = [1, 2, 3, 4...]
vadd.vi v16, v31, -1 // v16 = [-1, 0, 1, 2...]
vadd.vi v17, v31, 0 // v17 = [0,1,2,3...]
vadd.vi v18, v31, 9 // v18 = [9, 10, 11, 12...]
vadd.vi v19, v31, -9 // v19 = [-9, -8, -7, -6...]
vadd.vi v20, v31, 10 // v20 = [10, 11, 12, 13...]
vadd.vi v21, v31, -10 // v21 = [-10, -9, -8, -7...]
vadd.vi v22, v31, 11 // v22 = [11, 12, 13, 14...]
vadd.vi v23, v31, -11 // v23 = [-11, -10, -9, -8...]
vadd.vi v24, v31, 12 // v24 = [12, 13, 14, 15...]
vadd.vi v25, v31, -12 // v25 = [-12, -11, -10, -9...]
vadd.vi v26, v31, 13 // v26 = [13, 14, 15, 16...]
vadd.vi v27, v31, -13 // v27 = [-13, -12, -11, -10...]
vadd.vi v28, v31, 14 // v28 = [14, 15, 16, 17...]
vadd.vi v29, v31, -14 // v29 = [-14, -13, -12, -11...]
vadd.vi v30, v31, -15 // v30 = [-15, -14, -13, -12...]
vadd.vi v0, v31, 15 // v0 = [15, 16, 17, 18...]
#endif
Reg2_loop:
@ -507,7 +801,7 @@ Reg2_loop:
li x5, 0x2f
bne x5, x31, reg2_error_loop
#endif
#if __riscv_flen == 64
#if configENABLE_FPU == 1
li x5, 0x402E000000000000 // 15
fmv.d.x f0, x5
feq.d x5, f1, f0
@ -633,6 +927,224 @@ Reg2_loop:
feq.d x5, f31, f0
beqz x5, reg2_error_loop
#endif
#if configENABLE_VPU == 1
vid.v v31 // v31 = [0,1,2,3...]
vadd.vi v31, v31, 8 // v31 = [-15, -14, -13, -12...]
vsub.vv v31, v1, v31 // Compare v1 to the expected value, v31
vredor.vs v31, v31, v31 // Reduce the mask to a single value, 0 if all elements were equal
vmv.x.s x5, v31 // Move the result to a scalar register
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -8
vsub.vv v31, v2, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 7
vsub.vv v31, v3, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -7
vsub.vv v31, v4, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 6
vsub.vv v31, v5, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -6
vsub.vv v31, v6, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 5
vsub.vv v31, v7, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -5
vsub.vv v31, v8, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 4
vsub.vv v31, v9, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -4
vsub.vv v31, v10, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 3
vsub.vv v31, v11, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -3
vsub.vv v31, v12, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 2
vsub.vv v31, v13, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -2
vsub.vv v31, v14, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 1
vsub.vv v31, v15, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -1
vsub.vv v31, v16, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 0
vsub.vv v31, v17, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 9
vsub.vv v31, v18, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -9
vsub.vv v31, v19, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 10
vsub.vv v31, v20, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -10
vsub.vv v31, v21, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 11
vsub.vv v31, v22, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -11
vsub.vv v31, v23, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 12
vsub.vv v31, v24, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -12
vsub.vv v31, v25, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 13
vsub.vv v31, v26, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -13
vsub.vv v31, v27, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 14
vsub.vv v31, v28, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -14
vsub.vv v31, v29, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, -15
vsub.vv v31, v30, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
vid.v v31
vadd.vi v31, v31, 15
vsub.vv v31, v0, v31
vredor.vs v31, v31, v31
vmv.x.s x5, v31
bnez x5, reg2_error_loop
#endif
/* Everything passed, increment the loop counter. */
#if __riscv_xlen == 64

View File

@ -74,6 +74,11 @@ _start:
csrs mstatus, t0
fscsr x0
#endif
#ifdef __riscv_vector
// Enable VPU
li t0, (1 << 9)
csrs mstatus, t0
#endif
// argc, argv, envp is 0
li a0, 0

View File

@ -108,7 +108,11 @@
* constant is different depending on the compiler in use. */
#define mainMESSAGE_BUFFER_STACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) )
#define mainCHECK_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + ( configMINIMAL_STACK_SIZE >> 1 ) )
#ifdef __riscv_vector
#define mainREG_TEST_STACK_SIZE_WORDS 222
#else
#define mainREG_TEST_STACK_SIZE_WORDS 90
#endif
/* Parameters that are passed into the register check tasks solely for the
* purpose of ensuring parameters are passed into tasks correctly. */
@ -250,7 +254,7 @@ static void prvCheckTask( void * pvParameters )
/* Demo start marker. */
#if __riscv_flen == 64
printf( "FreeRTOS Demo Start (With FPU)\r\n" );
printf( "FreeRTOS Demo Start (With FPU and vector)\r\n" );
#else
printf( "FreeRTOS Demo Start\r\n" );
#endif

View File

@ -5,7 +5,7 @@ license: "MIT"
dependencies:
- name: "FreeRTOS-Kernel"
version: "4d9cd90"
version: "0030d609a"
repository:
type: "git"
url: "https://github.com/FreeRTOS/FreeRTOS-Kernel.git"