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:
parent
b39d70fe25
commit
91063e85f0
@ -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)
|
||||
|
@ -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_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
|
||||
****************************************************************************/
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user