Skip to content

Commit

Permalink
arm64: save FPU regs every time
Browse files Browse the repository at this point in the history
Signed-off-by: ligd <[email protected]>
Signed-off-by: lipengfei28 <[email protected]>
  • Loading branch information
GUIDINGLI authored and lipengfei28 committed Sep 20, 2024
1 parent 444420e commit 6759fc1
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 359 deletions.
3 changes: 3 additions & 0 deletions arch/arm64/src/common/arm64_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,9 @@ struct regs_context
uint64_t spsr;
uint64_t sp_el0;
uint64_t exe_depth;
#ifdef CONFIG_ARCH_FPU
struct fpu_reg fpu_regs;
#endif
};

/****************************************************************************
Expand Down
6 changes: 0 additions & 6 deletions arch/arm64/src/common/arm64_exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,6 @@ void up_exit(int status)
*/

enter_critical_section();

/* Destroy the task at the head of the ready to run list. */
#ifdef CONFIG_ARCH_FPU
arm64_destory_fpu(tcb);
#endif

nxtask_exit();

/* Now, perform the context switch to the new ready-to-run task at the
Expand Down
140 changes: 2 additions & 138 deletions arch/arm64/src/common/arm64_fpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,10 @@ struct arm64_fpu_procfs_file_s
* Private Data
***************************************************************************/

static struct fpu_reg g_idle_thread_fpu[CONFIG_SMP_NCPUS];
static struct arm64_cpu_fpu_context g_cpu_fpu_ctx[CONFIG_SMP_NCPUS];

#ifdef CONFIG_FS_PROCFS_REGISTER

static struct arm64_cpu_fpu_context g_cpu_fpu_ctx[CONFIG_SMP_NCPUS];

/* procfs methods */

static int arm64_fpu_procfs_open(struct file *filep, const char *relpath,
Expand Down Expand Up @@ -262,141 +261,6 @@ static int arm64_fpu_procfs_stat(const char *relpath, struct stat *buf)
}
#endif

/***************************************************************************
* Public Functions
***************************************************************************/

void arm64_init_fpu(struct tcb_s *tcb)
{
if (tcb->pid < CONFIG_SMP_NCPUS)
{
#ifdef CONFIG_SMP
int cpu = tcb->cpu;
#else
int cpu = 0;
#endif
memset(&g_cpu_fpu_ctx[cpu], 0,
sizeof(struct arm64_cpu_fpu_context));
g_cpu_fpu_ctx[cpu].idle_thread = tcb;

tcb->xcp.fpu_regs = (uint64_t *)&g_idle_thread_fpu[cpu];
}

memset(tcb->xcp.fpu_regs, 0, sizeof(struct fpu_reg));
}

void arm64_destory_fpu(struct tcb_s *tcb)
{
struct tcb_s *owner;

/* save current fpu owner's context */

owner = g_cpu_fpu_ctx[this_cpu()].fpu_owner;

if (owner == tcb)
{
g_cpu_fpu_ctx[this_cpu()].fpu_owner = NULL;
}
}

/***************************************************************************
* Name: arm64_fpu_enter_exception
*
* Description:
* called at every time get into a exception
*
***************************************************************************/

void arm64_fpu_enter_exception(void)
{
}

void arm64_fpu_exit_exception(void)
{
}

void arm64_fpu_trap(struct regs_context *regs)
{
struct tcb_s *owner;

UNUSED(regs);

/* disable fpu trap access */

arm64_fpu_access_trap_disable();

/* save current fpu owner's context */

owner = g_cpu_fpu_ctx[this_cpu()].fpu_owner;

if (owner != NULL)
{
arm64_fpu_save((struct fpu_reg *)owner->xcp.fpu_regs);
ARM64_DSB();
g_cpu_fpu_ctx[this_cpu()].save_count++;
g_cpu_fpu_ctx[this_cpu()].fpu_owner = NULL;
}

if (arch_get_exception_depth() > 1)
{
/* if get_exception_depth > 1
* it means FPU access exception occurred in exception context
* switch FPU owner to idle thread
*/

owner = g_cpu_fpu_ctx[this_cpu()].idle_thread;
}
else
{
owner = running_task();
}

/* restore our context */

arm64_fpu_restore((struct fpu_reg *)owner->xcp.fpu_regs);
g_cpu_fpu_ctx[this_cpu()].restore_count++;

/* become new owner */

g_cpu_fpu_ctx[this_cpu()].fpu_owner = owner;
}

void arm64_fpu_context_restore(void)
{
struct tcb_s *new_tcb = running_task();

arm64_fpu_access_trap_disable();

/* FPU trap has happened at this task */

if (new_tcb == g_cpu_fpu_ctx[this_cpu()].fpu_owner)
{
arm64_fpu_access_trap_disable();
}
else
{
arm64_fpu_access_trap_enable();
}

g_cpu_fpu_ctx[this_cpu()].switch_count++;
}

#ifdef CONFIG_SMP
void arm64_fpu_context_save(void)
{
struct tcb_s *tcb = running_task();

if (tcb == g_cpu_fpu_ctx[this_cpu()].fpu_owner)
{
arm64_fpu_access_trap_disable();
arm64_fpu_save((struct fpu_reg *)tcb->xcp.fpu_regs);
ARM64_DSB();
g_cpu_fpu_ctx[this_cpu()].save_count++;
g_cpu_fpu_ctx[this_cpu()].fpu_owner = NULL;
}
}
#endif

