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.
This commit is contained in:
Ville Juven 2022-05-19 15:48:49 +03:00 committed by Xiang Xiao
parent b39d70fe25
commit 91063e85f0
3 changed files with 66 additions and 21 deletions

View File

@ -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)

View File

@ -28,6 +28,8 @@
#include <nuttx/config.h>
#include <arch/irq.h>
#include "riscv_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@ -60,33 +62,53 @@
* f2831 ft811 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_SIZEOF (13*INT_REG_SIZE)
# 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_FPU_SIZE (0)
#endif
#define VFORK_SIZEOF STACK_ALIGN_UP(VFORK_INT_SIZE + VFORK_FPU_SIZE)
/****************************************************************************
* Public Types
****************************************************************************/

View File

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