From 13d8e7e982a4df6d8798fcbcb432bdaff0ee1427 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Tue, 18 Oct 2022 15:48:13 +0800 Subject: [PATCH 01/11] [riscv] add vector context in kernel; --- bsp/qemu-virt64-riscv/Kconfig | 4 + libcpu/risc-v/virt64/context.h | 20 ++++ libcpu/risc-v/virt64/context_gcc.S | 59 ++++++++-- libcpu/risc-v/virt64/cpuport.h | 11 +- libcpu/risc-v/virt64/encoding.h | 5 + libcpu/risc-v/virt64/ext_context.h | 155 +++++++++++++++++++++++++ libcpu/risc-v/virt64/stack.h | 3 + libcpu/risc-v/virt64/stackframe.h | 67 +++++------ libcpu/risc-v/virt64/trap.c | 40 +++++++ libcpu/risc-v/virt64/vector_encoding.h | 44 +++++++ 10 files changed, 360 insertions(+), 48 deletions(-) create mode 100644 libcpu/risc-v/virt64/context.h create mode 100644 libcpu/risc-v/virt64/ext_context.h create mode 100644 libcpu/risc-v/virt64/vector_encoding.h diff --git a/bsp/qemu-virt64-riscv/Kconfig b/bsp/qemu-virt64-riscv/Kconfig index 4411c401be..a1e68e09c5 100644 --- a/bsp/qemu-virt64-riscv/Kconfig +++ b/bsp/qemu-virt64-riscv/Kconfig @@ -35,6 +35,10 @@ config ENABLE_FPU bool "Enable FPU" default y +config ENABLE_VECTOR + bool "Using RISC-V Vector Extension" + default n + config RT_USING_USERSPACE_32BIT_LIMIT bool "Enable userspace 32bit limit" default n diff --git a/libcpu/risc-v/virt64/context.h b/libcpu/risc-v/virt64/context.h new file mode 100644 index 0000000000..aae39fdc46 --- /dev/null +++ b/libcpu/risc-v/virt64/context.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-10-10 RT-Thread the first version + */ + +#ifndef __CONTEXT_H__ +#define __CONTEXT_H__ + +void rt_hw_vector_ctx_save(void *buf); +void rt_hw_vector_ctx_restore(void *buf); + +void rt_hw_disable_vector(); +void rt_hw_enable_vector(); + +#endif /* __CONTEXT_H__ */ \ No newline at end of file diff --git a/libcpu/risc-v/virt64/context_gcc.S b/libcpu/risc-v/virt64/context_gcc.S index adf5a50301..e66c9a70e6 100644 --- a/libcpu/risc-v/virt64/context_gcc.S +++ b/libcpu/risc-v/virt64/context_gcc.S @@ -32,23 +32,32 @@ rt_hw_context_switch_to: /* * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to); * - * a0 --> from - * a1 --> to + * a0 --> from SP pointer + * a1 --> to SP pointer */ .globl rt_hw_context_switch rt_hw_context_switch: - mv t2, sp - li t0, 0x120//set SPIE and SPP = 1 - csrs sstatus, t0//if enter here,caller must be in system thread - csrw sepc, ra//return address - //saved from thread context - SAVE_ALL + // backup prev stack top of from thread + csrw sscratch, sp + + // on sret, reset status to + // 1. interrupt DISABLE + // 2. cpu in supervisor mode + // 3. reserved other status + li t0, 0x120 + csrs sstatus, t0 - STORE t2, 32 * REGBYTES(sp)//save user_sp + // simulate a exception return to supervisor mode + // by storing ra in sepc of from-thread stack frame + csrw sepc, ra + + // NOTE: we do NOT guarantee that any temporary registers + // will remains their value after SAVE_ALL + SAVE_ALL STORE sp, (a0) - //restore to thread context + // restore to thread context LOAD sp, (a1) la s0, rt_current_thread @@ -65,3 +74,33 @@ rt_hw_context_switch: RESTORE_ALL sret + +#ifdef ENABLE_VECTOR +/** + * @param a0 pointer to frame bottom + */ +.global rt_hw_vector_ctx_save +rt_hw_vector_ctx_save: + SAVE_VECTOR a0 + ret + +/** + * @param a0 pointer to frame bottom + */ +.global rt_hw_vector_ctx_restore +rt_hw_vector_ctx_restore: + RESTORE_VECTOR a0 + ret + +.global rt_hw_disable_vector +rt_hw_disable_vector: + li t0, SSTATUS_VS + csrc sstatus, t0 + ret + +.global rt_hw_enable_vector +rt_hw_enable_vector: + li t0, SSTATUS_VS + csrs sstatus, t0 + ret +#endif /* ENABLE_VECTOR */ diff --git a/libcpu/risc-v/virt64/cpuport.h b/libcpu/risc-v/virt64/cpuport.h index 9895f9a199..702db34a63 100644 --- a/libcpu/risc-v/virt64/cpuport.h +++ b/libcpu/risc-v/virt64/cpuport.h @@ -20,6 +20,7 @@ #define REGBYTES 8 #else // error here, not portable +#error "Not supported XLEN" #endif /* 33 general register */ @@ -32,8 +33,16 @@ #define CTX_FPU_REG_NR 0 #endif +#ifdef ENABLE_VECTOR +/* 32 128/256 bits registers, for risc-v 64, we assuming 64 64-bit regs */ +/* TODO we should detect VLEN on the fly */ +#define CTX_VECTOR_REG_NR (64 + 4) +#else +#define CTX_VECTOR_REG_NR 0 +#endif + /* all context registers */ -#define CTX_REG_NR (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR) +#define CTX_REG_NR (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR + CTX_VECTOR_REG_NR) #ifndef __ASSEMBLY__ rt_inline void rt_hw_dsb() diff --git a/libcpu/risc-v/virt64/encoding.h b/libcpu/risc-v/virt64/encoding.h index 44d4cd1aa9..9f91770f1f 100644 --- a/libcpu/risc-v/virt64/encoding.h +++ b/libcpu/risc-v/virt64/encoding.h @@ -23,6 +23,7 @@ #define MSTATUS_HPP 0x00000600 #define MSTATUS_MPP 0x00001800 #define MSTATUS_FS 0x00006000 +#define MSTATUS_VS 0x00000600 #define MSTATUS_XS 0x00018000 #define MSTATUS_MPRV 0x00020000 #define MSTATUS_PUM 0x00040000 @@ -40,6 +41,10 @@ #define SSTATUS_FS_INITIAL 0x00002000 #define SSTATUS_FS_CLEAN 0x00004000 #define SSTATUS_FS_DIRTY 0x00006000 +#define SSTATUS_VS 0x00000600 /* Vector Status */ +#define SSTATUS_VS_INITIAL 0x00000200 +#define SSTATUS_VS_CLEAN 0x00000400 +#define SSTATUS_VS_DIRTY 0x00000600 #define SSTATUS_XS 0x00018000 #define SSTATUS_PUM 0x00040000 #define SSTATUS32_SD 0x80000000 diff --git a/libcpu/risc-v/virt64/ext_context.h b/libcpu/risc-v/virt64/ext_context.h new file mode 100644 index 0000000000..ac757dddb6 --- /dev/null +++ b/libcpu/risc-v/virt64/ext_context.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-10-10 RT-Thread the first version, + * compatible to riscv-v-spec-1.0 + */ +#ifndef __EXT_CONTEXT_H__ +#define __EXT_CONTEXT_H__ + +#ifdef __ASSEMBLY__ + +/** + * extension context maintenance + */ + +#include "cpuport.h" +#include "encoding.h" +#include "vector_encoding.h" + +/** + * ================================== + * FPU EXTENSION + * ================================== + */ + +#ifdef ENABLE_FPU +#define FPU_CTX_F0_OFF 0 /* offsetof(fpu_context_t, fpustatus.f[0]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F1_OFF 8 /* offsetof(fpu_context_t, fpustatus.f[1]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F2_OFF 16 /* offsetof(fpu_context_t, fpustatus.f[2]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F3_OFF 24 /* offsetof(fpu_context_t, fpustatus.f[3]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F4_OFF 32 /* offsetof(fpu_context_t, fpustatus.f[4]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F5_OFF 40 /* offsetof(fpu_context_t, fpustatus.f[5]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F6_OFF 48 /* offsetof(fpu_context_t, fpustatus.f[6]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F7_OFF 56 /* offsetof(fpu_context_t, fpustatus.f[7]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F8_OFF 64 /* offsetof(fpu_context_t, fpustatus.f[8]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F9_OFF 72 /* offsetof(fpu_context_t, fpustatus.f[9]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F10_OFF 80 /* offsetof(fpu_context_t, fpustatus.f[10]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F11_OFF 88 /* offsetof(fpu_context_t, fpustatus.f[11]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F12_OFF 96 /* offsetof(fpu_context_t, fpustatus.f[12]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F13_OFF 104 /* offsetof(fpu_context_t, fpustatus.f[13]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F14_OFF 112 /* offsetof(fpu_context_t, fpustatus.f[14]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F15_OFF 120 /* offsetof(fpu_context_t, fpustatus.f[15]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F16_OFF 128 /* offsetof(fpu_context_t, fpustatus.f[16]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F17_OFF 136 /* offsetof(fpu_context_t, fpustatus.f[17]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F18_OFF 144 /* offsetof(fpu_context_t, fpustatus.f[18]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F19_OFF 152 /* offsetof(fpu_context_t, fpustatus.f[19]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F20_OFF 160 /* offsetof(fpu_context_t, fpustatus.f[20]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F21_OFF 168 /* offsetof(fpu_context_t, fpustatus.f[21]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F22_OFF 176 /* offsetof(fpu_context_t, fpustatus.f[22]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F23_OFF 184 /* offsetof(fpu_context_t, fpustatus.f[23]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F24_OFF 192 /* offsetof(fpu_context_t, fpustatus.f[24]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F25_OFF 200 /* offsetof(fpu_context_t, fpustatus.f[25]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F26_OFF 208 /* offsetof(fpu_context_t, fpustatus.f[26]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F27_OFF 216 /* offsetof(fpu_context_t, fpustatus.f[27]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F28_OFF 224 /* offsetof(fpu_context_t, fpustatus.f[28]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F29_OFF 232 /* offsetof(fpu_context_t, fpustatus.f[29]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F30_OFF 240 /* offsetof(fpu_context_t, fpustatus.f[30]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#define FPU_CTX_F31_OFF 248 /* offsetof(fpu_context_t, fpustatus.f[31]) - offsetof(fpu_context_t, fpustatus.f[0]) */ +#endif /* ENABLE_FPU */ + +/** + * ================================== + * VECTOR EXTENSION + * ================================== + */ + +#ifdef ENABLE_VECTOR + +#define VEC_FRAME_VSTART (0 * REGBYTES) +#define VEC_FRAME_VTYPE (1 * REGBYTES) +#define VEC_FRAME_VL (2 * REGBYTES) +#define VEC_FRAME_VCSR (3 * REGBYTES) +#define VEC_FRAME_V0 (4 * REGBYTES) + +.macro GET_VEC_FRAME_LEN, xreg + csrr \xreg, vlenb + slli \xreg, \xreg, 5 + addi \xreg, \xreg, 4 * REGBYTES +.endm + +/** + * @brief save vector extension hardware state + * + * @param dst register storing bottom of storage block + * + */ +.macro SAVE_VECTOR, dst + mv t1, \dst + + csrr t0, vstart + STORE t0, VEC_FRAME_VSTART(t1) + csrr t0, vtype + STORE t0, VEC_FRAME_VTYPE(t1) + csrr t0, vl + STORE t0, VEC_FRAME_VL(t1) + csrr t0, vcsr + STORE t0, VEC_FRAME_VCSR(t1) + + addi t1, t1, VEC_FRAME_V0 + + // config vector setting, + // t2 is updated to length of a vector group in bytes + VEC_CONFIG_SETVLI(t2, x0, VEC_IMM_SEW_8, VEC_IMM_LMUL_8) + + vse8.v v0, (t1) + add t1, t1, t2 + vse8.v v8, (t1) + add t1, t1, t2 + vse8.v v16, (t1) + add t1, t1, t2 + vse8.v v24, (t1) +.endm + +/** + * @brief restore vector extension hardware states + * + * @param dst register storing bottom of storage block + * + */ +.macro RESTORE_VECTOR, dst + // restore vector registers first since it will modify vector states + mv t0, \dst + addi t1, t0, VEC_FRAME_V0 + + VEC_CONFIG_SETVLI(t2, x0, VEC_IMM_SEW_8, VEC_IMM_LMUL_8) + + vle8.v v0, (t1) + add t1, t1, t2 + vle8.v v8, (t1) + add t1, t1, t2 + vle8.v v16, (t1) + add t1, t1, t2 + vle8.v v24, (t1) + + mv t1, t0 + + LOAD t0, VEC_FRAME_VSTART(t1) + csrw vstart, t0 + LOAD t0, VEC_FRAME_VCSR(t1) + csrw vcsr, t0 + + LOAD t0, VEC_FRAME_VTYPE(t1) + LOAD t3, VEC_FRAME_VL(t1) + VEC_CONFIG_SET_VL_VTYPE(t3, t0) +.endm + +#endif /* ENABLE_VECTOR */ + +#endif /* __ASSEMBLY__ */ + +#endif /* __EXT_CONTEXT_H__ */ \ No newline at end of file diff --git a/libcpu/risc-v/virt64/stack.h b/libcpu/risc-v/virt64/stack.h index bd47570d98..d619d3fd35 100644 --- a/libcpu/risc-v/virt64/stack.h +++ b/libcpu/risc-v/virt64/stack.h @@ -50,6 +50,9 @@ struct rt_hw_stack_frame #ifdef ENABLE_FPU rt_ubase_t f[CTX_FPU_REG_NR]; /* f0~f31 */ #endif +#ifdef ENABLE_VECTOR + rt_ubase_t v[CTX_VECTOR_REG_NR]; +#endif }; #endif diff --git a/libcpu/risc-v/virt64/stackframe.h b/libcpu/risc-v/virt64/stackframe.h index 1e191900b4..3bc8bc9c32 100644 --- a/libcpu/risc-v/virt64/stackframe.h +++ b/libcpu/risc-v/virt64/stackframe.h @@ -15,41 +15,7 @@ #include "cpuport.h" #include "encoding.h" - -#ifdef ENABLE_FPU -#define FPU_CTX_F0_OFF 0 /* offsetof(fpu_context_t, fpustatus.f[0]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F1_OFF 8 /* offsetof(fpu_context_t, fpustatus.f[1]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F2_OFF 16 /* offsetof(fpu_context_t, fpustatus.f[2]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F3_OFF 24 /* offsetof(fpu_context_t, fpustatus.f[3]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F4_OFF 32 /* offsetof(fpu_context_t, fpustatus.f[4]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F5_OFF 40 /* offsetof(fpu_context_t, fpustatus.f[5]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F6_OFF 48 /* offsetof(fpu_context_t, fpustatus.f[6]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F7_OFF 56 /* offsetof(fpu_context_t, fpustatus.f[7]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F8_OFF 64 /* offsetof(fpu_context_t, fpustatus.f[8]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F9_OFF 72 /* offsetof(fpu_context_t, fpustatus.f[9]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F10_OFF 80 /* offsetof(fpu_context_t, fpustatus.f[10]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F11_OFF 88 /* offsetof(fpu_context_t, fpustatus.f[11]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F12_OFF 96 /* offsetof(fpu_context_t, fpustatus.f[12]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F13_OFF 104 /* offsetof(fpu_context_t, fpustatus.f[13]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F14_OFF 112 /* offsetof(fpu_context_t, fpustatus.f[14]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F15_OFF 120 /* offsetof(fpu_context_t, fpustatus.f[15]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F16_OFF 128 /* offsetof(fpu_context_t, fpustatus.f[16]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F17_OFF 136 /* offsetof(fpu_context_t, fpustatus.f[17]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F18_OFF 144 /* offsetof(fpu_context_t, fpustatus.f[18]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F19_OFF 152 /* offsetof(fpu_context_t, fpustatus.f[19]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F20_OFF 160 /* offsetof(fpu_context_t, fpustatus.f[20]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F21_OFF 168 /* offsetof(fpu_context_t, fpustatus.f[21]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F22_OFF 176 /* offsetof(fpu_context_t, fpustatus.f[22]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F23_OFF 184 /* offsetof(fpu_context_t, fpustatus.f[23]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F24_OFF 192 /* offsetof(fpu_context_t, fpustatus.f[24]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F25_OFF 200 /* offsetof(fpu_context_t, fpustatus.f[25]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F26_OFF 208 /* offsetof(fpu_context_t, fpustatus.f[26]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F27_OFF 216 /* offsetof(fpu_context_t, fpustatus.f[27]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F28_OFF 224 /* offsetof(fpu_context_t, fpustatus.f[28]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F29_OFF 232 /* offsetof(fpu_context_t, fpustatus.f[29]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F30_OFF 240 /* offsetof(fpu_context_t, fpustatus.f[30]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#define FPU_CTX_F31_OFF 248 /* offsetof(fpu_context_t, fpustatus.f[31]) - offsetof(fpu_context_t, fpustatus.f[0]) */ -#endif /* ENABLE_FPU */ +#include "ext_context.h" /** * The register `tp` always save/restore when context switch, @@ -65,6 +31,10 @@ /* reserve float registers */ addi sp, sp, -CTX_FPU_REG_NR * REGBYTES #endif /* ENABLE_FPU */ +#ifdef ENABLE_VECTOR + /* reserve float registers */ + addi sp, sp, -CTX_VECTOR_REG_NR * REGBYTES +#endif /* ENABLE_VECTOR */ /* save general registers */ addi sp, sp, -CTX_GENERAL_REG_NR * REGBYTES @@ -157,14 +127,37 @@ #endif /* ENABLE_FPU */ +#ifdef ENABLE_VECTOR + csrr t0, sstatus + andi t0, t0, SSTATUS_VS + beqz t0, 0f + + /* push vector frame */ + addi t1, sp, (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR) * REGBYTES + + SAVE_VECTOR t1 +0: +#endif /* ENABLE_VECTOR */ .endm .macro RESTORE_ALL +#ifdef ENABLE_VECTOR + // skip on close + csrr t0, sstatus + andi t0, t0, SSTATUS_VS + beqz t0, 0f + + /* push vector frame */ + addi t1, sp, (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR) * REGBYTES + + RESTORE_VECTOR t1 +0: +#endif /* ENABLE_VECTOR */ + #ifdef ENABLE_FPU /* restore float register */ - mv t2, sp - addi t2, t2, CTX_GENERAL_REG_NR * REGBYTES /* skip all normal reg */ + addi t2, sp, CTX_GENERAL_REG_NR * REGBYTES li t0, SSTATUS_FS csrs sstatus, t0 diff --git a/libcpu/risc-v/virt64/trap.c b/libcpu/risc-v/virt64/trap.c index dc8398784c..cce3227c73 100644 --- a/libcpu/risc-v/virt64/trap.c +++ b/libcpu/risc-v/virt64/trap.c @@ -172,6 +172,41 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw sys_exit(-1); } +static void vector_enable(struct rt_hw_stack_frame *sp) +{ + sp->sstatus |= SSTATUS_VS_INITIAL; +} + +/** + * detect V/D support, and do not distinguish V/D instruction + */ +static int illegal_inst_recoverable(rt_ubase_t stval, struct rt_hw_stack_frame *sp) +{ + // first 7 bits is opcode + int opcode = stval & 0x7f; + int csr = (stval & 0xFFF00000) >> 20; + // ref riscv-v-spec-1.0, [Vector Instruction Formats] + int width = ((stval & 0x7000) >> 12) - 1; + int flag = 0; + + switch (opcode) + { + case 0x57: // V + case 0x27: // scalar FLOAT + case 0x07: + case 0x73: // CSR + flag = 1; + break; + } + + if (flag) + { + vector_enable(sp); + } + + return flag; +} + /* Trap entry */ void handle_trap(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw_stack_frame *sp) { @@ -213,6 +248,11 @@ void handle_trap(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw } else { + if (scause == 0x2) + { + if (!(sp->sstatus & SSTATUS_VS) && illegal_inst_recoverable(stval, sp)) + return; + } if (!(sp->sstatus & 0x100)) { handle_user(scause, stval, sepc, sp); diff --git a/libcpu/risc-v/virt64/vector_encoding.h b/libcpu/risc-v/virt64/vector_encoding.h new file mode 100644 index 0000000000..5445843f06 --- /dev/null +++ b/libcpu/risc-v/virt64/vector_encoding.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-10-10 RT-Thread the first version, + * compatible to riscv-v-spec-1.0 + */ + +#ifndef __VECTOR_ENCODING_H__ +#define __VECTOR_ENCODING_H__ + +/** + * assembler names used for vset{i}vli vtypei immediate + */ + +#define VEC_IMM_SEW_8 e8 +#define VEC_IMM_SEW_16 e16 +#define VEC_IMM_SEW_32 e32 +#define VEC_IMM_SEW_64 e64 +/* group setting, encoding by multiplier */ +#define VEC_IMM_LMUL_F8 mf8 +#define VEC_IMM_LMUL_F4 mf4 +#define VEC_IMM_LMUL_F2 mf2 +#define VEC_IMM_LMUL_1 m1 +#define VEC_IMM_LMUL_2 m2 +#define VEC_IMM_LMUL_4 m4 +#define VEC_IMM_LMUL_8 m8 +/* TAIL & MASK agnostic bits */ +#define VEC_IMM_TAIL_AGNOSTIC ta +#define VEC_IMM_MASK_AGNOSTIC ma +#define VEC_IMM_TAMA VEC_IMM_TAIL_AGNOSTIC, VEC_IMM_MASK_AGNOSTIC +#define VEC_IMM_TAMU VEC_IMM_TAIL_AGNOSTIC +#define VEC_IMM_TUMA VEC_IMM_MASK_AGNOSTIC + +/** + * configuration setting instruction + */ +#define VEC_CONFIG_SETVLI(xVl, xAvl, vtype...) vsetvli xVl, xAvl, ##vtype +#define VEC_CONFIG_SET_VL_VTYPE(xVl, xVtype) vsetvl x0, xVl, xVtype + +#endif /* __VECTOR_ENCODING_H__ */ \ No newline at end of file -- Gitee From 3a8c8fa69ec4284ec5efe70bb13723af75272b73 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Wed, 19 Oct 2022 16:51:35 +0800 Subject: [PATCH 02/11] [riscv/rv64] add vector test script --- .../applications/test/test_vector/SConscript | 9 + .../test/test_vector/test_vector.c | 178 ++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 bsp/qemu-virt64-riscv/applications/test/test_vector/SConscript create mode 100644 bsp/qemu-virt64-riscv/applications/test/test_vector/test_vector.c diff --git a/bsp/qemu-virt64-riscv/applications/test/test_vector/SConscript b/bsp/qemu-virt64-riscv/applications/test/test_vector/SConscript new file mode 100644 index 0000000000..92c4259bdb --- /dev/null +++ b/bsp/qemu-virt64-riscv/applications/test/test_vector/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +group = DefineGroup('Vector', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/qemu-virt64-riscv/applications/test/test_vector/test_vector.c b/bsp/qemu-virt64-riscv/applications/test/test_vector/test_vector.c new file mode 100644 index 0000000000..9a58704362 --- /dev/null +++ b/bsp/qemu-virt64-riscv/applications/test/test_vector/test_vector.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#include +#include +#include +#include + +#if defined(RT_USING_UTEST) && defined(ENABLE_VECTOR) +#include +#include + +void rt_hw_vector_ctx_restore(void *buf); +void rt_hw_vector_ctx_save(void *buf); + +/** + * ============================================================== + * TEST FEATURE + * Use libc `memcpy` which employing V extension codes + * to test V extension features + * ============================================================== + */ +static char *constant = "hello,it's a nice day and i'm happy to see you\nhello,it's a nice day and i'm happy to see you\nRT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统"; +#define ARR_SIZE 4096 +static char array[ARR_SIZE]; + +static void test_feature(void) +{ + memcpy(array, constant, sizeof array); + char *src = constant; + char *dst = array; + int error = 0; + + for (size_t i = 0; i < ARR_SIZE; i++) + { + if (src[i] != dst[i]) + { + error = 1; + break; + } + } + + uassert_false(error); +} + +/** + * ============================================================== + * TEST CONTEXT SAVING + * Create 2 threads employing V extension, verify V states are + * not modified by each other + * ============================================================== + */ +#define TEST_THREAD 2 +#define VECTOR_CTX_BYTES (CTX_VECTOR_REG_NR * REGBYTES) +void *ctx_vector[TEST_THREAD * 2]; + +static rt_sem_t sem; + +void dump_frame(void *frame) +{ + uint64_t *content = frame; + for (size_t i = 0; i < VECTOR_CTX_BYTES / 8; i++) + { + rt_kprintf("%x ", content[i]); + } + rt_kprintf("\n"); +} + +static void vector_child(void *param) +{ + void **ctx = param; + uint64_t *reg = ctx[0]; + uint64_t vtype; + uint64_t vl; + + rt_sem_release(sem); + + rt_hw_vector_ctx_restore(ctx[0]); + + /* STAGE 2, save t2 context */ + test_feature(); + + /** + * @brief vtype & vl will be modified after context saving, + * it's ok because it will be recover after context restoring + * We restore these states manually here. + */ + asm volatile("csrr %0, vtype":"=r"(vtype)); + asm volatile("csrr %0, vl":"=r"(vl)); + rt_hw_vector_ctx_save(ctx[0]); + + rt_memcpy(ctx[1], ctx[0], VECTOR_CTX_BYTES); + + rt_thread_yield(); + + asm volatile("vsetvl x0, %0, %1"::"r"(vl), "r"(vtype)); + rt_hw_vector_ctx_save(ctx[0]); + + uassert_false(rt_memcmp(ctx[1], ctx[0], VECTOR_CTX_BYTES)); +} + +/** + * @brief Test if context save/restore codes work properly + */ +static void test_context() +{ + rt_thread_t child; + uint64_t vtype; + uint64_t vl; + + for (size_t i = 0; i < TEST_THREAD; i++) + { + ctx_vector[i * 2] = calloc(VECTOR_CTX_BYTES, 1); + ctx_vector[i * 2 + 1] = calloc(VECTOR_CTX_BYTES, 1); + } + rt_hw_vector_ctx_restore(ctx_vector[0]); + + child = rt_thread_create("test_vector_child", vector_child, &ctx_vector[2], 4096, 10, 20); + + /* STAGE 1, save t1 context */ + /* assuming that rt libc memcpy do not use vector instruction */ + asm volatile("csrr %0, vtype":"=r"(vtype)); + asm volatile("csrr %0, vl":"=r"(vl)); + rt_hw_vector_ctx_save(ctx_vector[0]); + + rt_memcpy(ctx_vector[1], ctx_vector[0], VECTOR_CTX_BYTES); + + rt_thread_startup(child); + rt_sem_take(sem, 0); + + /* STAGE 3, verify t1 context */ + asm volatile("vsetvl x0, %0, %1"::"r"(vl), "r"(vtype)); + rt_hw_vector_ctx_save(ctx_vector[0]); + uassert_false(rt_memcmp(ctx_vector[1], ctx_vector[0], VECTOR_CTX_BYTES)); + + rt_thread_yield(); +} + +/** + * ============================================================== + * TEST NO VECTOR raise error and recover + * ============================================================== + */ + +static void test_no_vector() +{ + asm volatile ("li t0, 0x600\n" + "csrc sstatus, t0"); + test_feature(); + uassert_true(1); +} + +static rt_err_t utest_tc_init(void) +{ + sem = rt_sem_create("test_ctx", 0, RT_IPC_FLAG_FIFO); + return RT_EOK; +} + +static rt_err_t utest_tc_cleanup(void) +{ + rt_sem_delete(sem); + return RT_EOK; +} + +static void testcase(void) +{ + UTEST_UNIT_RUN(test_feature); + UTEST_UNIT_RUN(test_context); + UTEST_UNIT_RUN(test_no_vector); +} + +UTEST_TC_EXPORT(testcase, "testcases.libcpu.vector", utest_tc_init, utest_tc_cleanup, 10); +#endif /* RT_USING_UTEST && ENABLE_VECTOR */ -- Gitee From 906c193e86e44e5737fdd8ae39eba92c339f363f Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Sat, 22 Oct 2022 17:40:33 +0800 Subject: [PATCH 03/11] [riscv] process switch using less context --- bsp/qemu-virt64-riscv/Kconfig | 19 +++- components/lwp/arch/risc-v/rv64/lwp_gcc.S | 1 - libcpu/risc-v/virt64/context_gcc.S | 101 +++++++++++++----- libcpu/risc-v/virt64/cpuport.c | 79 +++++++------- .../virt64/{context.h => cpuport_gcc.S} | 22 ++-- libcpu/risc-v/virt64/interrupt_gcc.S | 25 ++--- libcpu/risc-v/virt64/riscv_mmu.c | 4 +- libcpu/risc-v/virt64/startup_gcc.S | 1 - libcpu/risc-v/virt64/trap.c | 2 +- 9 files changed, 152 insertions(+), 102 deletions(-) rename libcpu/risc-v/virt64/{context.h => cpuport_gcc.S} (32%) diff --git a/bsp/qemu-virt64-riscv/Kconfig b/bsp/qemu-virt64-riscv/Kconfig index a1e68e09c5..0b7da6b9ab 100644 --- a/bsp/qemu-virt64-riscv/Kconfig +++ b/bsp/qemu-virt64-riscv/Kconfig @@ -17,10 +17,12 @@ config PKGS_DIR source "$RTT_DIR/Kconfig" source "$PKGS_DIR/Kconfig" +source "driver/Kconfig" -config BOARD_virt +config BOARD_QEMU_VIRT_RV64 bool select ARCH_RISCV64 + select ARCH_CONTEXT_EXTEND select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN select RT_USING_CACHE @@ -39,6 +41,19 @@ config ENABLE_VECTOR bool "Using RISC-V Vector Extension" default n +if ENABLE_VECTOR + choice + prompt "Vector Registers Length in Bits" + default ARCH_VECTOR_VLEN_128 + + config ARCH_VECTOR_VLEN_128 + bool "128" + + config ARCH_VECTOR_VLEN_256 + bool "256" + endchoice +endif + config RT_USING_USERSPACE_32BIT_LIMIT bool "Enable userspace 32bit limit" default n @@ -47,8 +62,6 @@ config RT_USING_VIRTIO_MMIO_ALIGN bool "Open packed attribution, this may caused an error on virtio" default n -source "driver/Kconfig" - config __STACKSIZE__ int "stack size for interrupt" default 4096 diff --git a/components/lwp/arch/risc-v/rv64/lwp_gcc.S b/components/lwp/arch/risc-v/rv64/lwp_gcc.S index 2ba9ced92b..c41ad5297c 100644 --- a/components/lwp/arch/risc-v/rv64/lwp_gcc.S +++ b/components/lwp/arch/risc-v/rv64/lwp_gcc.S @@ -12,7 +12,6 @@ #include "rtconfig.h" -#define __ASSEMBLY__ #include "cpuport.h" #include "encoding.h" #include "stackframe.h" diff --git a/libcpu/risc-v/virt64/context_gcc.S b/libcpu/risc-v/virt64/context_gcc.S index e66c9a70e6..176625a94e 100644 --- a/libcpu/risc-v/virt64/context_gcc.S +++ b/libcpu/risc-v/virt64/context_gcc.S @@ -10,11 +10,74 @@ * 2021/02/02 lizhirui Add userspace support */ -#define __ASSEMBLY__ #include "cpuport.h" #include "stackframe.h" - .globl rt_hw_context_switch_to +/** + * sstatus -> interrupt frame + * sepc -> interrupt frame + * sscratch -> ? + * sp -> TCB + * tp -> pointer to current TCB + */ + +.macro PUSH_8 reg + addi sp, sp, -8 + STORE \reg, (sp) +.endm + +.macro POP_8 reg + LOAD \reg, (sp) + addi sp, sp, 8 +.endm + +.macro RESERVE_CONTEXT + PUSH_8 tp + PUSH_8 ra + PUSH_8 s0 + PUSH_8 s1 + PUSH_8 s2 + PUSH_8 s3 + PUSH_8 s4 + PUSH_8 s5 + PUSH_8 s6 + PUSH_8 s7 + PUSH_8 s8 + PUSH_8 s9 + PUSH_8 s10 + PUSH_8 s11 + csrr s11, sstatus + li s10, (SSTATUS_SPP) + or s11, s11, s10 + PUSH_8 s11 +.endm + +.macro RESTORE_CONTEXT + POP_8 s11 + csrw sstatus, s11 + POP_8 s11 + POP_8 s10 + POP_8 s9 + POP_8 s8 + POP_8 s7 + POP_8 s6 + POP_8 s5 + POP_8 s4 + POP_8 s3 + POP_8 s2 + POP_8 s1 + POP_8 s0 + POP_8 ra + POP_8 tp + csrw sepc, ra +.endm + +/* + * void rt_hw_context_switch_to(rt_ubase_t to); + * + * a0 --> to SP pointer + */ +.globl rt_hw_context_switch_to rt_hw_context_switch_to: LOAD sp, (a0) @@ -26,7 +89,7 @@ rt_hw_context_switch_to: jal lwp_mmu_switch #endif - RESTORE_ALL + RESTORE_CONTEXT sret /* @@ -34,32 +97,18 @@ rt_hw_context_switch_to: * * a0 --> from SP pointer * a1 --> to SP pointer + * + * It should only be used on local interrupt disable */ - .globl rt_hw_context_switch +.globl rt_hw_context_switch rt_hw_context_switch: - // backup prev stack top of from thread - csrw sscratch, sp - - // on sret, reset status to - // 1. interrupt DISABLE - // 2. cpu in supervisor mode - // 3. reserved other status - li t0, 0x120 - csrs sstatus, t0 - - // simulate a exception return to supervisor mode - // by storing ra in sepc of from-thread stack frame - csrw sepc, ra - - // NOTE: we do NOT guarantee that any temporary registers - // will remains their value after SAVE_ALL - SAVE_ALL - + RESERVE_CONTEXT STORE sp, (a0) - // restore to thread context + // restore to thread SP LOAD sp, (a1) + // restore Address Space la s0, rt_current_thread LOAD s1, (s0) @@ -68,11 +117,7 @@ rt_hw_context_switch: jal lwp_mmu_switch #endif - LOAD t0, 2 * REGBYTES(sp) - andi t0, t0, 0x100 - beqz t0, arch_ret_to_user - - RESTORE_ALL + RESTORE_CONTEXT sret #ifdef ENABLE_VECTOR diff --git a/libcpu/risc-v/virt64/cpuport.c b/libcpu/risc-v/virt64/cpuport.c index c4210a2837..0573eceac7 100644 --- a/libcpu/risc-v/virt64/cpuport.c +++ b/libcpu/risc-v/virt64/cpuport.c @@ -17,27 +17,30 @@ #include +#define K_SSTATUS_DEFAULT (SSTATUS_SPP | SSTATUS_SPIE | SSTATUS_SUM) /** * @brief from thread used interrupt context switch * */ -volatile rt_ubase_t rt_interrupt_from_thread = 0; +volatile rt_ubase_t rt_interrupt_from_thread = 0; /** * @brief to thread used interrupt context switch * */ -volatile rt_ubase_t rt_interrupt_to_thread = 0; +volatile rt_ubase_t rt_interrupt_to_thread = 0; /** * @brief flag to indicate context switch in interrupt or not * */ volatile rt_ubase_t rt_thread_switch_interrupt_flag = 0; - /** - * This function will initialize thread stack + * This function will initialize thread stack, we assuming + * when scheduler restore this new thread, context will restore + * an entry to user first application * + * s0-s11, ra, sstatus, a0 * @param tentry the entry of thread * @param parameter the parameter of entry * @param stack_addr the beginning stack address @@ -45,41 +48,38 @@ volatile rt_ubase_t rt_thread_switch_interrupt_flag = 0; * * @return stack address */ -rt_uint8_t *rt_hw_stack_init(void *tentry, - void *parameter, +rt_uint8_t *rt_hw_stack_init(void *tentry, + void *parameter, rt_uint8_t *stack_addr, - void *texit) + void *texit) { - struct rt_hw_stack_frame *frame; - rt_uint8_t *stk; - int i; - extern int __global_pointer$; - - stk = stack_addr + sizeof(rt_ubase_t); - stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_ubase_t)stk, REGBYTES); - stk -= sizeof(struct rt_hw_stack_frame); - - frame = (struct rt_hw_stack_frame *)stk; - - for (i = 0; i < sizeof(struct rt_hw_stack_frame) / sizeof(rt_ubase_t); i++) - { - ((rt_ubase_t *)frame)[i] = 0xdeadbeef; - } - - frame->ra = (rt_ubase_t)texit; - frame->gp = (rt_ubase_t)&__global_pointer$; - frame->a0 = (rt_ubase_t)parameter; - frame->epc = (rt_ubase_t)tentry; - frame->user_sp_exc_stack = (rt_ubase_t)(((rt_ubase_t)stk) + sizeof(struct rt_hw_stack_frame)); - - /* force to supervisor mode(SPP=1) and set SPIE and SUM to 1 */ -#ifdef ENABLE_FPU - frame->sstatus = 0x00046120; /* enable FPU */ -#else - frame->sstatus = 0x00040120; -#endif - - return stk; + rt_ubase_t *sp = (rt_ubase_t *)stack_addr; + // we use a strict alignment requirement for Q extension + sp = (rt_ubase_t *)RT_ALIGN_DOWN((rt_ubase_t)sp, 16); + + (*--sp) = (rt_ubase_t)tentry; + (*--sp) = (rt_ubase_t)parameter; + (*--sp) = (rt_ubase_t)texit; + + /* compatible to RESTORE_CONTEXT */ + extern void _rt_thread_entry(void); + (*--sp) = 0; /* tp */ + (*--sp) = (rt_ubase_t)_rt_thread_entry; /* ra */ + (*--sp) = 0; /* s0(fp) */ + (*--sp) = 0; /* s1 */ + (*--sp) = 0; /* s2 */ + (*--sp) = 0; /* s3 */ + (*--sp) = 0; /* s4 */ + (*--sp) = 0; /* s5 */ + (*--sp) = 0; /* s6 */ + (*--sp) = 0; /* s7 */ + (*--sp) = 0; /* s8 */ + (*--sp) = 0; /* s9 */ + (*--sp) = 0; /* s10 */ + (*--sp) = 0; /* s11 */ + (*--sp) = K_SSTATUS_DEFAULT; /* sstatus */ + + return (rt_uint8_t *)sp; } /* @@ -98,7 +98,7 @@ void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to, rt_thread_t rt_interrupt_to_thread = to; rt_thread_switch_interrupt_flag = 1; - return ; + return; } #endif /* end of RT_USING_SMP */ @@ -117,6 +117,5 @@ void rt_hw_cpu_shutdown() void rt_hw_set_process_id(int pid) { - //TODO + // TODO } - diff --git a/libcpu/risc-v/virt64/context.h b/libcpu/risc-v/virt64/cpuport_gcc.S similarity index 32% rename from libcpu/risc-v/virt64/context.h rename to libcpu/risc-v/virt64/cpuport_gcc.S index aae39fdc46..cb636c9a4f 100644 --- a/libcpu/risc-v/virt64/context.h +++ b/libcpu/risc-v/virt64/cpuport_gcc.S @@ -5,16 +5,18 @@ * * Change Logs: * Date Author Notes - * 2022-10-10 RT-Thread the first version + * 2022-10-19 RT-Thread the first version */ -#ifndef __CONTEXT_H__ -#define __CONTEXT_H__ +#include "cpuport.h" +#include "stackframe.h" -void rt_hw_vector_ctx_save(void *buf); -void rt_hw_vector_ctx_restore(void *buf); - -void rt_hw_disable_vector(); -void rt_hw_enable_vector(); - -#endif /* __CONTEXT_H__ */ \ No newline at end of file +.global _rt_thread_entry +_rt_thread_entry: + LOAD ra, (sp) /* texit */ + addi sp, sp, 8 + LOAD a0, (sp) /* parameter */ + addi sp, sp, 8 + LOAD t0, (sp) /* tentry */ + addi sp, sp, 8 + jr t0 diff --git a/libcpu/risc-v/virt64/interrupt_gcc.S b/libcpu/risc-v/virt64/interrupt_gcc.S index d2e9bba6e2..413f9e65f9 100644 --- a/libcpu/risc-v/virt64/interrupt_gcc.S +++ b/libcpu/risc-v/virt64/interrupt_gcc.S @@ -11,7 +11,6 @@ * 2021/12/24 JasonHu Add user setting save/restore */ -#define __ASSEMBLY__ #include "cpuport.h" #include "encoding.h" #include "stackframe.h" @@ -28,7 +27,7 @@ trap_entry: la sp, __stack_cpu0 //backup context SAVE_ALL - + RESTORE_SYS_GP //check syscall @@ -50,7 +49,6 @@ trap_entry: beqz s2, spurious_interrupt sw zero, 0(s0) -.global rt_hw_context_switch_interrupt_do rt_hw_context_switch_interrupt_do: //swap to thread kernel stack @@ -85,19 +83,14 @@ copy_context_loop_interrupt: addi t2, t2, 8 bnez s0, copy_context_loop_interrupt - la s0, rt_interrupt_from_thread - LOAD s1, 0(s0) - STORE sp, 0(s1) - - la s0, rt_interrupt_to_thread - LOAD s1, 0(s0) - LOAD sp, 0(s1) - - #ifdef RT_USING_USERSPACE - mv a0, s1 - jal rt_thread_sp_to_thread - jal lwp_mmu_switch - #endif +do_ctx_switch: + la t0, rt_interrupt_from_thread + LOAD a0, 0(t0) + + la t0, rt_interrupt_to_thread + LOAD a1, 0(t0) + + jal rt_hw_context_switch spurious_interrupt: LOAD t0, 2 * REGBYTES(sp) diff --git a/libcpu/risc-v/virt64/riscv_mmu.c b/libcpu/risc-v/virt64/riscv_mmu.c index e08dfc6735..e79ca8b37b 100644 --- a/libcpu/risc-v/virt64/riscv_mmu.c +++ b/libcpu/risc-v/virt64/riscv_mmu.c @@ -30,10 +30,10 @@ void mmu_set_pagetable(rt_ubase_t addr) void mmu_enable_user_page_access() { - set_csr(sstatus, SSTATUS_PUM); + set_csr(sstatus, SSTATUS_SUM); } void mmu_disable_user_page_access() { - clear_csr(sstatus, SSTATUS_PUM); + clear_csr(sstatus, SSTATUS_SUM); } diff --git a/libcpu/risc-v/virt64/startup_gcc.S b/libcpu/risc-v/virt64/startup_gcc.S index cc31cca51f..0655f7fd06 100644 --- a/libcpu/risc-v/virt64/startup_gcc.S +++ b/libcpu/risc-v/virt64/startup_gcc.S @@ -11,7 +11,6 @@ */ #define SSTATUS_FS 0x00006000U /* initial state of FPU, clear to disable */ -#define __ASSEMBLY__ #include boot_hartid: .int diff --git a/libcpu/risc-v/virt64/trap.c b/libcpu/risc-v/virt64/trap.c index cce3227c73..bb751f4a53 100644 --- a/libcpu/risc-v/virt64/trap.c +++ b/libcpu/risc-v/virt64/trap.c @@ -45,7 +45,7 @@ void dump_regs(struct rt_hw_stack_frame *regs) rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SIE) ? "Supervisor Interrupt Enabled" : "Supervisor Interrupt Disabled"); rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SPIE) ? "Last Time Supervisor Interrupt Enabled" : "Last Time Supervisor Interrupt Disabled"); rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SPP) ? "Last Privilege is Supervisor Mode" : "Last Privilege is User Mode"); - rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_PUM) ? "Permit to Access User Page" : "Not Permit to Access User Page"); + rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SUM) ? "Permit to Access User Page" : "Not Permit to Access User Page"); rt_kprintf("\t%s\n", (regs->sstatus & (1 << 19)) ? "Permit to Read Executable-only Page" : "Not Permit to Read Executable-only Page"); rt_size_t satp_v = read_csr(satp); rt_kprintf("satp = 0x%p\n", satp_v); -- Gitee From 579c7f5b77cea9ed7210863144a28bcdcb8acf53 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Sun, 23 Oct 2022 01:28:51 +0800 Subject: [PATCH 04/11] [risc-v] robust backtrace; Avoiding access to illegal memory due to memory corruption --- libcpu/risc-v/virt64/backtrace.c | 7 +++++-- libcpu/risc-v/virt64/encoding.h | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libcpu/risc-v/virt64/backtrace.c b/libcpu/risc-v/virt64/backtrace.c index e60a2d7f0b..8834a9548b 100644 --- a/libcpu/risc-v/virt64/backtrace.c +++ b/libcpu/risc-v/virt64/backtrace.c @@ -18,6 +18,7 @@ static char *_get_elf_name(); void rt_hw_backtrace(rt_uint32_t *ffp, rt_ubase_t sepc) { + extern rt_mmu_info mmu_info; rt_ubase_t *ra; rt_ubase_t *fp; rt_ubase_t vas, vae; @@ -57,15 +58,17 @@ void rt_hw_backtrace(rt_uint32_t *ffp, rt_ubase_t sepc) } ra = fp - 1; - if (*ra < vas || *ra > vae) + if (!rt_hw_mmu_v2p(&mmu_info, ra) || *ra < vas || *ra > vae) break; rt_kprintf(" %p", *ra - 0x04); fp = fp - 2; - if (!fp) + if (!rt_hw_mmu_v2p(&mmu_info, fp)) break; fp = (rt_ubase_t *)(*fp); + if (!fp) + break; } rt_kputs("\r\n"); diff --git a/libcpu/risc-v/virt64/encoding.h b/libcpu/risc-v/virt64/encoding.h index 9f91770f1f..2616b86461 100644 --- a/libcpu/risc-v/virt64/encoding.h +++ b/libcpu/risc-v/virt64/encoding.h @@ -46,7 +46,7 @@ #define SSTATUS_VS_CLEAN 0x00000400 #define SSTATUS_VS_DIRTY 0x00000600 #define SSTATUS_XS 0x00018000 -#define SSTATUS_PUM 0x00040000 +#define SSTATUS_SUM 0x00040000 #define SSTATUS32_SD 0x80000000 #define SSTATUS64_SD 0x8000000000000000 -- Gitee From 73f65c9fbaf89d48a8863705f89efb9becfd25f8 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Tue, 25 Oct 2022 11:30:02 +0800 Subject: [PATCH 05/11] [riscv] interrupt & exception handling rewrite --- components/lwp/arch/risc-v/rv64/lwp_gcc.S | 45 ++----- libcpu/risc-v/virt64/context_gcc.S | 2 + libcpu/risc-v/virt64/interrupt_gcc.S | 138 ++++++++++------------ libcpu/risc-v/virt64/stackframe.h | 33 ++++-- libcpu/risc-v/virt64/startup_gcc.S | 6 +- libcpu/risc-v/virt64/trap.c | 39 +++++- 6 files changed, 135 insertions(+), 128 deletions(-) diff --git a/components/lwp/arch/risc-v/rv64/lwp_gcc.S b/components/lwp/arch/risc-v/rv64/lwp_gcc.S index c41ad5297c..7d0525bab1 100644 --- a/components/lwp/arch/risc-v/rv64/lwp_gcc.S +++ b/components/lwp/arch/risc-v/rv64/lwp_gcc.S @@ -24,6 +24,8 @@ .global arch_start_umode .type arch_start_umode, % function arch_start_umode: + // load kstack for user process + csrw sscratch, a3 li t0, SSTATUS_SPP | SSTATUS_SIE // set as user mode, close interrupt csrc sstatus, t0 li t0, SSTATUS_SPIE // enable interrupt when return to user mode @@ -56,6 +58,8 @@ arch_crt_start_umode: mv sp, a0//user_sp mv ra, a0//return address mv a0, s0//args + + csrw sscratch, a3 sret//enter user mode .global arch_ret_to_user @@ -63,11 +67,13 @@ arch_ret_to_user: call lwp_signal_check beqz a0, ret_to_user_exit RESTORE_ALL - //now sp is user sp + csrw sscratch, zero + // now sp is user sp J user_do_signal ret_to_user_exit: RESTORE_ALL + csrw sscratch, zero sret /*#ifdef RT_USING_LWP @@ -132,6 +138,7 @@ arch_signal_quit: //a0 is user_ctx mv sp, a0 RESTORE_ALL + csrw sscratch, zero sret user_do_signal: @@ -234,36 +241,6 @@ arch_clone_exit: .global syscall_entry syscall_entry: - //swap to thread kernel stack - csrr t0, sstatus - andi t0, t0, 0x100 - beqz t0, __restore_sp_from_tcb - -__restore_sp_from_sscratch: - csrr t0, sscratch - j __move_stack_context - -__restore_sp_from_tcb: - la a0, rt_current_thread - LOAD a0, 0(a0) - jal get_thread_kernel_stack_top - mv t0, a0 - -__move_stack_context: - mv t1, sp//src - mv sp, t0//switch stack - addi sp, sp, -CTX_REG_NR * REGBYTES - //copy context - li s0, CTX_REG_NR//cnt - mv t2, sp//dst - -copy_context_loop: - LOAD t0, 0(t1) - STORE t0, 0(t2) - addi s0, s0, -1 - addi t1, t1, 8 - addi t2, t2, 8 - bnez s0, copy_context_loop LOAD s0, 7 * REGBYTES(sp) addi s0, s0, -0xfe @@ -285,13 +262,12 @@ arch_syscall_exit: CLOSE_INTERRUPT #if defined(RT_USING_USERSPACE) - LOAD s0, 2 * REGBYTES(sp) + LOAD s0, FRAME_OFF_SSTATUS(sp) andi s0, s0, 0x100 bnez s0, dont_ret_to_user - li s0, 0 j arch_ret_to_user - dont_ret_to_user: #endif +dont_ret_to_user: #ifdef RT_USING_USERSPACE /* restore setting when syscall exit */ @@ -304,5 +280,6 @@ arch_syscall_exit: //restore context RESTORE_ALL + csrw sscratch, zero sret diff --git a/libcpu/risc-v/virt64/context_gcc.S b/libcpu/risc-v/virt64/context_gcc.S index 176625a94e..57cf3e3efd 100644 --- a/libcpu/risc-v/virt64/context_gcc.S +++ b/libcpu/risc-v/virt64/context_gcc.S @@ -8,6 +8,8 @@ * 2018/10/28 Bernard The unify RISC-V porting implementation * 2018/12/27 Jesven Add SMP support * 2021/02/02 lizhirui Add userspace support + * 2022/10/22 WangXiaoyao Support User mode RVV; + * Trimming process switch context */ #include "cpuport.h" diff --git a/libcpu/risc-v/virt64/interrupt_gcc.S b/libcpu/risc-v/virt64/interrupt_gcc.S index 413f9e65f9..e6b90b81ea 100644 --- a/libcpu/risc-v/virt64/interrupt_gcc.S +++ b/libcpu/risc-v/virt64/interrupt_gcc.S @@ -9,105 +9,91 @@ * 2018/12/27 Jesven Add SMP schedule * 2021/02/02 lizhirui Add userspace support * 2021/12/24 JasonHu Add user setting save/restore + * 2022/10/22 WangXiaoyao Support kernel mode RVV; + * Rewrite trap handling routine */ #include "cpuport.h" #include "encoding.h" #include "stackframe.h" - .section .text.entry - .align 2 - .global trap_entry - .extern __stack_cpu0 - .extern get_current_thread_kernel_stack_top +#define ARCH_CHECK_SP + + .align 2 + .global trap_entry + .global debug_check_sp trap_entry: - //backup sp - csrrw sp, sscratch, sp - //load interrupt stack - la sp, __stack_cpu0 - //backup context + // distingush exception from kernel or user + csrrw sp, sscratch, sp + bnez sp, _from_user + + // BE REALLY careful with sscratch, + // if it's wrong, we could looping here forever + // or accessing random memory and seeing things totally + // messy after a long time and don't even know why +_from_kernel: + csrr sp, sscratch + j _save_context +_from_user: + nop +_save_context: SAVE_ALL + // clear sscratch to say 'now in kernel mode' + csrw sscratch, zero RESTORE_SYS_GP - //check syscall - csrr t0, scause - li t1, 8//environment call from u-mode - beq t0, t1, syscall_entry - - csrr a0, scause - csrrc a1, stval, zero - csrr a2, sepc - mv a3, sp - - /* scause, stval, sepc, sp */ - call handle_trap - - /* need to switch new thread */ - la s0, rt_thread_switch_interrupt_flag - lw s2, 0(s0) - beqz s2, spurious_interrupt - sw zero, 0(s0) - -rt_hw_context_switch_interrupt_do: - -//swap to thread kernel stack - csrr t0, sstatus - andi t0, t0, 0x100 - beqz t0, __restore_sp_from_tcb_interrupt - -__restore_sp_from_sscratch_interrupt: - csrr t0, sscratch - j __move_stack_context_interrupt - -__restore_sp_from_tcb_interrupt: - la s0, rt_interrupt_from_thread - LOAD a0, 0(s0) - jal rt_thread_sp_to_thread - jal get_thread_kernel_stack_top - mv t0, a0 - -__move_stack_context_interrupt: - mv t1, sp//src - mv sp, t0//switch stack - addi sp, sp, -CTX_REG_NR * REGBYTES - //copy context - li s0, CTX_REG_NR//cnt - mv t2, sp//dst - -copy_context_loop_interrupt: - LOAD t0, 0(t1) - STORE t0, 0(t2) - addi s0, s0, -1 - addi t1, t1, 8 - addi t2, t2, 8 - bnez s0, copy_context_loop_interrupt - -do_ctx_switch: - la t0, rt_interrupt_from_thread - LOAD a0, 0(t0) - - la t0, rt_interrupt_to_thread - LOAD a1, 0(t0) - +#ifdef ARCH_CHECK_SP + mv a0, sp + li a1, 1 + call debug_check_sp +#endif + + // now we are ready to enter interrupt / excepiton handler +_distinguish_syscall: + csrr t0, scause + // TODO swap 8 with config macro name + li t1, 8 + beq t0, t1, syscall_entry + // syscall never return here + +_handle_interrupt_and_exception: + mv a0, t0 + csrrc a1, stval, zero + csrr a2, sepc + // sp as exception frame pointer + mv a3, sp + call handle_trap + +_interrupt_exit: + la s0, rt_thread_switch_interrupt_flag + lw s2, 0(s0) + beqz s2, _resume_execution + sw zero, 0(s0) + +_context_switch: + la t0, rt_interrupt_from_thread + LOAD a0, 0(t0) + la t0, rt_interrupt_to_thread + LOAD a1, 0(t0) jal rt_hw_context_switch -spurious_interrupt: - LOAD t0, 2 * REGBYTES(sp) - andi t0, t0, 0x100 - beqz t0, arch_ret_to_user +_resume_execution: + LOAD t0, FRAME_OFF_SSTATUS(sp) + andi t0, t0, SSTATUS_SPP + beqz t0, arch_ret_to_user +_resume_kernel: RESTORE_ALL + csrw sscratch, zero sret .global rt_hw_interrupt_enable rt_hw_interrupt_enable: - fence.i csrs sstatus, a0 /* restore to old csr */ jr ra .global rt_hw_interrupt_disable rt_hw_interrupt_disable: csrrci a0, sstatus, 2 /* clear SIE */ - fence.i jr ra diff --git a/libcpu/risc-v/virt64/stackframe.h b/libcpu/risc-v/virt64/stackframe.h index 3bc8bc9c32..5b546f01f9 100644 --- a/libcpu/risc-v/virt64/stackframe.h +++ b/libcpu/risc-v/virt64/stackframe.h @@ -8,6 +8,7 @@ * 2021-02-02 lizhirui first version * 2021-02-11 lizhirui fixed gp save/store bug * 2021-11-18 JasonHu add fpu registers save/restore + * 2022/10/22 WangXiaoyao Support kernel mode RVV; */ #ifndef __STACKFRAME_H__ @@ -17,13 +18,10 @@ #include "encoding.h" #include "ext_context.h" -/** - * The register `tp` always save/restore when context switch, - * we call `lwp_user_setting_save` when syscall enter, - * call `lwp_user_setting_restore` when syscall exit - * and modify context stack after `lwp_user_setting_restore` called - * so that the `tp` can be the correct thread area value. - */ +#define BYTES(idx) ((idx) * REGBYTES) +#define FRAME_OFF_SSTATUS BYTES(2) + +#ifdef __ASSEMBLY__ .macro SAVE_ALL @@ -41,10 +39,10 @@ STORE x1, 1 * REGBYTES(sp) csrr x1, sstatus - STORE x1, 2 * REGBYTES(sp) + STORE x1, FRAME_OFF_SSTATUS(sp) csrr x1, sepc - STORE x1, 0 * REGBYTES(sp) + STORE x1, 0 * REGBYTES(sp) STORE x3, 3 * REGBYTES(sp) STORE x4, 4 * REGBYTES(sp) /* save tp */ @@ -140,12 +138,17 @@ #endif /* ENABLE_VECTOR */ .endm +/** + * @brief Restore All General Registers, for interrupt handling + * + */ .macro RESTORE_ALL #ifdef ENABLE_VECTOR // skip on close - csrr t0, sstatus - andi t0, t0, SSTATUS_VS + ld t0, 2 * REGBYTES(sp) + // cannot use vector on initial + andi t0, t0, SSTATUS_VS_CLEAN beqz t0, 0f /* push vector frame */ @@ -204,9 +207,11 @@ #endif /* ENABLE_FPU */ /* restore general register */ + addi t0, sp, CTX_REG_NR * REGBYTES + csrw sscratch, t0 /* resw ra to sepc */ - LOAD x1, 0 * REGBYTES(sp) + LOAD x1, 0 * REGBYTES(sp) csrw sepc, x1 LOAD x1, 2 * REGBYTES(sp) @@ -263,4 +268,6 @@ csrci sstatus, 2 .endm -#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __STACKFRAME_H__ */ diff --git a/libcpu/risc-v/virt64/startup_gcc.S b/libcpu/risc-v/virt64/startup_gcc.S index 0655f7fd06..700f31181d 100644 --- a/libcpu/risc-v/virt64/startup_gcc.S +++ b/libcpu/risc-v/virt64/startup_gcc.S @@ -86,5 +86,9 @@ _start: la sp, __stack_start__ li t0, __STACKSIZE__ add sp, sp, t0 - csrw sscratch, sp + + /** + * sscratch is always zero on kernel mode + */ + csrw sscratch, zero j primary_cpu_entry diff --git a/libcpu/risc-v/virt64/trap.c b/libcpu/risc-v/virt64/trap.c index bb751f4a53..35392559d6 100644 --- a/libcpu/risc-v/virt64/trap.c +++ b/libcpu/risc-v/virt64/trap.c @@ -177,7 +177,7 @@ static void vector_enable(struct rt_hw_stack_frame *sp) sp->sstatus |= SSTATUS_VS_INITIAL; } -/** +/** * detect V/D support, and do not distinguish V/D instruction */ static int illegal_inst_recoverable(rt_ubase_t stval, struct rt_hw_stack_frame *sp) @@ -207,9 +207,34 @@ static int illegal_inst_recoverable(rt_ubase_t stval, struct rt_hw_stack_frame * return flag; } +static void handle_nested_trap_panic( + rt_size_t cause, + rt_size_t tval, + rt_size_t epc, + struct rt_hw_stack_frame *eframe) +{ + LOG_E("\n-------- [SEVER ERROR] --------"); + LOG_E("Nested trap detected"); + LOG_E("scause:0x%p,stval:0x%p,sepc:0x%p\n", cause, tval, epc); + dump_regs(eframe); + rt_hw_cpu_shutdown(); +} + +#ifndef RT_USING_SMP +static volatile int nested = 0; +#define ENTER_TRAP \ + nested += 1 +#define EXIT_TRAP \ + nested -= 1 +#define CHECK_NESTED_PANIC(cause, tval, epc, eframe) \ + if (nested != 1) \ + handle_nested_trap_panic(cause, tval, epc, eframe) +#endif /* RT_USING_SMP */ + /* Trap entry */ void handle_trap(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw_stack_frame *sp) { + ENTER_TRAP; rt_size_t id = __MASKVALUE(scause, __MASK(63UL)); const char *msg; @@ -230,6 +255,8 @@ void handle_trap(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw } else { + // trap cannot nested when handling another trap / interrupt + CHECK_NESTED_PANIC(scause, stval, sepc, sp); rt_size_t id = __MASKVALUE(scause, __MASK(63UL)); const char *msg; @@ -248,16 +275,18 @@ void handle_trap(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw } else { +#ifdef ENABLE_VECTOR if (scause == 0x2) { if (!(sp->sstatus & SSTATUS_VS) && illegal_inst_recoverable(stval, sp)) - return; + goto _exit; } +#endif /* ENABLE_VECTOR */ if (!(sp->sstatus & 0x100)) { handle_user(scause, stval, sepc, sp); // if handle_user() return here, jump to u mode then - return; + goto _exit; } // handle kernel exception: @@ -268,7 +297,6 @@ void handle_trap(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw dump_regs(sp); rt_kprintf("--------------Thread list--------------\n"); rt_kprintf("current thread: %s\n", rt_thread_self()->name); - list_process(); extern struct rt_thread *rt_current_thread; rt_kprintf("--------------Backtrace--------------\n"); @@ -277,4 +305,7 @@ void handle_trap(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw while (1) ; } +_exit: + EXIT_TRAP; + return ; } -- Gitee From e4b8460455d74cc36996d046aa14443decfd1ec5 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Thu, 27 Oct 2022 17:40:21 +0800 Subject: [PATCH 06/11] [lwp/riscv] signal handing fixups: remove close interrupt; fix setting of sp in kernel --- bsp/qemu-virt64-riscv/.config | 6 +- bsp/qemu-virt64-riscv/rtconfig.h | 5 +- components/lwp/arch/risc-v/rv64/lwp_gcc.S | 72 ++++++++++++++++------- 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/bsp/qemu-virt64-riscv/.config b/bsp/qemu-virt64-riscv/.config index 510c8d7745..89eabbb73a 100644 --- a/bsp/qemu-virt64-riscv/.config +++ b/bsp/qemu-virt64-riscv/.config @@ -16,7 +16,7 @@ CONFIG_RT_THREAD_PRIORITY_32=y # CONFIG_RT_THREAD_PRIORITY_256 is not set CONFIG_RT_THREAD_PRIORITY_MAX=32 CONFIG_RT_TICK_PER_SECOND=100 -# CONFIG_RT_USING_OVERFLOW_CHECK is not set +CONFIG_RT_USING_OVERFLOW_CHECK=y CONFIG_RT_USING_HOOK=y CONFIG_RT_USING_IDLE_HOOK=y CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 @@ -102,12 +102,12 @@ CONFIG_RT_USING_MSH=y CONFIG_FINSH_USING_MSH=y CONFIG_FINSH_THREAD_NAME="tshell" CONFIG_FINSH_USING_HISTORY=y -CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_HISTORY_LINES=10 CONFIG_FINSH_USING_SYMTAB=y CONFIG_FINSH_USING_DESCRIPTION=y # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set CONFIG_FINSH_THREAD_PRIORITY=20 -CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_THREAD_STACK_SIZE=16384 CONFIG_FINSH_CMD_SIZE=80 # CONFIG_FINSH_USING_AUTH is not set CONFIG_FINSH_ARG_MAX=10 diff --git a/bsp/qemu-virt64-riscv/rtconfig.h b/bsp/qemu-virt64-riscv/rtconfig.h index 2899d7cca1..ceeee96e64 100644 --- a/bsp/qemu-virt64-riscv/rtconfig.h +++ b/bsp/qemu-virt64-riscv/rtconfig.h @@ -12,6 +12,7 @@ #define RT_THREAD_PRIORITY_32 #define RT_THREAD_PRIORITY_MAX 32 #define RT_TICK_PER_SECOND 100 +#define RT_USING_OVERFLOW_CHECK #define RT_USING_HOOK #define RT_USING_IDLE_HOOK #define RT_IDLE_HOOK_LIST_SIZE 4 @@ -71,11 +72,11 @@ #define FINSH_USING_MSH #define FINSH_THREAD_NAME "tshell" #define FINSH_USING_HISTORY -#define FINSH_HISTORY_LINES 5 +#define FINSH_HISTORY_LINES 10 #define FINSH_USING_SYMTAB #define FINSH_USING_DESCRIPTION #define FINSH_THREAD_PRIORITY 20 -#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_THREAD_STACK_SIZE 16384 #define FINSH_CMD_SIZE 80 #define FINSH_ARG_MAX 10 diff --git a/components/lwp/arch/risc-v/rv64/lwp_gcc.S b/components/lwp/arch/risc-v/rv64/lwp_gcc.S index 7d0525bab1..3640091f5a 100644 --- a/components/lwp/arch/risc-v/rv64/lwp_gcc.S +++ b/components/lwp/arch/risc-v/rv64/lwp_gcc.S @@ -59,15 +59,13 @@ arch_crt_start_umode: mv ra, a0//return address mv a0, s0//args - csrw sscratch, a3 + csrw sscratch, s3 sret//enter user mode .global arch_ret_to_user arch_ret_to_user: call lwp_signal_check beqz a0, ret_to_user_exit - RESTORE_ALL - csrw sscratch, zero // now sp is user sp J user_do_signal @@ -142,14 +140,18 @@ arch_signal_quit: sret user_do_signal: - //now sp is user sp - //save context to user sp + csrw sscratch, sp + RESTORE_ALL + // now sp is user sp + // and in interrupt close SAVE_ALL - //ensure original user sp correct + + // save user sp in SAVE_ALL frame mv t0, sp addi t0, t0, CTX_REG_NR * REGBYTES - STORE t0, CTX_REG_NR * REGBYTES(sp) - OPEN_INTERRUPT + STORE t0, 32 * REGBYTES(sp) + + // save lwp_sigreturn in user memory mv s0, sp la t0, lwp_sigreturn//t0 = src la t1, lwp_sigreturn_end @@ -165,25 +167,53 @@ lwp_sigreturn_copy_loop: mv t1, t2 bnez t1, lwp_sigreturn_copy_loop - mv a0, sp//sp - li a1, 0//pc - li a2, 0//flag + // restore kernel stack + csrrw sp, sscratch, s0 + + /** + * a0: user sp + * a1: user_pc (not used) + * a2: user_flag (not used) + */ + csrr a0, sscratch + mv a1, zero + mv a2, zero call lwp_signal_backup - //a0 = signal id - mv sp, s0//update new sp - mv s2, a0//signal id backup - call lwp_sighandler_get//need a0 returned by lwp_signal_backup - mv ra, s0//lwp_sigreturn func addr - mv s1, s0//if func = 0,s1 = lwp_sigreturn func + // a0 <- signal id + + // restore kernel sp to initial, and load `sp` to user stack + + // s2 <- signal id(a0) + mv s2, a0 + call lwp_sighandler_get + // a0 <- signal_handler + + // ra <- lwp_sigreturn + mv ra, s0 + + mv s1, s0 beqz a0, skip_user_signal_handler + // a0 <- signal_handler mv s1, a0 skip_user_signal_handler: - li t0, 0x100 - csrc sstatus, t0 + // enter user mode and enable interrupt when return to user mode + li t0, SSTATUS_SPP + csrc sstatus, t0 + li t0, SSTATUS_SPIE + csrs sstatus, t0 + + /** + * sp <- user sp + * sscratch <- kernel sp + */ + csrrw sp, sscratch, sp + + // sepc <- signal_handler csrw sepc, s1 - mv a0, s2//signal id as arg 0 - sret//enter lwp signal handler + // a0 <- signal id + mv a0, s2 + sret .align 3 lwp_debugreturn: -- Gitee From 43c387ddc52273a57b41aa36a87597292194e8ee Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Thu, 27 Oct 2022 17:49:53 +0800 Subject: [PATCH 07/11] [libcpu/rv64] using sbi call to shutdown machine --- bsp/qemu-virt64-riscv/rtconfig.py | 8 ++++---- libcpu/risc-v/virt64/backtrace.c | 1 + libcpu/risc-v/virt64/cpuport.c | 10 ++++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/bsp/qemu-virt64-riscv/rtconfig.py b/bsp/qemu-virt64-riscv/rtconfig.py index 9202bd684a..63325f172c 100644 --- a/bsp/qemu-virt64-riscv/rtconfig.py +++ b/bsp/qemu-virt64-riscv/rtconfig.py @@ -37,15 +37,15 @@ if PLATFORM == 'gcc': OBJDUMP = PREFIX + 'objdump' OBJCPY = PREFIX + 'objcopy' - DEVICE = ' -mcmodel=medany -march=rv64imafdc -mabi=lp64' - CFLAGS = DEVICE + ' -fvar-tracking -ffreestanding -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields' - AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + DEVICE = ' -mcmodel=medany -march=rv64imafdc -mabi=lp64 ' + CFLAGS = DEVICE + '-ffreestanding -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields' + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -D__ASSEMBLY__ ' LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,_start -T link.lds' + ' -lsupc++ -lgcc -static' CPATH = '' LPATH = '' if BUILD == 'debug': - CFLAGS += ' -O0 -ggdb' + CFLAGS += ' -O0 -ggdb -fvar-tracking ' AFLAGS += ' -ggdb' else: CFLAGS += ' -O2 -Os' diff --git a/libcpu/risc-v/virt64/backtrace.c b/libcpu/risc-v/virt64/backtrace.c index 8834a9548b..a23f1394ed 100644 --- a/libcpu/risc-v/virt64/backtrace.c +++ b/libcpu/risc-v/virt64/backtrace.c @@ -79,6 +79,7 @@ static void _assert_backtrace_cb(const char *ex, const char *func, rt_size_t lin rt_kprintf("(%s) assertion failed at function:%s, line number:%d \n", ex, func, line); rt_hw_backtrace(0, 0); + rt_hw_cpu_shutdown(); } static int rt_hw_backtrace_init(void) diff --git a/libcpu/risc-v/virt64/cpuport.c b/libcpu/risc-v/virt64/cpuport.c index 0573eceac7..8f5d7461ed 100644 --- a/libcpu/risc-v/virt64/cpuport.c +++ b/libcpu/risc-v/virt64/cpuport.c @@ -14,6 +14,7 @@ #include "cpuport.h" #include "stack.h" +#include "sbi.h" #include @@ -109,10 +110,11 @@ void rt_hw_cpu_shutdown() rt_kprintf("shutdown...\n"); level = rt_hw_interrupt_disable(); - while (level) - { - RT_ASSERT(0); - } + + sbi_shutdown(); + + while (1) + ; } void rt_hw_set_process_id(int pid) -- Gitee From 81aa2a33aef26fcbfa1d9e142ae4801127e7ab27 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Thu, 27 Oct 2022 18:36:57 +0800 Subject: [PATCH 08/11] [libcpu/rv64] improve vector configuration --- libcpu/risc-v/virt64/cpuport.c | 2 +- libcpu/risc-v/virt64/cpuport.h | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libcpu/risc-v/virt64/cpuport.c b/libcpu/risc-v/virt64/cpuport.c index 8f5d7461ed..09f8d0d1aa 100644 --- a/libcpu/risc-v/virt64/cpuport.c +++ b/libcpu/risc-v/virt64/cpuport.c @@ -18,7 +18,7 @@ #include -#define K_SSTATUS_DEFAULT (SSTATUS_SPP | SSTATUS_SPIE | SSTATUS_SUM) +#define K_SSTATUS_DEFAULT (SSTATUS_SPP | SSTATUS_SPIE | SSTATUS_SUM | SSTATUS_FS) /** * @brief from thread used interrupt context switch diff --git a/libcpu/risc-v/virt64/cpuport.h b/libcpu/risc-v/virt64/cpuport.h index 702db34a63..a84cdb2d33 100644 --- a/libcpu/risc-v/virt64/cpuport.h +++ b/libcpu/risc-v/virt64/cpuport.h @@ -34,9 +34,14 @@ #endif #ifdef ENABLE_VECTOR -/* 32 128/256 bits registers, for risc-v 64, we assuming 64 64-bit regs */ -/* TODO we should detect VLEN on the fly */ -#define CTX_VECTOR_REG_NR (64 + 4) + +#if defined(ARCH_VECTOR_VLEN_128) +#define CTX_VECTOR_REGS 64 +#elif defined(ARCH_VECTOR_VLEN_256) +#define CTX_VECTOR_REGS 128 +#endif + +#define CTX_VECTOR_REG_NR (CTX_VECTOR_REGS + 4) #else #define CTX_VECTOR_REG_NR 0 #endif -- Gitee From 310c6f85299c0060110d9cba196f9b2095f64c65 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Thu, 27 Oct 2022 18:55:24 +0800 Subject: [PATCH 09/11] [libcpu/rv64] remove useless code --- bsp/qemu-virt64-riscv/.config | 184 +++++++++++++++++++++- bsp/qemu-virt64-riscv/Kconfig | 4 + bsp/qemu-virt64-riscv/rtconfig.h | 38 ++++- components/lwp/arch/risc-v/rv64/lwp_gcc.S | 39 ++++- libcpu/risc-v/virt64/interrupt_gcc.S | 13 +- 5 files changed, 256 insertions(+), 22 deletions(-) diff --git a/bsp/qemu-virt64-riscv/.config b/bsp/qemu-virt64-riscv/.config index 89eabbb73a..797dd28780 100644 --- a/bsp/qemu-virt64-riscv/.config +++ b/bsp/qemu-virt64-riscv/.config @@ -142,6 +142,7 @@ CONFIG_RT_USING_DFS_DEVFS=y CONFIG_RT_USING_DFS_ROMFS=y # CONFIG_RT_USING_DFS_CROMFS is not set # CONFIG_RT_USING_DFS_RAMFS is not set +# CONFIG_RT_USING_DFS_TMPFS is not set # CONFIG_RT_USING_DFS_UFFS is not set # CONFIG_RT_USING_DFS_JFFS2 is not set # CONFIG_RT_USING_DFS_NFS is not set @@ -562,6 +563,7 @@ CONFIG_RT_LWP_SHM_MAX_NR=64 # CONFIG_PKG_USING_HASH_MATCH is not set # CONFIG_PKG_USING_FIRE_PID_CURVE is not set # CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set # # system packages @@ -597,7 +599,6 @@ CONFIG_RT_LWP_SHM_MAX_NR=64 # CONFIG_PKG_USING_UC_CLK is not set # CONFIG_PKG_USING_UC_COMMON is not set # CONFIG_PKG_USING_UC_MODBUS is not set -# CONFIG_PKG_USING_RTDUINO is not set # CONFIG_PKG_USING_FREERTOS_WRAPPER is not set # CONFIG_PKG_USING_CAIRO is not set # CONFIG_PKG_USING_PIXMAN is not set @@ -632,6 +633,7 @@ CONFIG_RT_LWP_SHM_MAX_NR=64 # CONFIG_PKG_USING_KMULTI_RTIMER is not set # CONFIG_PKG_USING_TFDB is not set # CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set # # peripheral libraries and drivers @@ -643,7 +645,7 @@ CONFIG_RT_LWP_SHM_MAX_NR=64 # CONFIG_PKG_USING_ADT74XX is not set # CONFIG_PKG_USING_AS7341 is not set # CONFIG_PKG_USING_STM32_SDIO is not set -# CONFIG_PKG_USING_RTT_ESP_IDF is not set +# CONFIG_PKG_USING_ESP_IDF is not set # CONFIG_PKG_USING_ICM20608 is not set # CONFIG_PKG_USING_BUTTON is not set # CONFIG_PKG_USING_PCF8574 is not set @@ -798,9 +800,176 @@ CONFIG_RT_LWP_SHM_MAX_NR=64 # CONFIG_PKG_USING_MFBD is not set # CONFIG_PKG_USING_SLCAN2RTT is not set # CONFIG_PKG_USING_SOEM is not set -CONFIG_BOARD_virt=y -CONFIG_ENABLE_FPU=y -# CONFIG_RT_USING_USERSPACE_32BIT_LIMIT is not set +# CONFIG_PKG_USING_QPARAM is not set + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects +# +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set + +# +# Other +# + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set + +# +# Uncategorized +# # # RISC-V QEMU virt64 configs @@ -812,4 +981,9 @@ CONFIG_BSP_USING_VIRTIO_NET=y # CONFIG_BSP_USING_VIRTIO_GPU is not set # CONFIG_BSP_USING_VIRTIO_INPUT is not set # CONFIG_BSP_USING_UART1 is not set +CONFIG_BOARD_QEMU_VIRT_RV64=y +CONFIG_ENABLE_FPU=y +# CONFIG_ENABLE_VECTOR is not set +# CONFIG_RT_USING_USERSPACE_32BIT_LIMIT is not set +CONFIG_ARCH_USING_NEW_CTX_SWITCH=y CONFIG___STACKSIZE__=16384 diff --git a/bsp/qemu-virt64-riscv/Kconfig b/bsp/qemu-virt64-riscv/Kconfig index 0b7da6b9ab..2edc9b2605 100644 --- a/bsp/qemu-virt64-riscv/Kconfig +++ b/bsp/qemu-virt64-riscv/Kconfig @@ -62,6 +62,10 @@ config RT_USING_VIRTIO_MMIO_ALIGN bool "Open packed attribution, this may caused an error on virtio" default n +config ARCH_USING_NEW_CTX_SWITCH + bool + default y + config __STACKSIZE__ int "stack size for interrupt" default 4096 diff --git a/bsp/qemu-virt64-riscv/rtconfig.h b/bsp/qemu-virt64-riscv/rtconfig.h index ceeee96e64..a142be0ca0 100644 --- a/bsp/qemu-virt64-riscv/rtconfig.h +++ b/bsp/qemu-virt64-riscv/rtconfig.h @@ -298,14 +298,48 @@ /* entertainment: terminal games and other interesting software packages */ -#define BOARD_virt -#define ENABLE_FPU + +/* Arduino libraries */ + + +/* Projects */ + + +/* Sensors */ + + +/* Display */ + + +/* Timing */ + + +/* Data Processing */ + + +/* Data Storage */ + +/* Communication */ + + +/* Device Control */ + + +/* Other */ + +/* Signal IO */ + + +/* Uncategorized */ /* RISC-V QEMU virt64 configs */ #define RISCV_S_MODE #define BSP_USING_VIRTIO_BLK #define BSP_USING_VIRTIO_NET +#define BOARD_QEMU_VIRT_RV64 +#define ENABLE_FPU +#define ARCH_USING_NEW_CTX_SWITCH #define __STACKSIZE__ 16384 #endif diff --git a/components/lwp/arch/risc-v/rv64/lwp_gcc.S b/components/lwp/arch/risc-v/rv64/lwp_gcc.S index 3640091f5a..fbf26de6e7 100644 --- a/components/lwp/arch/risc-v/rv64/lwp_gcc.S +++ b/components/lwp/arch/risc-v/rv64/lwp_gcc.S @@ -12,6 +12,7 @@ #include "rtconfig.h" +#define __ASSEMBLY__ #include "cpuport.h" #include "encoding.h" #include "stackframe.h" @@ -71,7 +72,7 @@ arch_ret_to_user: ret_to_user_exit: RESTORE_ALL - csrw sscratch, zero + // `RESTORE_ALL` also reset sp to user sp sret /*#ifdef RT_USING_LWP @@ -130,7 +131,6 @@ lwp_check_debug_quit: //#endif */ -.global arch_signal_quit arch_signal_quit: call lwp_signal_restore //a0 is user_ctx @@ -271,7 +271,38 @@ arch_clone_exit: .global syscall_entry syscall_entry: - +#ifndef ARCH_USING_NEW_CTX_SWITCH + //swap to thread kernel stack + csrr t0, sstatus + andi t0, t0, 0x100 + beqz t0, __restore_sp_from_tcb + +__restore_sp_from_sscratch: + csrr t0, sscratch + j __move_stack_context + +__restore_sp_from_tcb: + la a0, rt_current_thread + LOAD a0, 0(a0) + jal get_thread_kernel_stack_top + mv t0, a0 + +__move_stack_context: + mv t1, sp//src + mv sp, t0//switch stack + addi sp, sp, -CTX_REG_NR * REGBYTES + //copy context + li s0, CTX_REG_NR//cnt + mv t2, sp//dst + +copy_context_loop: + LOAD t0, 0(t1) + STORE t0, 0(t2) + addi s0, s0, -1 + addi t1, t1, 8 + addi t2, t2, 8 + bnez s0, copy_context_loop +#endif /* ARCH_USING_NEW_CTX_SWITCH */ LOAD s0, 7 * REGBYTES(sp) addi s0, s0, -0xfe beqz s0, arch_signal_quit @@ -292,7 +323,7 @@ arch_syscall_exit: CLOSE_INTERRUPT #if defined(RT_USING_USERSPACE) - LOAD s0, FRAME_OFF_SSTATUS(sp) + LOAD s0, 2 * REGBYTES(sp) andi s0, s0, 0x100 bnez s0, dont_ret_to_user j arch_ret_to_user diff --git a/libcpu/risc-v/virt64/interrupt_gcc.S b/libcpu/risc-v/virt64/interrupt_gcc.S index e6b90b81ea..6cc26731f1 100644 --- a/libcpu/risc-v/virt64/interrupt_gcc.S +++ b/libcpu/risc-v/virt64/interrupt_gcc.S @@ -17,15 +17,13 @@ #include "encoding.h" #include "stackframe.h" -#define ARCH_CHECK_SP - .align 2 .global trap_entry .global debug_check_sp trap_entry: // distingush exception from kernel or user csrrw sp, sscratch, sp - bnez sp, _from_user + bnez sp, _save_context // BE REALLY careful with sscratch, // if it's wrong, we could looping here forever @@ -34,8 +32,7 @@ trap_entry: _from_kernel: csrr sp, sscratch j _save_context -_from_user: - nop + _save_context: SAVE_ALL // clear sscratch to say 'now in kernel mode' @@ -43,12 +40,6 @@ _save_context: RESTORE_SYS_GP -#ifdef ARCH_CHECK_SP - mv a0, sp - li a1, 1 - call debug_check_sp -#endif - // now we are ready to enter interrupt / excepiton handler _distinguish_syscall: csrr t0, scause -- Gitee From 4a0f3f06ba9fdd7a18bf8b093fdce50207fc6403 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Fri, 28 Oct 2022 17:30:05 +0800 Subject: [PATCH 10/11] [libcpu/rv64] remove useless code --- bsp/qemu-virt64-riscv/.config | 184 +++++++++++++++++++++- bsp/qemu-virt64-riscv/Kconfig | 4 + bsp/qemu-virt64-riscv/rtconfig.h | 38 ++++- components/lwp/arch/risc-v/rv64/lwp_gcc.S | 39 ++++- libcpu/risc-v/virt64/context_gcc.S | 8 - libcpu/risc-v/virt64/interrupt_gcc.S | 13 +- 6 files changed, 256 insertions(+), 30 deletions(-) diff --git a/bsp/qemu-virt64-riscv/.config b/bsp/qemu-virt64-riscv/.config index 89eabbb73a..797dd28780 100644 --- a/bsp/qemu-virt64-riscv/.config +++ b/bsp/qemu-virt64-riscv/.config @@ -142,6 +142,7 @@ CONFIG_RT_USING_DFS_DEVFS=y CONFIG_RT_USING_DFS_ROMFS=y # CONFIG_RT_USING_DFS_CROMFS is not set # CONFIG_RT_USING_DFS_RAMFS is not set +# CONFIG_RT_USING_DFS_TMPFS is not set # CONFIG_RT_USING_DFS_UFFS is not set # CONFIG_RT_USING_DFS_JFFS2 is not set # CONFIG_RT_USING_DFS_NFS is not set @@ -562,6 +563,7 @@ CONFIG_RT_LWP_SHM_MAX_NR=64 # CONFIG_PKG_USING_HASH_MATCH is not set # CONFIG_PKG_USING_FIRE_PID_CURVE is not set # CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set +# CONFIG_PKG_USING_VOFA_PLUS is not set # # system packages @@ -597,7 +599,6 @@ CONFIG_RT_LWP_SHM_MAX_NR=64 # CONFIG_PKG_USING_UC_CLK is not set # CONFIG_PKG_USING_UC_COMMON is not set # CONFIG_PKG_USING_UC_MODBUS is not set -# CONFIG_PKG_USING_RTDUINO is not set # CONFIG_PKG_USING_FREERTOS_WRAPPER is not set # CONFIG_PKG_USING_CAIRO is not set # CONFIG_PKG_USING_PIXMAN is not set @@ -632,6 +633,7 @@ CONFIG_RT_LWP_SHM_MAX_NR=64 # CONFIG_PKG_USING_KMULTI_RTIMER is not set # CONFIG_PKG_USING_TFDB is not set # CONFIG_PKG_USING_QPC is not set +# CONFIG_PKG_USING_AGILE_UPGRADE is not set # # peripheral libraries and drivers @@ -643,7 +645,7 @@ CONFIG_RT_LWP_SHM_MAX_NR=64 # CONFIG_PKG_USING_ADT74XX is not set # CONFIG_PKG_USING_AS7341 is not set # CONFIG_PKG_USING_STM32_SDIO is not set -# CONFIG_PKG_USING_RTT_ESP_IDF is not set +# CONFIG_PKG_USING_ESP_IDF is not set # CONFIG_PKG_USING_ICM20608 is not set # CONFIG_PKG_USING_BUTTON is not set # CONFIG_PKG_USING_PCF8574 is not set @@ -798,9 +800,176 @@ CONFIG_RT_LWP_SHM_MAX_NR=64 # CONFIG_PKG_USING_MFBD is not set # CONFIG_PKG_USING_SLCAN2RTT is not set # CONFIG_PKG_USING_SOEM is not set -CONFIG_BOARD_virt=y -CONFIG_ENABLE_FPU=y -# CONFIG_RT_USING_USERSPACE_32BIT_LIMIT is not set +# CONFIG_PKG_USING_QPARAM is not set + +# +# Arduino libraries +# +# CONFIG_PKG_USING_RTDUINO is not set + +# +# Projects +# +# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set +# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set +# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set + +# +# Sensors +# +# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set +# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set +# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set +# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set +# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set + +# +# Display +# +# CONFIG_PKG_USING_ARDUINO_U8G2 is not set + +# +# Timing +# +# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set + +# +# Data Processing +# +# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set +# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set + +# +# Data Storage +# + +# +# Communication +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set + +# +# Device Control +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set + +# +# Other +# + +# +# Signal IO +# +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set +# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set + +# +# Uncategorized +# # # RISC-V QEMU virt64 configs @@ -812,4 +981,9 @@ CONFIG_BSP_USING_VIRTIO_NET=y # CONFIG_BSP_USING_VIRTIO_GPU is not set # CONFIG_BSP_USING_VIRTIO_INPUT is not set # CONFIG_BSP_USING_UART1 is not set +CONFIG_BOARD_QEMU_VIRT_RV64=y +CONFIG_ENABLE_FPU=y +# CONFIG_ENABLE_VECTOR is not set +# CONFIG_RT_USING_USERSPACE_32BIT_LIMIT is not set +CONFIG_ARCH_USING_NEW_CTX_SWITCH=y CONFIG___STACKSIZE__=16384 diff --git a/bsp/qemu-virt64-riscv/Kconfig b/bsp/qemu-virt64-riscv/Kconfig index 0b7da6b9ab..2edc9b2605 100644 --- a/bsp/qemu-virt64-riscv/Kconfig +++ b/bsp/qemu-virt64-riscv/Kconfig @@ -62,6 +62,10 @@ config RT_USING_VIRTIO_MMIO_ALIGN bool "Open packed attribution, this may caused an error on virtio" default n +config ARCH_USING_NEW_CTX_SWITCH + bool + default y + config __STACKSIZE__ int "stack size for interrupt" default 4096 diff --git a/bsp/qemu-virt64-riscv/rtconfig.h b/bsp/qemu-virt64-riscv/rtconfig.h index ceeee96e64..a142be0ca0 100644 --- a/bsp/qemu-virt64-riscv/rtconfig.h +++ b/bsp/qemu-virt64-riscv/rtconfig.h @@ -298,14 +298,48 @@ /* entertainment: terminal games and other interesting software packages */ -#define BOARD_virt -#define ENABLE_FPU + +/* Arduino libraries */ + + +/* Projects */ + + +/* Sensors */ + + +/* Display */ + + +/* Timing */ + + +/* Data Processing */ + + +/* Data Storage */ + +/* Communication */ + + +/* Device Control */ + + +/* Other */ + +/* Signal IO */ + + +/* Uncategorized */ /* RISC-V QEMU virt64 configs */ #define RISCV_S_MODE #define BSP_USING_VIRTIO_BLK #define BSP_USING_VIRTIO_NET +#define BOARD_QEMU_VIRT_RV64 +#define ENABLE_FPU +#define ARCH_USING_NEW_CTX_SWITCH #define __STACKSIZE__ 16384 #endif diff --git a/components/lwp/arch/risc-v/rv64/lwp_gcc.S b/components/lwp/arch/risc-v/rv64/lwp_gcc.S index 3640091f5a..fbf26de6e7 100644 --- a/components/lwp/arch/risc-v/rv64/lwp_gcc.S +++ b/components/lwp/arch/risc-v/rv64/lwp_gcc.S @@ -12,6 +12,7 @@ #include "rtconfig.h" +#define __ASSEMBLY__ #include "cpuport.h" #include "encoding.h" #include "stackframe.h" @@ -71,7 +72,7 @@ arch_ret_to_user: ret_to_user_exit: RESTORE_ALL - csrw sscratch, zero + // `RESTORE_ALL` also reset sp to user sp sret /*#ifdef RT_USING_LWP @@ -130,7 +131,6 @@ lwp_check_debug_quit: //#endif */ -.global arch_signal_quit arch_signal_quit: call lwp_signal_restore //a0 is user_ctx @@ -271,7 +271,38 @@ arch_clone_exit: .global syscall_entry syscall_entry: - +#ifndef ARCH_USING_NEW_CTX_SWITCH + //swap to thread kernel stack + csrr t0, sstatus + andi t0, t0, 0x100 + beqz t0, __restore_sp_from_tcb + +__restore_sp_from_sscratch: + csrr t0, sscratch + j __move_stack_context + +__restore_sp_from_tcb: + la a0, rt_current_thread + LOAD a0, 0(a0) + jal get_thread_kernel_stack_top + mv t0, a0 + +__move_stack_context: + mv t1, sp//src + mv sp, t0//switch stack + addi sp, sp, -CTX_REG_NR * REGBYTES + //copy context + li s0, CTX_REG_NR//cnt + mv t2, sp//dst + +copy_context_loop: + LOAD t0, 0(t1) + STORE t0, 0(t2) + addi s0, s0, -1 + addi t1, t1, 8 + addi t2, t2, 8 + bnez s0, copy_context_loop +#endif /* ARCH_USING_NEW_CTX_SWITCH */ LOAD s0, 7 * REGBYTES(sp) addi s0, s0, -0xfe beqz s0, arch_signal_quit @@ -292,7 +323,7 @@ arch_syscall_exit: CLOSE_INTERRUPT #if defined(RT_USING_USERSPACE) - LOAD s0, FRAME_OFF_SSTATUS(sp) + LOAD s0, 2 * REGBYTES(sp) andi s0, s0, 0x100 bnez s0, dont_ret_to_user j arch_ret_to_user diff --git a/libcpu/risc-v/virt64/context_gcc.S b/libcpu/risc-v/virt64/context_gcc.S index 57cf3e3efd..23a0b014e9 100644 --- a/libcpu/risc-v/virt64/context_gcc.S +++ b/libcpu/risc-v/virt64/context_gcc.S @@ -15,14 +15,6 @@ #include "cpuport.h" #include "stackframe.h" -/** - * sstatus -> interrupt frame - * sepc -> interrupt frame - * sscratch -> ? - * sp -> TCB - * tp -> pointer to current TCB - */ - .macro PUSH_8 reg addi sp, sp, -8 STORE \reg, (sp) diff --git a/libcpu/risc-v/virt64/interrupt_gcc.S b/libcpu/risc-v/virt64/interrupt_gcc.S index e6b90b81ea..6cc26731f1 100644 --- a/libcpu/risc-v/virt64/interrupt_gcc.S +++ b/libcpu/risc-v/virt64/interrupt_gcc.S @@ -17,15 +17,13 @@ #include "encoding.h" #include "stackframe.h" -#define ARCH_CHECK_SP - .align 2 .global trap_entry .global debug_check_sp trap_entry: // distingush exception from kernel or user csrrw sp, sscratch, sp - bnez sp, _from_user + bnez sp, _save_context // BE REALLY careful with sscratch, // if it's wrong, we could looping here forever @@ -34,8 +32,7 @@ trap_entry: _from_kernel: csrr sp, sscratch j _save_context -_from_user: - nop + _save_context: SAVE_ALL // clear sscratch to say 'now in kernel mode' @@ -43,12 +40,6 @@ _save_context: RESTORE_SYS_GP -#ifdef ARCH_CHECK_SP - mv a0, sp - li a1, 1 - call debug_check_sp -#endif - // now we are ready to enter interrupt / excepiton handler _distinguish_syscall: csrr t0, scause -- Gitee From 58ec0ec03ec95e7bc2e355ecb36fa2a13937c586 Mon Sep 17 00:00:00 2001 From: wangxiaoyao Date: Mon, 31 Oct 2022 10:32:32 +0800 Subject: [PATCH 11/11] [libcpu/rv64] remove useless code --- .../applications/test/test_vector/test_vector.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp/qemu-virt64-riscv/applications/test/test_vector/test_vector.c b/bsp/qemu-virt64-riscv/applications/test/test_vector/test_vector.c index 9a58704362..50aae80248 100644 --- a/bsp/qemu-virt64-riscv/applications/test/test_vector/test_vector.c +++ b/bsp/qemu-virt64-riscv/applications/test/test_vector/test_vector.c @@ -25,7 +25,7 @@ void rt_hw_vector_ctx_save(void *buf); * to test V extension features * ============================================================== */ -static char *constant = "hello,it's a nice day and i'm happy to see you\nhello,it's a nice day and i'm happy to see you\nRT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统"; +static char *constant = "hello,it's a nice day and i'm happy to see you\n"; #define ARR_SIZE 4096 static char array[ARR_SIZE]; -- Gitee