From 814c07c7928511c8551be2ead06f78f0a0a6785c Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Tue, 29 Mar 2022 22:57:56 +0800 Subject: [PATCH] arch/risc-v: Store/Restore FPU register in exception_common Signed-off-by: Huang Qi --- arch/risc-v/src/common/riscv_copystate.c | 15 +-------------- .../risc-v/src/common/riscv_exception_common.S | 18 ++++++++++++++---- arch/risc-v/src/common/riscv_internal.h | 5 ----- arch/risc-v/src/common/riscv_swint.c | 3 --- 4 files changed, 15 insertions(+), 26 deletions(-) diff --git a/arch/risc-v/src/common/riscv_copystate.c b/arch/risc-v/src/common/riscv_copystate.c index 004aa15dd7..064e1af522 100644 --- a/arch/risc-v/src/common/riscv_copystate.c +++ b/arch/risc-v/src/common/riscv_copystate.c @@ -55,10 +55,6 @@ void riscv_copystate(uintptr_t *dest, uintptr_t *src) { int i; -#ifdef CONFIG_ARCH_FPU - uintptr_t *regs = dest; -#endif - /* In the RISC-V model, the state is copied from the stack to the TCB, * but only a reference is passed to get the state from the TCB. So the * following check avoids copying the TCB save area onto itself: @@ -68,18 +64,9 @@ void riscv_copystate(uintptr_t *dest, uintptr_t *src) { /* save integer registers first */ - for (i = 0; i < INT_XCPT_REGS; i++) + for (i = 0; i < XCPTCONTEXT_REGS; i++) { *dest++ = *src++; } - - /* Save the floating point registers: This will initialize the floating - * registers at indices INT_XCPT_REGS through (XCPTCONTEXT_REGS-1). - * Do this after saving REG_INT_CTX with the ORIGINAL context pointer. - */ - -#ifdef CONFIG_ARCH_FPU - riscv_savefpu(regs); -#endif } } diff --git a/arch/risc-v/src/common/riscv_exception_common.S b/arch/risc-v/src/common/riscv_exception_common.S index 4d5665ac2d..a4dbdc0c23 100644 --- a/arch/risc-v/src/common/riscv_exception_common.S +++ b/arch/risc-v/src/common/riscv_exception_common.S @@ -25,6 +25,8 @@ #include #include +#include "riscv_internal.h" + /**************************************************************************** * Public Symbols ****************************************************************************/ @@ -96,13 +98,18 @@ exception_common: addi s0, sp, XCPTCONTEXT_SIZE REGSTORE s0, REG_X2(sp) /* original SP */ - /* Setup arg0(exception cause), arg1(context) */ - - csrr a0, mcause /* exception cause */ csrr s0, mepc REGSTORE s0, REG_EPC(sp) /* exception PC */ - mv a1, sp /* context = sp */ +#ifdef CONFIG_ARCH_FPU + mv a0, sp + jal x1, riscv_savefpu /* save FPU context */ +#endif + + /* Setup arg0(exception cause), arg1(context) */ + + csrr a0, mcause /* exception cause */ + mv a1, sp /* context = sp */ #if CONFIG_ARCH_INTERRUPTSTACK > 15 /* Load mhartid (cpuid) */ @@ -137,6 +144,9 @@ 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 */ diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h index 6787d1f292..2f1e8886ae 100644 --- a/arch/risc-v/src/common/riscv_internal.h +++ b/arch/risc-v/src/common/riscv_internal.h @@ -68,13 +68,8 @@ * only a reference stored in TCB. */ -#ifdef CONFIG_ARCH_FPU -#define riscv_savestate(regs) (regs = (uintptr_t *)CURRENT_REGS, riscv_savefpu(regs)) -#define riscv_restorestate(regs) (CURRENT_REGS = regs, riscv_restorefpu((uintptr_t *)CURRENT_REGS)) -#else #define riscv_savestate(regs) (regs = (uintptr_t *)CURRENT_REGS) #define riscv_restorestate(regs) (CURRENT_REGS = regs) -#endif #define _START_TEXT &_stext #define _END_TEXT &_etext diff --git a/arch/risc-v/src/common/riscv_swint.c b/arch/risc-v/src/common/riscv_swint.c index 7d14148e1c..dcfa92ef1c 100644 --- a/arch/risc-v/src/common/riscv_swint.c +++ b/arch/risc-v/src/common/riscv_swint.c @@ -223,7 +223,6 @@ int riscv_swint(int irq, void *context, void *arg) { DEBUGASSERT(regs[REG_A1] != 0); CURRENT_REGS = (uintptr_t *)regs[REG_A1]; - riscv_restorefpu((uintptr_t *)CURRENT_REGS); } break; @@ -247,8 +246,6 @@ int riscv_swint(int irq, void *context, void *arg) case SYS_switch_context: { DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0); - riscv_savefpu(regs); - riscv_restorefpu((uintptr_t *)regs[REG_A2]); *(uintptr_t **)regs[REG_A1] = (uintptr_t *)regs; CURRENT_REGS = (uintptr_t *)regs[REG_A2]; }