From 2c6ad5c2bfee33af22c230e9ddbaaec1da5e5fc5 Mon Sep 17 00:00:00 2001 From: Masayuki Ishikawa Date: Mon, 19 Jun 2023 22:47:29 +0900 Subject: [PATCH] Revert "riscv/fpu: Restore correct lazy-FPU functionality" This reverts commit 35c27b5a9a120368e472c29278653206d07abd9b. --- arch/risc-v/include/irq.h | 82 ++++++------- .../src/common/riscv_exception_common.S | 4 + arch/risc-v/src/common/riscv_fpu.S | 113 +++--------------- arch/risc-v/src/common/riscv_internal.h | 16 --- arch/risc-v/src/common/riscv_macros.S | 30 +++++ arch/risc-v/src/common/riscv_swint.c | 6 +- arch/risc-v/src/common/riscv_vfork.c | 24 ++-- arch/risc-v/src/common/riscv_vfork.h | 1 - .../src/common/supervisor/riscv_syscall.S | 4 + 9 files changed, 106 insertions(+), 174 deletions(-) diff --git a/arch/risc-v/include/irq.h b/arch/risc-v/include/irq.h index 0ab74886e8..a566492e89 100644 --- a/arch/risc-v/include/irq.h +++ b/arch/risc-v/include/irq.h @@ -204,52 +204,50 @@ #endif #ifdef CONFIG_ARCH_FPU -# define REG_F0_NDX (FPU_REG_SIZE * 0) -# define REG_F1_NDX (FPU_REG_SIZE * 1) -# define REG_F2_NDX (FPU_REG_SIZE * 2) -# define REG_F3_NDX (FPU_REG_SIZE * 3) -# define REG_F4_NDX (FPU_REG_SIZE * 4) -# define REG_F5_NDX (FPU_REG_SIZE * 5) -# define REG_F6_NDX (FPU_REG_SIZE * 6) -# define REG_F7_NDX (FPU_REG_SIZE * 7) -# define REG_F8_NDX (FPU_REG_SIZE * 8) -# define REG_F9_NDX (FPU_REG_SIZE * 9) -# define REG_F10_NDX (FPU_REG_SIZE * 10) -# define REG_F11_NDX (FPU_REG_SIZE * 11) -# define REG_F12_NDX (FPU_REG_SIZE * 12) -# define REG_F13_NDX (FPU_REG_SIZE * 13) -# define REG_F14_NDX (FPU_REG_SIZE * 14) -# define REG_F15_NDX (FPU_REG_SIZE * 15) -# define REG_F16_NDX (FPU_REG_SIZE * 16) -# define REG_F17_NDX (FPU_REG_SIZE * 17) -# define REG_F18_NDX (FPU_REG_SIZE * 18) -# define REG_F19_NDX (FPU_REG_SIZE * 19) -# define REG_F20_NDX (FPU_REG_SIZE * 20) -# define REG_F21_NDX (FPU_REG_SIZE * 21) -# define REG_F22_NDX (FPU_REG_SIZE * 22) -# define REG_F23_NDX (FPU_REG_SIZE * 23) -# define REG_F24_NDX (FPU_REG_SIZE * 24) -# define REG_F25_NDX (FPU_REG_SIZE * 25) -# define REG_F26_NDX (FPU_REG_SIZE * 26) -# define REG_F27_NDX (FPU_REG_SIZE * 27) -# define REG_F28_NDX (FPU_REG_SIZE * 28) -# define REG_F29_NDX (FPU_REG_SIZE * 29) -# define REG_F30_NDX (FPU_REG_SIZE * 30) -# define REG_F31_NDX (FPU_REG_SIZE * 31) -# define REG_FCSR_NDX (FPU_REG_SIZE * 32) +# define REG_F0_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 0) +# define REG_F1_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 1) +# define REG_F2_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 2) +# define REG_F3_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 3) +# define REG_F4_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 4) +# define REG_F5_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 5) +# define REG_F6_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 6) +# define REG_F7_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 7) +# define REG_F8_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 8) +# define REG_F9_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 9) +# define REG_F10_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 10) +# define REG_F11_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 11) +# define REG_F12_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 12) +# define REG_F13_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 13) +# define REG_F14_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 14) +# define REG_F15_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 15) +# define REG_F16_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 16) +# define REG_F17_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 17) +# define REG_F18_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 18) +# define REG_F19_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 19) +# define REG_F20_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 20) +# define REG_F21_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 21) +# define REG_F22_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 22) +# define REG_F23_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 23) +# define REG_F24_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 24) +# define REG_F25_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 25) +# define REG_F26_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 26) +# define REG_F27_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 27) +# define REG_F28_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 28) +# define REG_F29_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 29) +# define REG_F30_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 30) +# define REG_F31_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 31) +# define REG_FCSR_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 32) # define FPU_XCPT_REGS (FPU_REG_SIZE * 33) -# define FPU_XCPT_SIZE (INT_REG_SIZE * FPU_XCPT_REGS) +# define FPU_REG_FULL_SIZE (INT_REG_SIZE * FPU_REG_SIZE) #else /* !CONFIG_ARCH_FPU */ # define FPU_XCPT_REGS (0) -# define FPU_XCPT_SIZE (0) +# define FPU_REG_FULL_SIZE (0) #endif /* CONFIG_ARCH_FPU */ #define XCPTCONTEXT_REGS (INT_XCPT_REGS + FPU_XCPT_REGS) -/* Save only integer regs. FPU is handled separately */ - -#define XCPTCONTEXT_SIZE (INT_XCPT_SIZE) +#define XCPTCONTEXT_SIZE (INT_REG_SIZE * XCPTCONTEXT_REGS) /* In assembly language, values have to be referenced as byte address * offsets. But in C, it is more convenient to reference registers as @@ -564,15 +562,9 @@ struct xcptcontext #endif #endif - /* Integer register save area */ + /* Register save area */ uintptr_t *regs; - - /* FPU register save area */ - -#ifdef CONFIG_ARCH_FPU - uintptr_t fregs[FPU_XCPT_SIZE]; -#endif }; #endif /* __ASSEMBLY__ */ diff --git a/arch/risc-v/src/common/riscv_exception_common.S b/arch/risc-v/src/common/riscv_exception_common.S index 9d78b65c09..1f1180d46b 100644 --- a/arch/risc-v/src/common/riscv_exception_common.S +++ b/arch/risc-v/src/common/riscv_exception_common.S @@ -113,6 +113,8 @@ exception_common: csrr s0, CSR_EPC REGSTORE s0, REG_EPC(sp) /* exception PC */ + riscv_savefpu sp + /* Setup arg0(exception cause), arg1(context) */ csrr a0, CSR_CAUSE /* exception cause */ @@ -146,6 +148,8 @@ exception_common: mv sp, a0 + riscv_loadfpu sp + REGLOAD s0, REG_EPC(sp) /* restore sepc */ csrw CSR_EPC, s0 diff --git a/arch/risc-v/src/common/riscv_fpu.S b/arch/risc-v/src/common/riscv_fpu.S index 9d5feb9390..84989ccbf3 100644 --- a/arch/risc-v/src/common/riscv_fpu.S +++ b/arch/risc-v/src/common/riscv_fpu.S @@ -1,4 +1,4 @@ -/**************************************************************************** +/************************************************************************************ * arch/risc-v/src/common/riscv_fpu.S * * Licensed to the Apache Software Foundation (ASF) under one or more @@ -16,11 +16,11 @@ * License for the specific language governing permissions and limitations * under the License. * - ****************************************************************************/ + ************************************************************************************/ -/**************************************************************************** +/************************************************************************************ * Included Files - ****************************************************************************/ + ************************************************************************************/ #include @@ -29,24 +29,20 @@ #include #include -#include "riscv_macros.S" - #ifdef CONFIG_ARCH_FPU -/**************************************************************************** +/************************************************************************************ * Public Symbols - ****************************************************************************/ + ************************************************************************************/ .globl riscv_fpuconfig - .globl riscv_savefpu - .globl riscv_restorefpu .file "riscv_fpu.S" -/**************************************************************************** +/************************************************************************************ * Public Functions - ****************************************************************************/ + ************************************************************************************/ -/**************************************************************************** +/************************************************************************************ * Name: riscv_fpuconfig * * Description: @@ -61,95 +57,18 @@ * Returned Value: * This function does not return anything explicitly. * - ****************************************************************************/ + ************************************************************************************/ .type riscv_fpuconfig, function riscv_fpuconfig: - li a0, MSTATUS_FS_INIT - csrs CSR_STATUS, a0 + li a0, MSTATUS_FS_INIT + csrs CSR_STATUS, a0 - fsflags zero - fsrm zero + fsflags zero + fsrm zero - fence.i - 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, uintptr_t *fregs); - * - * Input Parameters: - * regs - A pointer to the integer registers that contain the status - * fregs - 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) - - riscv_savefpu a1 - -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(uintptr_t *regs, uintptr_t *fregs); - * - * Input Parameters: - * regs - A pointer to the integer registers that contain the status - * fregs - 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 - - riscv_loadfpu a1 - -1: - ret + fence.i + 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 e890a30d8e..6b385818cb 100644 --- a/arch/risc-v/src/common/riscv_internal.h +++ b/arch/risc-v/src/common/riscv_internal.h @@ -204,12 +204,8 @@ void riscv_exception_attach(void); #ifdef CONFIG_ARCH_FPU void riscv_fpuconfig(void); -void riscv_savefpu(uintptr_t *regs, uintptr_t *fregs); -void riscv_restorefpu(uintptr_t *regs, uintptr_t *fregs); #else # define riscv_fpuconfig() -# define riscv_savefpu(regs, fregs) -# define riscv_restorefpu(regs, fregs) #endif /* Save / restore context of task */ @@ -217,23 +213,11 @@ void riscv_restorefpu(uintptr_t *regs, uintptr_t *fregs); static inline void riscv_savecontext(struct tcb_s *tcb) { tcb->xcp.regs = (uintptr_t *)CURRENT_REGS; - -#ifdef CONFIG_ARCH_FPU - /* Save current process FPU state to TCB */ - - riscv_savefpu(tcb->xcp.regs, tcb->xcp.fregs); -#endif } static inline void riscv_restorecontext(struct tcb_s *tcb) { CURRENT_REGS = (uintptr_t *)tcb->xcp.regs; - -#ifdef CONFIG_ARCH_FPU - /* Restore FPU after the new address environment is instantiated */ - - riscv_restorefpu(tcb->xcp.regs, tcb->xcp.fregs); -#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 5f9bd12f65..83626b05b0 100644 --- a/arch/risc-v/src/common/riscv_macros.S +++ b/arch/risc-v/src/common/riscv_macros.S @@ -100,6 +100,13 @@ .macro riscv_savefpu in +#ifdef CONFIG_ARCH_FPU + REGLOAD t0, REG_INT_CTX(\in) + li t1, MSTATUS_FS + and t0, t0, t1 + li t1, MSTATUS_FS_INIT + ble t0, t1, 1f + /* Store all floating point registers */ FSTORE f0, REG_F0(\in) @@ -138,6 +145,14 @@ frcsr t0 REGSTORE t0, REG_FCSR(\in) +1: + + /* Restore what we have just destroyed (t0, t1) */ + + REGLOAD t0, REG_T0(\in) + REGLOAD t1, REG_T1(\in) +#endif + .endm /**************************************************************************** @@ -201,6 +216,13 @@ .macro riscv_loadfpu out +#ifdef CONFIG_ARCH_FPU + REGLOAD t0, REG_INT_CTX(\out) + li t1, MSTATUS_FS + and t0, t0, t1 + li t1, MSTATUS_FS_INIT + ble t0, t1, 1f + /* Load all floating point registers */ FLOAD f0, REG_F0(\out) @@ -241,6 +263,14 @@ REGLOAD t0, REG_FCSR(\out) fscsr t0 +1: + + /* Restore what we have just destroyed (t0, t1) */ + + REGLOAD t0, REG_T0(\out) + REGLOAD t1, REG_T1(\out) +#endif + .endm /**************************************************************************** diff --git a/arch/risc-v/src/common/riscv_swint.c b/arch/risc-v/src/common/riscv_swint.c index 0a262fe700..dc2c11f00e 100644 --- a/arch/risc-v/src/common/riscv_swint.c +++ b/arch/risc-v/src/common/riscv_swint.c @@ -153,7 +153,7 @@ int riscv_swint(int irq, void *context, void *arg) struct tcb_s *next = (struct tcb_s *)regs[REG_A1]; DEBUGASSERT(regs[REG_A1] != 0); - riscv_restorecontext(next); + CURRENT_REGS = (uintptr_t *)next->xcp.regs; } break; @@ -180,8 +180,8 @@ int riscv_swint(int irq, void *context, void *arg) struct tcb_s *next = (struct tcb_s *)regs[REG_A2]; DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0); - riscv_savecontext(prev); - riscv_restorecontext(next); + prev->xcp.regs = (uintptr_t *)CURRENT_REGS; + CURRENT_REGS = (uintptr_t *)next->xcp.regs; } break; diff --git a/arch/risc-v/src/common/riscv_vfork.c b/arch/risc-v/src/common/riscv_vfork.c index 4446b6b708..b2def7a8a0 100644 --- a/arch/risc-v/src/common/riscv_vfork.c +++ b/arch/risc-v/src/common/riscv_vfork.c @@ -227,18 +227,18 @@ pid_t up_vfork(const struct vfork_s *context) child->cmn.xcp.regs[REG_GP] = newsp; /* Global pointer */ #endif #ifdef CONFIG_ARCH_FPU - child->cmn.xcp.fregs[REG_FS0] = context->fs0; /* Saved register fs1 */ - child->cmn.xcp.fregs[REG_FS1] = context->fs1; /* Saved register fs1 */ - child->cmn.xcp.fregs[REG_FS2] = context->fs2; /* Saved register fs2 */ - child->cmn.xcp.fregs[REG_FS3] = context->fs3; /* Saved register fs3 */ - child->cmn.xcp.fregs[REG_FS4] = context->fs4; /* Saved register fs4 */ - child->cmn.xcp.fregs[REG_FS5] = context->fs5; /* Saved register fs5 */ - child->cmn.xcp.fregs[REG_FS6] = context->fs6; /* Saved register fs6 */ - child->cmn.xcp.fregs[REG_FS7] = context->fs7; /* Saved register fs7 */ - child->cmn.xcp.fregs[REG_FS8] = context->fs8; /* Saved register fs8 */ - child->cmn.xcp.fregs[REG_FS9] = context->fs9; /* Saved register fs9 */ - child->cmn.xcp.fregs[REG_FS10] = context->fs10; /* Saved register fs10 */ - child->cmn.xcp.fregs[REG_FS11] = context->fs11; /* Saved register fs11 */ + child->cmn.xcp.regs[REG_FS0] = context->fs0; /* Saved register fs1 */ + child->cmn.xcp.regs[REG_FS1] = context->fs1; /* Saved register fs1 */ + child->cmn.xcp.regs[REG_FS2] = context->fs2; /* Saved register fs2 */ + child->cmn.xcp.regs[REG_FS3] = context->fs3; /* Saved register fs3 */ + child->cmn.xcp.regs[REG_FS4] = context->fs4; /* Saved register fs4 */ + child->cmn.xcp.regs[REG_FS5] = context->fs5; /* Saved register fs5 */ + child->cmn.xcp.regs[REG_FS6] = context->fs6; /* Saved register fs6 */ + child->cmn.xcp.regs[REG_FS7] = context->fs7; /* Saved register fs7 */ + child->cmn.xcp.regs[REG_FS8] = context->fs8; /* Saved register fs8 */ + child->cmn.xcp.regs[REG_FS9] = context->fs9; /* Saved register fs9 */ + child->cmn.xcp.regs[REG_FS10] = context->fs10; /* Saved register fs10 */ + child->cmn.xcp.regs[REG_FS11] = context->fs11; /* Saved register fs11 */ #endif #ifdef CONFIG_LIB_SYSCALL diff --git a/arch/risc-v/src/common/riscv_vfork.h b/arch/risc-v/src/common/riscv_vfork.h index f754eb082c..f1eaa0b783 100644 --- a/arch/risc-v/src/common/riscv_vfork.h +++ b/arch/risc-v/src/common/riscv_vfork.h @@ -90,7 +90,6 @@ #endif #ifdef CONFIG_ARCH_FPU -# define FPU_REG_FULL_SIZE (INT_REG_SIZE * FPU_REG_SIZE) # define VFORK_FS0_OFFSET (VFORK_INT_SIZE + 0*FPU_REG_FULL_SIZE) # define VFORK_FS1_OFFSET (VFORK_INT_SIZE + 1*FPU_REG_FULL_SIZE) # define VFORK_FS2_OFFSET (VFORK_INT_SIZE + 2*FPU_REG_FULL_SIZE) diff --git a/arch/risc-v/src/common/supervisor/riscv_syscall.S b/arch/risc-v/src/common/supervisor/riscv_syscall.S index 3e4515fea7..18804a49f1 100644 --- a/arch/risc-v/src/common/supervisor/riscv_syscall.S +++ b/arch/risc-v/src/common/supervisor/riscv_syscall.S @@ -109,6 +109,8 @@ sys_call6: addi s0, sp, XCPTCONTEXT_SIZE REGSTORE s0, REG_SP(sp) /* original SP */ + riscv_savefpu sp + mv a0, sp /* a0 = context */ #if CONFIG_ARCH_INTERRUPTSTACK > 15 @@ -125,6 +127,8 @@ sys_call6: mv sp, a0 /* use sp, as a0 gets wiped */ + riscv_loadfpu sp + REGLOAD s0, REG_EPC(sp) /* restore epc */ csrw CSR_EPC, s0