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

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


The following commit(s) were added to refs/heads/master by this push:
     new 91063e85f0 risc-v/vfork: FPU was not saved correctly
91063e85f0 is described below

commit 91063e85f03cdd58dbedd417ebba2394c9e415be
Author: Ville Juven <ville.ju...@unikie.com>
AuthorDate: Thu May 19 15:48:49 2022 +0300

    risc-v/vfork: FPU was not saved correctly
    
    The FPU register saving upon vfork entry was missing.
    
    Also added macro that tells the actual size of an FPU reg, instead
    of just having a coefficient for qfpu/no-qfpu.
---
 arch/risc-v/include/irq.h            |  4 ++-
 arch/risc-v/src/common/riscv_vfork.h | 58 +++++++++++++++++++++++++-----------
 arch/risc-v/src/common/vfork.S       | 25 ++++++++++++++--
 3 files changed, 66 insertions(+), 21 deletions(-)

diff --git a/arch/risc-v/include/irq.h b/arch/risc-v/include/irq.h
index 9e2206acbf..602e10fe62 100644
--- a/arch/risc-v/include/irq.h
+++ b/arch/risc-v/include/irq.h
@@ -233,8 +233,10 @@
 #  define REG_FCSR_NDX      (INT_XCPT_REGS + FPU_REG_SIZE * 32)
 
 #  define FPU_XCPT_REGS     (FPU_REG_SIZE * 33)
+#  define FPU_REG_FULL_SIZE (INT_REG_SIZE * FPU_REG_SIZE)
 #else /* !CONFIG_ARCH_FPU */
-#  define FPU_XCPT_REGS     0
+#  define FPU_XCPT_REGS     (0)
+#  define FPU_REG_FULL_SIZE (0)
 #endif /* CONFIG_ARCH_FPU */
 
 #define XCPTCONTEXT_REGS    (INT_XCPT_REGS + FPU_XCPT_REGS)
diff --git a/arch/risc-v/src/common/riscv_vfork.h 
b/arch/risc-v/src/common/riscv_vfork.h
index 4f6d3dc3ac..f1eaa0b783 100644
--- a/arch/risc-v/src/common/riscv_vfork.h
+++ b/arch/risc-v/src/common/riscv_vfork.h
@@ -28,6 +28,8 @@
 #include <nuttx/config.h>
 #include <arch/irq.h>
 
+#include "riscv_internal.h"
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
@@ -60,33 +62,53 @@
  * f28–31   ft8–11   FP temporaries                     Caller
  */
 
-#define VFORK_S1_OFFSET   (1*INT_REG_SIZE)   /* Saved register s1 */
-#define VFORK_S2_OFFSET   (2*INT_REG_SIZE)   /* Saved register s2 */
-#define VFORK_S3_OFFSET   (3*INT_REG_SIZE)   /* Saved register s3 */
-#define VFORK_S4_OFFSET   (4*INT_REG_SIZE)   /* Saved register s4 */
-#define VFORK_S5_OFFSET   (5*INT_REG_SIZE)   /* Saved register s5 */
-#define VFORK_S6_OFFSET   (6*INT_REG_SIZE)   /* Saved register s6 */
-#define VFORK_S7_OFFSET   (7*INT_REG_SIZE)   /* Saved register s7 */
-#define VFORK_S8_OFFSET   (8*INT_REG_SIZE)   /* Saved register s8 */
-#define VFORK_S9_OFFSET   (9*INT_REG_SIZE)   /* Saved register s9 */
-#define VFORK_S10_OFFSET  (10*INT_REG_SIZE)  /* Saved register s10 */
-#define VFORK_S11_OFFSET  (11*INT_REG_SIZE)  /* Saved register s11 */
+#define VFORK_S1_OFFSET     (1*INT_REG_SIZE)   /* Saved register s1 */
+#define VFORK_S2_OFFSET     (2*INT_REG_SIZE)   /* Saved register s2 */
+#define VFORK_S3_OFFSET     (3*INT_REG_SIZE)   /* Saved register s3 */
+#define VFORK_S4_OFFSET     (4*INT_REG_SIZE)   /* Saved register s4 */
+#define VFORK_S5_OFFSET     (5*INT_REG_SIZE)   /* Saved register s5 */
+#define VFORK_S6_OFFSET     (6*INT_REG_SIZE)   /* Saved register s6 */
+#define VFORK_S7_OFFSET     (7*INT_REG_SIZE)   /* Saved register s7 */
+#define VFORK_S8_OFFSET     (8*INT_REG_SIZE)   /* Saved register s8 */
+#define VFORK_S9_OFFSET     (9*INT_REG_SIZE)   /* Saved register s9 */
+#define VFORK_S10_OFFSET    (10*INT_REG_SIZE)  /* Saved register s10 */
+#define VFORK_S11_OFFSET    (11*INT_REG_SIZE)  /* Saved register s11 */
 
 #ifdef CONFIG_RISCV_FRAMEPOINTER
-#  define VFORK_FP_OFFSET (0*INT_REG_SIZE)   /* Frame pointer */
+#  define VFORK_FP_OFFSET   (0*INT_REG_SIZE)   /* Frame pointer */
 #else
-#  define VFORK_S0_OFFSET (0*INT_REG_SIZE)   /* Saved register s0 */
+#  define VFORK_S0_OFFSET   (0*INT_REG_SIZE)   /* Saved register s0 */
 #endif
 
