You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ma...@apache.org on 2023/06/19 13:47:42 UTC
[nuttx] 05/06: Revert "riscv/fpu: Restore correct lazy-FPU functionality"
This is an automated email from the ASF dual-hosted git repository.
masayuki pushed a commit to branch revert-9486-riscv_lazyfpu
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 3c1f9145267668d0ff6d6201cbe71d1f53ddec1f
Author: Masayuki Ishikawa <ma...@gmail.com>
AuthorDate: Mon Jun 19 22:47:29 2023 +0900
Revert "riscv/fpu: Restore correct lazy-FPU functionality"
This reverts commit 35c27b5a9a120368e472c29278653206d07abd9b.
---
arch/risc-v/include/irq.h | 82 +++++++---------
arch/risc-v/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 -
arch/risc-v/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 <nuttx/config.h>
@@ -29,24 +29,20 @@
#include <arch/irq.h>
#include <arch/mode.h>
-#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
-
- 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
+ li a0, MSTATUS_FS_INIT
+ csrs CSR_STATUS, a0
- riscv_loadfpu a1
+ fsflags zero
+ fsrm zero
-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