arch/risc-v: Store/Restore FPU register in exception_common

Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
Huang Qi 2022-03-29 22:57:56 +08:00 committed by Xiang Xiao
parent 8db038c18a
commit 814c07c792
4 changed files with 15 additions and 26 deletions

View File

@ -55,10 +55,6 @@ void riscv_copystate(uintptr_t *dest, uintptr_t *src)
{
int i;
#ifdef CONFIG_ARCH_FPU
uintptr_t *regs = dest;
#endif
/* In the RISC-V model, the state is copied from the stack to the TCB,
* but only a reference is passed to get the state from the TCB. So the
* following check avoids copying the TCB save area onto itself:
@ -68,18 +64,9 @@ void riscv_copystate(uintptr_t *dest, uintptr_t *src)
{
/* save integer registers first */
for (i = 0; i < INT_XCPT_REGS; i++)
for (i = 0; i < XCPTCONTEXT_REGS; i++)
{
*dest++ = *src++;
}
/* Save the floating point registers: This will initialize the floating
* registers at indices INT_XCPT_REGS through (XCPTCONTEXT_REGS-1).
* Do this after saving REG_INT_CTX with the ORIGINAL context pointer.
*/
#ifdef CONFIG_ARCH_FPU
riscv_savefpu(regs);
#endif
}
}

View File

@ -25,6 +25,8 @@
#include <nuttx/config.h>
#include <arch/irq.h>
#include "riscv_internal.h"
/****************************************************************************
* Public Symbols
****************************************************************************/
@ -96,13 +98,18 @@ exception_common:
addi s0, sp, XCPTCONTEXT_SIZE
REGSTORE s0, REG_X2(sp) /* original SP */
/* Setup arg0(exception cause), arg1(context) */
csrr a0, mcause /* exception cause */
csrr s0, mepc
REGSTORE s0, REG_EPC(sp) /* exception PC */
mv a1, sp /* context = sp */
#ifdef CONFIG_ARCH_FPU
mv a0, sp
jal x1, riscv_savefpu /* save FPU context */
#endif
/* Setup arg0(exception cause), arg1(context) */
csrr a0, mcause /* exception cause */
mv a1, sp /* context = sp */
#if CONFIG_ARCH_INTERRUPTSTACK > 15
/* Load mhartid (cpuid) */
@ -137,6 +144,9 @@ exception_common:
addi sp, sp, XCPTCONTEXT_SIZE
#endif
#ifdef CONFIG_ARCH_FPU
jal x1, riscv_restorefpu /* restore FPU context */
#endif
/* If context switch is needed, return a new sp */

View File

@ -68,13 +68,8 @@
* only a reference stored in TCB.
*/
#ifdef CONFIG_ARCH_FPU
#define riscv_savestate(regs) (regs = (uintptr_t *)CURRENT_REGS, riscv_savefpu(regs))
#define riscv_restorestate(regs) (CURRENT_REGS = regs, riscv_restorefpu((uintptr_t *)CURRENT_REGS))
#else
#define riscv_savestate(regs) (regs = (uintptr_t *)CURRENT_REGS)
#define riscv_restorestate(regs) (CURRENT_REGS = regs)
#endif
#define _START_TEXT &_stext
#define _END_TEXT &_etext

View File

@ -223,7 +223,6 @@ int riscv_swint(int irq, void *context, void *arg)
{
DEBUGASSERT(regs[REG_A1] != 0);
CURRENT_REGS = (uintptr_t *)regs[REG_A1];
riscv_restorefpu((uintptr_t *)CURRENT_REGS);
}
break;
@ -247,8 +246,6 @@ int riscv_swint(int irq, void *context, void *arg)
case SYS_switch_context:
{
DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0);
riscv_savefpu(regs);
riscv_restorefpu((uintptr_t *)regs[REG_A2]);
*(uintptr_t **)regs[REG_A1] = (uintptr_t *)regs;
CURRENT_REGS = (uintptr_t *)regs[REG_A2];
}