-#define VFORK_SP_OFFSET   (12*INT_REG_SIZE)  /* Stack pointer*/
-#define VFORK_RA_OFFSET   (13*INT_REG_SIZE)  /* Return address*/
+#define VFORK_SP_OFFSET     (12*INT_REG_SIZE)  /* Stack pointer*/
+#define VFORK_RA_OFFSET     (13*INT_REG_SIZE)  /* Return address*/
 #ifdef RISCV_SAVE_GP
-#  define VFORK_GP_OFFSET (14*INT_REG_SIZE)  /* Global pointer */
-#  define VFORK_SIZEOF    (15*INT_REG_SIZE)
+#  define VFORK_GP_OFFSET   (14*INT_REG_SIZE)  /* Global pointer */
+#  define VFORK_INT_SIZE    (15*INT_REG_SIZE)
+#else
+#  define VFORK_INT_SIZE    (14*INT_REG_SIZE)
+#endif
+
+#ifdef CONFIG_ARCH_FPU
+#  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)
+#  define VFORK_FS3_OFFSET  (VFORK_INT_SIZE + 3*FPU_REG_FULL_SIZE)
+#  define VFORK_FS4_OFFSET  (VFORK_INT_SIZE + 4*FPU_REG_FULL_SIZE)
+#  define VFORK_FS5_OFFSET  (VFORK_INT_SIZE + 5*FPU_REG_FULL_SIZE)
+#  define VFORK_FS6_OFFSET  (VFORK_INT_SIZE + 6*FPU_REG_FULL_SIZE)
+#  define VFORK_FS7_OFFSET  (VFORK_INT_SIZE + 7*FPU_REG_FULL_SIZE)
+#  define VFORK_FS8_OFFSET  (VFORK_INT_SIZE + 8*FPU_REG_FULL_SIZE)
+#  define VFORK_FS9_OFFSET  (VFORK_INT_SIZE + 9*FPU_REG_FULL_SIZE)
+#  define VFORK_FS10_OFFSET (VFORK_INT_SIZE + 10*FPU_REG_FULL_SIZE)
+#  define VFORK_FS11_OFFSET (VFORK_INT_SIZE + 11*FPU_REG_FULL_SIZE)
+#  define VFORK_FPU_SIZE    (12*FPU_REG_FULL_SIZE)
 #else
-#  define VFORK_SIZEOF    (13*INT_REG_SIZE)
+#  define VFORK_FPU_SIZE    (0)
 #endif
 
+#define VFORK_SIZEOF        STACK_ALIGN_UP(VFORK_INT_SIZE + VFORK_FPU_SIZE)
+
 /****************************************************************************
  * Public Types
  ****************************************************************************/
diff --git a/arch/risc-v/src/common/vfork.S b/arch/risc-v/src/common/vfork.S
index 379f5fa3bf..d4283457ad 100644
--- a/arch/risc-v/src/common/vfork.S
+++ b/arch/risc-v/src/common/vfork.S
@@ -95,7 +95,6 @@ vfork:
   /* CPU registers */
   /* Save the volatile registers */
 
-  REGSTORE    s0, VFORK_S0_OFFSET(sp)
   REGSTORE    s1, VFORK_S1_OFFSET(sp)
   REGSTORE    s2, VFORK_S2_OFFSET(sp)
   REGSTORE    s3, VFORK_S3_OFFSET(sp)
@@ -103,17 +102,39 @@ vfork:
   REGSTORE    s5, VFORK_S5_OFFSET(sp)
   REGSTORE    s6, VFORK_S6_OFFSET(sp)
   REGSTORE    s7, VFORK_S7_OFFSET(sp)
+  REGSTORE    s8, VFORK_S8_OFFSET(sp)
+  REGSTORE    s9, VFORK_S9_OFFSET(sp)
+  REGSTORE    s10, VFORK_S10_OFFSET(sp)
+  REGSTORE    s11, VFORK_S11_OFFSET(sp)
 
   /* Save the frame pointer, stack pointer, and return address */
 
 #ifdef CONFIG_RISCV_FRAMEPOINTER
   REGSTORE    fp, VFORK_FP_OFFSET(sp)
+#else
+  REGSTORE    s0, VFORK_S0_OFFSET(sp)
 #endif
+
   addi        s0, sp, VFORK_SIZEOF
   REGSTORE    s0, VFORK_SP_OFFSET(sp) /* original SP */
   REGSTORE    x1, VFORK_RA_OFFSET(sp) /* return address */
 
-  /* Floating point registers (not yet) */
+  /* Floating point registers */
+
+#ifdef CONFIG_ARCH_FPU
+  FSTORE      fs0, VFORK_FS0_OFFSET(sp)
+  FSTORE      fs1, VFORK_FS1_OFFSET(sp)
+  FSTORE      fs2, VFORK_FS2_OFFSET(sp)
+  FSTORE      fs3, VFORK_FS3_OFFSET(sp)
+  FSTORE      fs4, VFORK_FS4_OFFSET(sp)
+  FSTORE      fs5, VFORK_FS5_OFFSET(sp)
+  FSTORE      fs6, VFORK_FS6_OFFSET(sp)
+  FSTORE      fs7, VFORK_FS7_OFFSET(sp)
+  FSTORE      fs8, VFORK_FS8_OFFSET(sp)
+  FSTORE      fs9, VFORK_FS9_OFFSET(sp)
+  FSTORE      fs10, VFORK_FS10_OFFSET(sp)
+  FSTORE      fs11, VFORK_FS11_OFFSET(sp)
+#endif
 
   /* Then, call up_vfork(), passing it a pointer to the stack frame */
 

Reply via email to