This is an automated email from the ASF dual-hosted git repository.

masayuki pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 2c6ad5c2bfee33af22c230e9ddbaaec1da5e5fc5
Author: Masayuki Ishikawa <[email protected]>
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
 

Reply via email to