You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2022/05/19 12:05:06 UTC

[incubator-nuttx] 01/03: risc-v/vfork: Save correct amount of registers for vfork

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

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

commit ec073d91c7e0eaa0dd70e723b9dd250059e2a111
Author: Ville Juven <vi...@unikie.com>
AuthorDate: Thu May 19 12:01:41 2022 +0300

    risc-v/vfork: Save correct amount of registers for vfork
    
    The original code does not obey RISC-V calling conventions, looks like
    it was copy&pasted from MIPS instead.
---
 arch/risc-v/src/common/riscv_vfork.c | 17 +++++----
 arch/risc-v/src/common/riscv_vfork.h | 70 +++++++++++++++++++-----------------
 2 files changed, 48 insertions(+), 39 deletions(-)

diff --git a/arch/risc-v/src/common/riscv_vfork.c b/arch/risc-v/src/common/riscv_vfork.c
index 7403b94670..02cc421130 100644
--- a/arch/risc-v/src/common/riscv_vfork.c
+++ b/arch/risc-v/src/common/riscv_vfork.c
@@ -206,18 +206,21 @@ pid_t up_vfork(const struct vfork_s *context)
    * indication to the newly started child thread.
    */
 
-  child->cmn.xcp.regs[REG_S0]  = context->s0;  /* Saved register s0 */
   child->cmn.xcp.regs[REG_S1]  = context->s1;  /* Saved register s1 */
   child->cmn.xcp.regs[REG_S2]  = context->s2;  /* Saved register s2 */
-  child->cmn.xcp.regs[REG_S3]  = context->s3;  /* Volatile register s3 */
-  child->cmn.xcp.regs[REG_S4]  = context->s4;  /* Volatile register s4 */
-  child->cmn.xcp.regs[REG_S5]  = context->s5;  /* Volatile register s5 */
-  child->cmn.xcp.regs[REG_S6]  = context->s6;  /* Volatile register s6 */
-  child->cmn.xcp.regs[REG_S7]  = context->s7;  /* Volatile register s7 */
+  child->cmn.xcp.regs[REG_S3]  = context->s3;  /* Saved register s3 */
+  child->cmn.xcp.regs[REG_S4]  = context->s4;  /* Saved register s4 */
+  child->cmn.xcp.regs[REG_S5]  = context->s5;  /* Saved register s5 */
+  child->cmn.xcp.regs[REG_S6]  = context->s6;  /* Saved register s6 */
+  child->cmn.xcp.regs[REG_S7]  = context->s7;  /* Saved register s7 */
+  child->cmn.xcp.regs[REG_S8]  = context->s8;  /* Saved register s8 */
+  child->cmn.xcp.regs[REG_S9]  = context->s9;  /* Saved register s9 */
+  child->cmn.xcp.regs[REG_S10] = context->s10; /* Saved register s10 */
+  child->cmn.xcp.regs[REG_S11] = context->s11; /* Saved register s11 */
 #ifdef CONFIG_RISCV_FRAMEPOINTER
   child->cmn.xcp.regs[REG_FP]  = newfp;        /* Frame pointer */
 #else
-  child->cmn.xcp.regs[REG_S8]  = context->s8;  /* Volatile register s8 */
+  child->cmn.xcp.regs[REG_S0]  = context->s0;  /* Saved register s0 */
 #endif
   child->cmn.xcp.regs[REG_SP]  = newsp;        /* Stack pointer */
 #ifdef RISCV_SAVE_GP
diff --git a/arch/risc-v/src/common/riscv_vfork.h b/arch/risc-v/src/common/riscv_vfork.h
index 24fed6942b..511e42102c 100644
--- a/arch/risc-v/src/common/riscv_vfork.h
+++ b/arch/risc-v/src/common/riscv_vfork.h
@@ -32,35 +32,34 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-/* Register r30 may be a frame pointer in some ABIs.  Or may just be saved
- * register s8.  It makes a difference for vfork handling.
+/* Register x8 may be a frame pointer in some ABIs.  Or may just be saved
+ * register s0.  It makes a difference for vfork handling.
  */
 
 #undef VFORK_HAVE_FP
 
