diff --git a/arch/risc-v/src/common/riscv_exception_common.S b/arch/risc-v/src/common/riscv_exception_common.S index a088b66c41c..ecf2a1b684a 100644 --- a/arch/risc-v/src/common/riscv_exception_common.S +++ b/arch/risc-v/src/common/riscv_exception_common.S @@ -92,10 +92,7 @@ exception_common: csrr s0, CSR_EPC REGSTORE s0, REG_EPC(sp) /* exception PC */ -#ifdef CONFIG_ARCH_FPU - mv a0, sp - jal x1, riscv_savefpu /* save FPU context */ -#endif + riscv_savefpu sp /* Setup arg0(exception cause), arg1(context) */ @@ -126,10 +123,6 @@ exception_common: addi sp, sp, XCPTCONTEXT_SIZE #endif -#ifdef CONFIG_ARCH_FPU - jal x1, riscv_restorefpu /* restore FPU context */ -#endif - /* If context switch is needed, return a new sp */ mv sp, a0 @@ -141,8 +134,9 @@ exception_common: csrw CSR_STATUS, s0 load_ctx sp + riscv_loadfpu sp - REGLOAD sp, REG_SP(sp) /* restore original sp */ + REGLOAD sp, REG_SP(sp) /* restore original sp */ /* Return from exception */ diff --git a/arch/risc-v/src/common/riscv_fpu.S b/arch/risc-v/src/common/riscv_fpu.S index 313e68a4beb..3eae438f592 100644 --- a/arch/risc-v/src/common/riscv_fpu.S +++ b/arch/risc-v/src/common/riscv_fpu.S @@ -36,9 +36,6 @@ ************************************************************************************/ .globl riscv_fpuconfig - .globl riscv_savefpu - .globl riscv_restorefpu - .file "riscv_fpu.S" /************************************************************************************ @@ -70,150 +67,4 @@ riscv_fpuconfig: csrwi fcsr, 0 ret -/************************************************************************************ - * Name: riscv_savefpu - * - * Description: - * Given the pointer to a register save area (in A0), save the state of the - * floating point registers. - * - * C Function Prototype: - * void riscv_savefpu(uintptr_t *regs); - * - * Input Parameters: - * regs - A pointer to the register save area in which to save the floating point - * registers - * - * Returned Value: - * None - * - ************************************************************************************/ - - .type riscv_savefpu, function - -riscv_savefpu: - REGLOAD t0, REG_INT_CTX(a0) - li t1, MSTATUS_FS - and t2, t0, t1 - li t1, MSTATUS_FS_DIRTY - bne t2, t1, 1f - li t1, ~MSTATUS_FS - and t0, t0, t1 - li t1, MSTATUS_FS_CLEAN - or t0, t0, t1 - REGSTORE t0, REG_INT_CTX(a0) - - /* Store all floating point registers */ - - FSTORE f0, REG_F0(a0) - FSTORE f1, REG_F1(a0) - FSTORE f2, REG_F2(a0) - FSTORE f3, REG_F3(a0) - FSTORE f4, REG_F4(a0) - FSTORE f5, REG_F5(a0) - FSTORE f6, REG_F6(a0) - FSTORE f7, REG_F7(a0) - FSTORE f8, REG_F8(a0) - FSTORE f9, REG_F9(a0) - FSTORE f10, REG_F10(a0) - FSTORE f11, REG_F11(a0) - FSTORE f12, REG_F12(a0) - FSTORE f13, REG_F13(a0) - FSTORE f14, REG_F14(a0) - FSTORE f15, REG_F15(a0) - FSTORE f16, REG_F16(a0) - FSTORE f17, REG_F17(a0) - FSTORE f18, REG_F18(a0) - FSTORE f19, REG_F19(a0) - FSTORE f20, REG_F20(a0) - FSTORE f21, REG_F21(a0) - FSTORE f22, REG_F22(a0) - FSTORE f23, REG_F23(a0) - FSTORE f24, REG_F24(a0) - FSTORE f25, REG_F25(a0) - FSTORE f26, REG_F26(a0) - FSTORE f27, REG_F27(a0) - FSTORE f28, REG_F28(a0) - FSTORE f29, REG_F29(a0) - FSTORE f30, REG_F30(a0) - FSTORE f31, REG_F31(a0) - - frcsr t0 - REGSTORE t0, REG_FCSR(a0) - -1: - ret - -/************************************************************************************ - * Name: riscv_restorefpu - * - * Description: - * Given the pointer to a register save area (in A0), restore the state of the - * floating point registers. - * - * C Function Prototype: - * void riscv_restorefpu(const uintptr_t *regs); - * - * Input Parameters: - * regs - A pointer to the register save area containing the floating point - * registers. - * - * Returned Value: - * This function does not return anything explicitly. However, it is called from - * interrupt level assembly logic that assumes that r0 is preserved. - * - ************************************************************************************/ - - .type riscv_restorefpu, function - -riscv_restorefpu: - REGLOAD t0, REG_INT_CTX(a0) - li t1, MSTATUS_FS - and t2, t0, t1 - li t1, MSTATUS_FS_INIT - ble t2, t1, 1f - - /* Load all floating point registers */ - - FLOAD f0, REG_F0(a0) - FLOAD f1, REG_F1(a0) - FLOAD f2, REG_F2(a0) - FLOAD f3, REG_F3(a0) - FLOAD f4, REG_F4(a0) - FLOAD f5, REG_F5(a0) - FLOAD f6, REG_F6(a0) - FLOAD f7, REG_F7(a0) - FLOAD f8, REG_F8(a0) - FLOAD f9, REG_F9(a0) - FLOAD f10, REG_F10(a0) - FLOAD f11, REG_F11(a0) - FLOAD f12, REG_F12(a0) - FLOAD f13, REG_F13(a0) - FLOAD f14, REG_F14(a0) - FLOAD f15, REG_F15(a0) - FLOAD f16, REG_F16(a0) - FLOAD f17, REG_F17(a0) - FLOAD f18, REG_F18(a0) - FLOAD f19, REG_F19(a0) - FLOAD f20, REG_F20(a0) - FLOAD f21, REG_F21(a0) - FLOAD f22, REG_F22(a0) - FLOAD f23, REG_F23(a0) - FLOAD f24, REG_F24(a0) - FLOAD f25, REG_F25(a0) - FLOAD f26, REG_F26(a0) - FLOAD f27, REG_F27(a0) - FLOAD f28, REG_F28(a0) - FLOAD f29, REG_F29(a0) - FLOAD f30, REG_F30(a0) - FLOAD f31, REG_F31(a0) - - /* Store the floating point control and status register */ - - REGLOAD t0, REG_FCSR(a0) - fscsr t0 - -1: - ret - #endif /* CONFIG_ARCH_FPU */ diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h index a719d859fb8..667bdc6545f 100644 --- a/arch/risc-v/src/common/riscv_internal.h +++ b/arch/risc-v/src/common/riscv_internal.h @@ -233,12 +233,8 @@ void riscv_exception_attach(void); #ifdef CONFIG_ARCH_FPU void riscv_fpuconfig(void); -void riscv_savefpu(uintptr_t *regs); -void riscv_restorefpu(const uintptr_t *regs); #else # define riscv_fpuconfig() -# define riscv_savefpu(regs) -# define riscv_restorefpu(regs) #endif /* RISC-V PMP Config ********************************************************/ diff --git a/arch/risc-v/src/common/riscv_macros.S b/arch/risc-v/src/common/riscv_macros.S index 76d43eab795..0d43449ff8c 100644 --- a/arch/risc-v/src/common/riscv_macros.S +++ b/arch/risc-v/src/common/riscv_macros.S @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -86,6 +87,75 @@ .endm +/**************************************************************************** + * Name: riscv_savefpu + * + * Parameter: + * in - Pointer to where the save is performed (e.g. sp) + * + * Description: + * Save the FPU context registers (i.e. work / temp / etc). + * + ****************************************************************************/ + +.macro riscv_savefpu in + +#ifdef CONFIG_ARCH_FPU + REGLOAD t0, REG_INT_CTX(\in) + li t1, MSTATUS_FS + and t2, t0, t1 + li t1, MSTATUS_FS_DIRTY + bne t2, t1, skip_save_fpu + li t1, ~MSTATUS_FS + and t0, t0, t1 + li t1, MSTATUS_FS_CLEAN + or t0, t0, t1 + REGSTORE t0, REG_INT_CTX(\in) + + /* Store all floating point registers */ + + FSTORE f0, REG_F0(\in) + FSTORE f1, REG_F1(\in) + FSTORE f2, REG_F2(\in) + FSTORE f3, REG_F3(\in) + FSTORE f4, REG_F4(\in) + FSTORE f5, REG_F5(\in) + FSTORE f6, REG_F6(\in) + FSTORE f7, REG_F7(\in) + FSTORE f8, REG_F8(\in) + FSTORE f9, REG_F9(\in) + FSTORE f10, REG_F10(\in) + FSTORE f11, REG_F11(\in) + FSTORE f12, REG_F12(\in) + FSTORE f13, REG_F13(\in) + FSTORE f14, REG_F14(\in) + FSTORE f15, REG_F15(\in) + FSTORE f16, REG_F16(\in) + FSTORE f17, REG_F17(\in) + FSTORE f18, REG_F18(\in) + FSTORE f19, REG_F19(\in) + FSTORE f20, REG_F20(\in) + FSTORE f21, REG_F21(\in) + FSTORE f22, REG_F22(\in) + FSTORE f23, REG_F23(\in) + FSTORE f24, REG_F24(\in) + FSTORE f25, REG_F25(\in) + FSTORE f26, REG_F26(\in) + FSTORE f27, REG_F27(\in) + FSTORE f28, REG_F28(\in) + FSTORE f29, REG_F29(\in) + FSTORE f30, REG_F30(\in) + FSTORE f31, REG_F31(\in) + + frcsr t0 + REGSTORE t0, REG_FCSR(\in) + +skip_save_fpu: + +#endif + +.endm + /**************************************************************************** * Name: load_ctx * @@ -134,6 +204,72 @@ .endm +/**************************************************************************** + * Name: riscv_loadfpu + * + * Parameter: + * out - Pointer to where the load is performed (e.g. sp) + * + * Description: + * Load the FPU context registers (i.e. work / temp / etc). + * + ****************************************************************************/ + +.macro riscv_loadfpu out + +#ifdef CONFIG_ARCH_FPU + REGLOAD t0, REG_INT_CTX(\out) + li t1, MSTATUS_FS + and t2, t0, t1 + li t1, MSTATUS_FS_INIT + ble t2, t1, skip_load_fpu + + /* Load all floating point registers */ + + FLOAD f0, REG_F0(\out) + FLOAD f1, REG_F1(\out) + FLOAD f2, REG_F2(\out) + FLOAD f3, REG_F3(\out) + FLOAD f4, REG_F4(\out) + FLOAD f5, REG_F5(\out) + FLOAD f6, REG_F6(\out) + FLOAD f7, REG_F7(\out) + FLOAD f8, REG_F8(\out) + FLOAD f9, REG_F9(\out) + FLOAD f10, REG_F10(\out) + FLOAD f11, REG_F11(\out) + FLOAD f12, REG_F12(\out) + FLOAD f13, REG_F13(\out) + FLOAD f14, REG_F14(\out) + FLOAD f15, REG_F15(\out) + FLOAD f16, REG_F16(\out) + FLOAD f17, REG_F17(\out) + FLOAD f18, REG_F18(\out) + FLOAD f19, REG_F19(\out) + FLOAD f20, REG_F20(\out) + FLOAD f21, REG_F21(\out) + FLOAD f22, REG_F22(\out) + FLOAD f23, REG_F23(\out) + FLOAD f24, REG_F24(\out) + FLOAD f25, REG_F25(\out) + FLOAD f26, REG_F26(\out) + FLOAD f27, REG_F27(\out) + FLOAD f28, REG_F28(\out) + FLOAD f29, REG_F29(\out) + FLOAD f30, REG_F30(\out) + FLOAD f31, REG_F31(\out) + + /* Store the floating point control and status register */ + + REGLOAD t0, REG_FCSR(\out) + fscsr t0 + +skip_load_fpu: + +#endif + +.endm + /**************************************************************************** * Name: setintstack * diff --git a/arch/risc-v/src/common/supervisor/riscv_dispatch_syscall.S b/arch/risc-v/src/common/supervisor/riscv_dispatch_syscall.S index d4322eed405..4629d16dfb9 100644 --- a/arch/risc-v/src/common/supervisor/riscv_dispatch_syscall.S +++ b/arch/risc-v/src/common/supervisor/riscv_dispatch_syscall.S @@ -91,10 +91,7 @@ riscv_dispatch_syscall: addi s0, sp, XCPTCONTEXT_SIZE REGSTORE s0, REG_SP(sp) /* original SP */ -#ifdef CONFIG_ARCH_FPU - mv a0, sp - jal x1, riscv_savefpu /* FP registers */ -#endif + riscv_savefpu sp mv a0, sp /* a0 = context */ @@ -112,10 +109,6 @@ riscv_dispatch_syscall: mv sp, a0 /* use sp, as a0 gets wiped */ -#ifdef CONFIG_ARCH_FPU - jal x1, riscv_restorefpu /* FP registers */ -#endif - REGLOAD s0, REG_EPC(sp) /* restore epc */ csrw CSR_EPC, s0 @@ -134,6 +127,7 @@ riscv_dispatch_syscall: csrw CSR_STATUS, s0 load_ctx sp + riscv_loadfpu sp REGLOAD sp, REG_SP(sp) /* restore original sp */