void arm64_fpu_enable(void)
{
irqstate_t flags = up_irq_save();
Expand Down
20 changes: 0 additions & 20 deletions arch/arm64/src/common/arm64_initialstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,6 @@
#include "chip.h"
#include "arm64_fatal.h"

#ifdef CONFIG_ARCH_FPU
#include "arm64_fpu.h"
#endif

/****************************************************************************
* Public Functions
****************************************************************************/
Expand All @@ -70,17 +66,6 @@ void arm64_new_task(struct tcb_s * tcb)
}
#endif

#ifdef CONFIG_ARCH_FPU
struct fpu_reg *pfpuctx;
pfpuctx = STACK_PTR_TO_FRAME(struct fpu_reg, stack_ptr);
tcb->xcp.fpu_regs = (uint64_t *)pfpuctx;

/* set fpu context */

arm64_init_fpu(tcb);
stack_ptr = (uintptr_t)pfpuctx;
#endif

pinitctx = STACK_PTR_TO_FRAME(struct regs_context, stack_ptr);
memset(pinitctx, 0, sizeof(struct regs_context));
pinitctx->elr = (uint64_t)tcb->start;
Expand Down Expand Up @@ -150,11 +135,6 @@ void up_initial_state(struct tcb_s *tcb)
tcb->stack_base_ptr = tcb->stack_alloc_ptr;
tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE;

#ifdef CONFIG_ARCH_FPU
/* set fpu context */

arm64_init_fpu(tcb);
#endif
/* set initialize idle thread tcb and exception depth
* core 0, idle0
*/
Expand Down
29 changes: 0 additions & 29 deletions arch/arm64/src/common/arm64_schedulesigaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@
#include "irq/irq.h"
#include "arm64_fatal.h"

#ifdef CONFIG_ARCH_FPU
#include "arm64_fpu.h"
#endif

/****************************************************************************
* Public Functions
****************************************************************************/
Expand All @@ -58,16 +54,6 @@ void arm64_init_signal_process(struct tcb_s *tcb, struct regs_context *regs)
struct regs_context *psigctx;
char *stack_ptr = (char *)pctx->sp_elx - sizeof(struct regs_context);

#ifdef CONFIG_ARCH_FPU
struct fpu_reg *pfpuctx;
pfpuctx = STACK_PTR_TO_FRAME(struct fpu_reg, stack_ptr);
tcb->xcp.fpu_regs = (uint64_t *)pfpuctx;

/* set fpu context */

arm64_init_fpu(tcb);
stack_ptr = (char *)pfpuctx;
#endif
psigctx = STACK_PTR_TO_FRAME(struct regs_context, stack_ptr);
memset(psigctx, 0, sizeof(struct regs_context));
psigctx->elr = (uint64_t)arm64_sigdeliver;
Expand Down Expand Up @@ -177,9 +163,6 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
/* create signal process context */

tcb->xcp.saved_reg = up_current_regs();
#ifdef CONFIG_ARCH_FPU
tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
#endif
arm64_init_signal_process(tcb,
(struct regs_context *)up_current_regs());

Expand All @@ -201,9 +184,6 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
* have been delivered.
*/

#ifdef CONFIG_ARCH_FPU
tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
#endif
/* create signal process context */

tcb->xcp.saved_reg = tcb->xcp.regs;
Expand Down Expand Up @@ -279,9 +259,6 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
* been delivered.
*/

#ifdef CONFIG_ARCH_FPU
tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
#endif
/* create signal process context */

tcb->xcp.saved_reg = tcb->xcp.regs;
Expand All @@ -300,9 +277,6 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
/* create signal process context */

tcb->xcp.saved_reg = up_current_regs();
#ifdef CONFIG_ARCH_FPU
tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
#endif
arm64_init_signal_process(tcb,
(struct regs_context *)up_current_regs());

Expand Down Expand Up @@ -339,9 +313,6 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
* have been delivered.
*/

#ifdef CONFIG_ARCH_FPU
tcb->xcp.saved_fpu_regs = tcb->xcp.fpu_regs;
#endif
tcb->xcp.saved_reg = tcb->xcp.regs;

/* create signal process context */
Expand Down
9 changes: 0 additions & 9 deletions arch/arm64/src/common/arm64_sigdeliver.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@
#include "irq/irq.h"
#include "arm64_fatal.h"

#ifdef CONFIG_ARCH_FPU
#include "arm64_fpu.h"
#endif

/****************************************************************************
* Public Functions
****************************************************************************/
Expand Down Expand Up @@ -157,11 +153,6 @@ void arm64_sigdeliver(void)
rtcb->xcp.sigdeliver = NULL; /* Allows next handler to be scheduled */
rtcb->xcp.regs = rtcb->xcp.saved_reg;

#ifdef CONFIG_ARCH_FPU
arm64_destory_fpu(rtcb);
rtcb->xcp.fpu_regs = rtcb->xcp.saved_fpu_regs;
#endif

/* Then restore the correct state for this thread of execution. */

#ifdef CONFIG_SMP
Expand Down
1 change: 0 additions & 1 deletion arch/arm64/src/common/arm64_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ uint64_t *arm64_syscall_switch(uint64_t * regs)
*/

ret_regs = (uint64_t *)f_regs->regs[REG_X1];
f_regs->regs[REG_X1] = 0; /* set the saveregs = 0 */

DEBUGASSERT(ret_regs);
}
Expand Down
Loading

0 comments on commit 6759fc1

Please sign in to comment.