-/* r0      zero   Always has the value 0.
- * r1      at     Temporary generally used by assembler.
- * r2-r3   v0-v1  Used for expression evaluations and to hold the integer and
- *                pointer type function return values.
- * r4-r7   a0-a3  Used for passing arguments to functions; values are not
- *                preserved across function calls.
- * r8-r15  t0-t7  Temporary registers used for expression evaluation; values
- *                are not preserved across function calls.
- * r16-r23 s0-s7  Saved registers; values are preserved across function
- *                calls.
- * r24-r25 t8-t9  Temporary registers used for expression evaluations; values
- *                are not preserved across function calls. When calling
- *                position independent functions r25 must contain the address
- *                of the called function.
- * r26-r27 k0-k1  Used only by the operating system.
- * r28     gp     Global pointer and context pointer.
- * r29     sp     Stack pointer.
- * r30     s8     Saved register (like s0-s7).  If a frame pointer is used,
- *                then this is the frame pointer.
- * r31     ra     Return address.
+/* Register ABI Name Description                        Saver
+ *
+ * x0       zero     Hard-wired zero                    —
+ * x1       ra       Return address                     Caller
+ * x2       sp       Stack pointer                      Callee
+ * x3       gp       Global pointer                     —
+ * x4       tp       Thread pointer                     —
+ * x5–7     t0–2     Temporaries                        Caller
+ * x8       s0/fp    Saved register/frame pointer       Callee
+ * x9       s1       Saved register                     Callee
+ * x10–11   a0–1     Function arguments/return values   Caller
+ * x12–17   a2–7     Function arguments                 Caller
+ * x18–27   s2–11    Saved registers                    Callee
+ * x28–31   t3–6     Temporaries                        Caller
+ * f0–7     ft0–7    FP temporaries                     Caller
+ * f8–9     fs0–1    FP saved registers                 Callee
+ * f10–11   fa0–1    FP arguments/return values         Caller
+ * f12–17   fa2–7    FP arguments                       Caller
+ * f18–27   fs2–11   FP saved registers                 Callee
+ * f28–31   ft8–11   FP temporaries                     Caller
  */
 
-#define VFORK_S0_OFFSET   (0*INT_REG_SIZE)   /* Saved register s0 */
 #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 */
@@ -68,20 +67,24 @@
 #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 (8*INT_REG_SIZE)   /* Frame pointer */
+#  define VFORK_FP_OFFSET (0*INT_REG_SIZE)   /* Frame pointer */
 #else
-#  define VFORK_S8_OFFSET (8*INT_REG_SIZE)   /* Saved register s8 */
+#  define VFORK_S0_OFFSET (0*INT_REG_SIZE)   /* Saved register s0 */
 #endif
 
-#define VFORK_SP_OFFSET   (9*INT_REG_SIZE)   /* Stack pointer*/
-#define VFORK_RA_OFFSET   (10*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 (11*INT_REG_SIZE)  /* Global pointer */
-#  define VFORK_SIZEOF    (12*INT_REG_SIZE)
+#  define VFORK_GP_OFFSET (14*INT_REG_SIZE)  /* Global pointer */
+#  define VFORK_SIZEOF    (15*INT_REG_SIZE)
 #else
-#  define VFORK_SIZEOF    (11*INT_REG_SIZE)
+#  define VFORK_SIZEOF    (13*INT_REG_SIZE)
 #endif
 
 /****************************************************************************
@@ -93,7 +96,6 @@ struct vfork_s
 {
   /* CPU registers */
 
-  uintptr_t s0;   /* Saved register s0 */
   uintptr_t s1;   /* Saved register s1 */
   uintptr_t s2;   /* Saved register s2 */
   uintptr_t s3;   /* Saved register s3 */
@@ -101,10 +103,14 @@ struct vfork_s
   uintptr_t s5;   /* Saved register s5 */
   uintptr_t s6;   /* Saved register s6 */
   uintptr_t s7;   /* Saved register s7 */
+  uintptr_t s8;   /* Saved register s8 */
+  uintptr_t s9;   /* Saved register s9 */
+  uintptr_t s10;  /* Saved register s10 */
+  uintptr_t s11;  /* Saved register s11 */
 #ifdef CONFIG_RISCV_FRAMEPOINTER
   uintptr_t fp;   /* Frame pointer */
 #else
-  uintptr_t s8;   /* Saved register s8 */
+  uintptr_t s0;   /* Saved register s0 */
 #endif
   uintptr_t sp;   /* Stack pointer */
   uintptr_t ra;   /* Return address */