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 */