You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/07/31 14:49:00 UTC
[nuttx] branch master updated (8f744592d5 -> c126ee8468)
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
from 8f744592d5 Fix nuttx coding style
new 3b5c0c885f riscv/swint: Give the full tcb to the context switch routine
new b409d72e9d riscv/fpu: Restore correct lazy-FPU functionality
new 0ea9debfce riscv/riscv_fpu: Clear the full FPU status/control register on boot
new 4a468b8d3b riscv/saveusercontext: Fix FPU state save
new 83105cfa49 sched/assert: Store table for all registers instead of buffer
new d0fbf9883d riscv/lazyfpu: Add option to disable lazy FPU
new 61460efe3c riscv/qemu-rv: Add FPU support back to qemu-rv
new c126ee8468 sched/assert.c: Fix style check error
The 8 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
arch/Kconfig | 41 ++++++++
arch/risc-v/Kconfig | 2 +
arch/risc-v/include/irq.h | 88 +++++++++-------
arch/risc-v/src/common/riscv_cpupause.c | 4 +-
arch/risc-v/src/common/riscv_exception_common.S | 4 -
arch/risc-v/src/common/riscv_exit.c | 2 +-
arch/risc-v/src/common/riscv_fork.c | 28 ++---
arch/risc-v/src/common/riscv_fork.h | 1 +
arch/risc-v/src/common/riscv_fpu.S | 116 ++++++++++++++++++---
arch/risc-v/src/common/riscv_internal.h | 57 ++++++++--
arch/risc-v/src/common/riscv_macros.S | 30 ------
arch/risc-v/src/common/riscv_saveusercontext.S | 5 +-
arch/risc-v/src/common/riscv_sigdeliver.c | 4 +-
arch/risc-v/src/common/riscv_swint.c | 21 ++--
arch/risc-v/src/common/riscv_switchcontext.c | 6 +-
arch/risc-v/src/common/supervisor/riscv_syscall.S | 4 -
.../qemu-rv/rv-virt/configs/citest/defconfig | 1 -
.../qemu-rv/rv-virt/configs/citest64/defconfig | 1 -
sched/misc/assert.c | 12 ++-
19 files changed, 295 insertions(+), 132 deletions(-)
[nuttx] 08/08: sched/assert.c: Fix style check error
Posted by xi...@apache.org.
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/nuttx.git
commit c126ee8468a0beff8913bc522b1c80a7d5279bb8
Author: Ville Juven <vi...@unikie.com>
AuthorDate: Mon Jul 31 12:14:35 2023 +0300
sched/assert.c: Fix style check error
---
sched/misc/assert.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/sched/misc/assert.c b/sched/misc/assert.c
index 60cb14dc34..357ad7b814 100644
--- a/sched/misc/assert.c
+++ b/sched/misc/assert.c
@@ -238,10 +238,11 @@ static void dump_stacks(FAR struct tcb_s *rtcb, uintptr_t sp)
intstack_base,
intstack_size,
#ifdef CONFIG_STACK_COLORATION
- up_check_intstack());
+ up_check_intstack()
#else
- 0);
+ 0
#endif
+ );
tcbstack_sp = up_getusrsp((FAR void *)CURRENT_REGS);
if (tcbstack_sp < tcbstack_base || tcbstack_sp >= tcbstack_top)
@@ -271,10 +272,11 @@ static void dump_stacks(FAR struct tcb_s *rtcb, uintptr_t sp)
tcbstack_base,
tcbstack_size,
#ifdef CONFIG_STACK_COLORATION
- up_check_tcbstack(rtcb));
+ up_check_tcbstack(rtcb)
#else
- 0);
+ 0
#endif
+ );
}
}
[nuttx] 01/08: riscv/swint: Give the full tcb to the context switch routine
Posted by xi...@apache.org.
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/nuttx.git
commit 3b5c0c885f2607d781d7fd5f93a27cb888d93771
Author: Ville Juven <vi...@unikie.com>
AuthorDate: Tue May 16 18:03:53 2023 +0300
riscv/swint: Give the full tcb to the context switch routine
Why? The tcb can contain info that is needed by the context switch
routine. One example is lazy-FPU handling; the integer registers can
be stored into the stack, because they are always stored & restored.
Lazy-FPU however needs a non-volatile location to store the FPU registers
as the save feature will skip saving a clean FPU, but the restore must
always restore the FPU registers if the thread uses FPU.
---
arch/risc-v/src/common/riscv_exit.c | 2 +-
arch/risc-v/src/common/riscv_internal.h | 25 +++++++++++++++++++------
arch/risc-v/src/common/riscv_sigdeliver.c | 4 +++-
arch/risc-v/src/common/riscv_swint.c | 21 +++++++++++++--------
arch/risc-v/src/common/riscv_switchcontext.c | 6 +++---
5 files changed, 39 insertions(+), 19 deletions(-)
diff --git a/arch/risc-v/src/common/riscv_exit.c b/arch/risc-v/src/common/riscv_exit.c
index c6177f29b7..143ffb438a 100644
--- a/arch/risc-v/src/common/riscv_exit.c
+++ b/arch/risc-v/src/common/riscv_exit.c
@@ -139,7 +139,7 @@ void up_exit(int status)
/* Then switch contexts */
- riscv_fullcontextrestore(tcb->xcp.regs);
+ riscv_fullcontextrestore(tcb);
/* riscv_fullcontextrestore() should not return but could if the software
* interrupts are disabled.
diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h
index f3a50d4c95..6b385818cb 100644
--- a/arch/risc-v/src/common/riscv_internal.h
+++ b/arch/risc-v/src/common/riscv_internal.h
@@ -29,6 +29,7 @@
#ifndef __ASSEMBLY__
# include <nuttx/compiler.h>
+# include <nuttx/sched.h>
# include <sys/types.h>
# include <stdint.h>
# include <syscall.h>
@@ -207,6 +208,18 @@ void riscv_fpuconfig(void);
# define riscv_fpuconfig()
#endif
+/* Save / restore context of task */
+
+static inline void riscv_savecontext(struct tcb_s *tcb)
+{
+ tcb->xcp.regs = (uintptr_t *)CURRENT_REGS;
+}
+
+static inline void riscv_restorecontext(struct tcb_s *tcb)
+{
+ CURRENT_REGS = (uintptr_t *)tcb->xcp.regs;
+}
+
/* RISC-V PMP Config ********************************************************/
int riscv_config_pmp_region(uintptr_t region, uintptr_t attr,
@@ -304,19 +317,19 @@ void *riscv_perform_syscall(uintptr_t *regs);
/* SYS call 1:
*
- * void riscv_fullcontextrestore(uintptr_t *restoreregs) noreturn_function;
+ * void riscv_fullcontextrestore(struct tcb_s *next) noreturn_function;
*/
-#define riscv_fullcontextrestore(restoreregs) \
- sys_call1(SYS_restore_context, (uintptr_t)restoreregs)
+#define riscv_fullcontextrestore(next) \
+ sys_call1(SYS_restore_context, (uintptr_t)next)
/* SYS call 2:
*
- * void riscv_switchcontext(uintptr_t *saveregs, uintptr_t *restoreregs);
+ * riscv_switchcontext(struct tcb_s *prev, struct tcb_s *next);
*/
-#define riscv_switchcontext(saveregs, restoreregs) \
- sys_call2(SYS_switch_context, (uintptr_t)saveregs, (uintptr_t)restoreregs)
+#define riscv_switchcontext(prev, next) \
+ sys_call2(SYS_switch_context, (uintptr_t)prev, (uintptr_t)next)
#ifdef CONFIG_BUILD_KERNEL
/* SYS call 3:
diff --git a/arch/risc-v/src/common/riscv_sigdeliver.c b/arch/risc-v/src/common/riscv_sigdeliver.c
index c9c84e65e5..6e1a70641a 100644
--- a/arch/risc-v/src/common/riscv_sigdeliver.c
+++ b/arch/risc-v/src/common/riscv_sigdeliver.c
@@ -161,5 +161,7 @@ retry:
leave_critical_section(regs[REG_INT_CTX]);
rtcb->irqcount--;
#endif
- riscv_fullcontextrestore(regs);
+
+ rtcb->xcp.regs = regs;
+ riscv_fullcontextrestore(rtcb);
}
diff --git a/arch/risc-v/src/common/riscv_swint.c b/arch/risc-v/src/common/riscv_swint.c
index 8eae2db37c..dc2c11f00e 100644
--- a/arch/risc-v/src/common/riscv_swint.c
+++ b/arch/risc-v/src/common/riscv_swint.c
@@ -135,12 +135,12 @@ int riscv_swint(int irq, void *context, void *arg)
/* A0=SYS_restore_context: This a restore context command:
*
* void
- * riscv_fullcontextrestore(uintptr_t *restoreregs) noreturn_function;
+ * void riscv_fullcontextrestore(struct tcb_s *prev) noreturn_function;
*
* At this point, the following values are saved in context:
*
* A0 = SYS_restore_context
- * A1 = restoreregs
+ * A1 = next
*
* In this case, we simply need to set CURRENT_REGS to restore register
* area referenced in the saved A1. context == CURRENT_REGS is the
@@ -150,21 +150,23 @@ int riscv_swint(int irq, void *context, void *arg)
case SYS_restore_context:
{
+ struct tcb_s *next = (struct tcb_s *)regs[REG_A1];
+
DEBUGASSERT(regs[REG_A1] != 0);
- CURRENT_REGS = (uintptr_t *)regs[REG_A1];
+ CURRENT_REGS = (uintptr_t *)next->xcp.regs;
}
break;
/* A0=SYS_switch_context: This a switch context command:
*
* void
- * riscv_switchcontext(uintptr_t *saveregs, uintptr_t *restoreregs);
+ * riscv_switchcontext(struct tcb_s *prev, struct tcb_s *next);
*
* At this point, the following values are saved in context:
*
* A0 = SYS_switch_context
- * A1 = saveregs
- * A2 = restoreregs
+ * A1 = prev
+ * A2 = next
*
* In this case, we save the context registers to the save register
* area referenced by the saved contents of R5 and then set
@@ -174,9 +176,12 @@ int riscv_swint(int irq, void *context, void *arg)
case SYS_switch_context:
{
+ struct tcb_s *prev = (struct tcb_s *)regs[REG_A1];
+ struct tcb_s *next = (struct tcb_s *)regs[REG_A2];
+
DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0);
- *(uintptr_t **)regs[REG_A1] = (uintptr_t *)regs;
- CURRENT_REGS = (uintptr_t *)regs[REG_A2];
+ prev->xcp.regs = (uintptr_t *)CURRENT_REGS;
+ CURRENT_REGS = (uintptr_t *)next->xcp.regs;
}
break;
diff --git a/arch/risc-v/src/common/riscv_switchcontext.c b/arch/risc-v/src/common/riscv_switchcontext.c
index 30ea84a00f..d39ad24b68 100644
--- a/arch/risc-v/src/common/riscv_switchcontext.c
+++ b/arch/risc-v/src/common/riscv_switchcontext.c
@@ -69,7 +69,7 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
* Just copy the CURRENT_REGS into the OLD rtcb.
*/
- riscv_savestate(rtcb->xcp.regs);
+ riscv_savecontext(rtcb);
/* Update scheduler parameters */
@@ -79,7 +79,7 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
* changes will be made when the interrupt returns.
*/
- riscv_restorestate(tcb->xcp.regs);
+ riscv_restorecontext(tcb);
}
/* No, then we will need to perform the user context switch */
@@ -92,7 +92,7 @@ void up_switch_context(struct tcb_s *tcb, struct tcb_s *rtcb)
/* Then switch contexts */
- riscv_switchcontext(&rtcb->xcp.regs, tcb->xcp.regs);
+ riscv_switchcontext(rtcb, tcb);
/* riscv_switchcontext forces a context switch to the task at the
* head of the ready-to-run list. It does not 'return' in the
[nuttx] 05/08: sched/assert: Store table for all registers instead of buffer
Posted by xi...@apache.org.
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/nuttx.git
commit 83105cfa49b8659cd952ea63ada84d5db770b66f
Author: Ville Juven <vi...@unikie.com>
AuthorDate: Thu Jun 1 15:39:50 2023 +0300
sched/assert: Store table for all registers instead of buffer
This way the registers can be read easily
---
sched/misc/assert.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sched/misc/assert.c b/sched/misc/assert.c
index 54c3be3f84..60cb14dc34 100644
--- a/sched/misc/assert.c
+++ b/sched/misc/assert.c
@@ -72,7 +72,7 @@
* Private Data
****************************************************************************/
-static uint8_t g_last_regs[XCPTCONTEXT_SIZE] aligned_data(16);
+static uintptr_t g_last_regs[XCPTCONTEXT_REGS] aligned_data(16);
#ifdef CONFIG_BOARD_COREDUMP
static struct lib_syslogstream_s g_syslogstream;
[nuttx] 04/08: riscv/saveusercontext: Fix FPU state save
Posted by xi...@apache.org.
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/nuttx.git
commit 4a468b8d3b8c4acedb0d94ac45d7b63a0d33d7af
Author: Ville Juven <vi...@unikie.com>
AuthorDate: Thu Jun 1 15:37:57 2023 +0300
riscv/saveusercontext: Fix FPU state save
---
arch/risc-v/src/common/riscv_saveusercontext.S | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/risc-v/src/common/riscv_saveusercontext.S b/arch/risc-v/src/common/riscv_saveusercontext.S
index b89508b3dd..bbdeca21e0 100644
--- a/arch/risc-v/src/common/riscv_saveusercontext.S
+++ b/arch/risc-v/src/common/riscv_saveusercontext.S
@@ -56,7 +56,10 @@ up_saveusercontext:
REGSTORE sp, REG_X2(a0) /* original SP */
REGSTORE x1, REG_EPC(a0)
- riscv_savefpu a0
+#ifdef CONFIG_ARCH_FPU
+ addi a0, a0, INT_XCPT_SIZE /* Save FPU after integer regs */
+ riscv_savefpu a0
+#endif
li a0, 0
jr ra
[nuttx] 06/08: riscv/lazyfpu: Add option to disable lazy FPU
Posted by xi...@apache.org.
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/nuttx.git
commit d0fbf9883d2e16785829a5d8f75b9d6122ad2b69
Author: Ville Juven <vi...@unikie.com>
AuthorDate: Wed Jun 7 14:02:48 2023 +0300
riscv/lazyfpu: Add option to disable lazy FPU
Adds option to use the old implementation where FPU is stored into
the process stack.
---
arch/Kconfig | 41 +++++++++++++++++++++++++++++++++
arch/risc-v/include/irq.h | 8 ++++++-
arch/risc-v/src/common/riscv_fork.c | 28 ++++++++++++----------
arch/risc-v/src/common/riscv_fpu.S | 4 ++++
arch/risc-v/src/common/riscv_internal.h | 20 ++++++++++++++--
5 files changed, 86 insertions(+), 15 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig
index 232e32ca10..673ff57771 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -93,6 +93,7 @@ config ARCH_RISCV
select ARCH_HAVE_RDWR_MEM_CPU_RUN
select ARCH_HAVE_TCBINFO
select ARCH_HAVE_THREAD_LOCAL
+ select ARCH_HAVE_LAZYFPU if ARCH_HAVE_FPU
---help---
RISC-V 32 and 64-bit RV32 / RV64 architectures.
@@ -416,6 +417,11 @@ config ARCH_HAVE_DPFPU
default n
select ARCH_HAVE_FPU
+config ARCH_HAVE_LAZYFPU
+ bool
+ default n
+ depends on ARCH_HAVE_FPU
+
config ARCH_HAVE_MMU
bool
default n
@@ -516,6 +522,41 @@ config ARCH_DPFPU
Enable toolchain support for double precision (64-bit) floating
point if both the toolchain and the hardware support it.
+config ARCH_LAZYFPU
+ bool "Enable lazy FPU state save / restore"
+ default n
+ depends on ARCH_FPU && ARCH_HAVE_LAZYFPU
+ ---help---
+ Enable lazy FPU state save and restore. Normally FPU state is saved
+ and restored with the integer context registers, if the task is using
+ FPU. The state is typically saved into the task's user stack upon
+ exception entry or context switch out, and restored when the
+ exception returns or context switches back in.
+
+ As the kernel does not use FPU, this can be optimized with the help
+ of the FPU hardware status and a bit of code logic inside the kernel.
+ The logic keeps track of the FPU state, which can be "unused",
+ "dirty" or "clean". A clean state means the FPU has not been used
+ since the last state save, while the dirty state indicates that the
+ FPU has been used.
+
+ The optimization saves / restores FPU registers only if:
+ - A context change has happened, save and restore does not happen
+ during exception entry / return to the same task
+ - FPU is in use (state is not unused) and
+ - FPU status is dirty, i.e. FPU has been used after the last
+ - FPU restore happens when status is in dirty or clean
+
+ This saves CPU time as the FPU registers do not have to be moved in
+ and out when handling an exception that does not result in a context
+ switch.
+
+ The tradeoff with the lazy FPU feature is that it requires a static
+ memory allocation from the task's TCB to store the FPU registers,
+ while the non-lazy style can use stack memory for storing the FPU
+ registers, saving memory as the stack frame for the FPU registers can
+ be skipped if the FPU is not in use.
+
config ARCH_USE_MMU
bool "Enable MMU"
default n
diff --git a/arch/risc-v/include/irq.h b/arch/risc-v/include/irq.h
index 5941d7057b..54f0febbba 100644
--- a/arch/risc-v/include/irq.h
+++ b/arch/risc-v/include/irq.h
@@ -247,9 +247,15 @@
#define XCPTCONTEXT_REGS (INT_XCPT_REGS + FPU_XCPT_REGS)
+#ifdef CONFIG_ARCH_LAZYFPU
/* Save only integer regs. FPU is handled separately */
#define XCPTCONTEXT_SIZE (INT_XCPT_SIZE)
+#else
+/* Save FPU registers with the integer registers */
+
+#define XCPTCONTEXT_SIZE (INT_XCPT_SIZE + FPU_XCPT_SIZE)
+#endif
/* In assembly language, values have to be referenced as byte address
* offsets. But in C, it is more convenient to reference registers as
@@ -570,7 +576,7 @@ struct xcptcontext
/* FPU register save area */
-#ifdef CONFIG_ARCH_FPU
+#if defined(CONFIG_ARCH_FPU) && defined(CONFIG_ARCH_LAZYFPU)
uintptr_t fregs[FPU_XCPT_REGS];
#endif
};
diff --git a/arch/risc-v/src/common/riscv_fork.c b/arch/risc-v/src/common/riscv_fork.c
index b1d96598e0..0dd41aecdc 100644
--- a/arch/risc-v/src/common/riscv_fork.c
+++ b/arch/risc-v/src/common/riscv_fork.c
@@ -109,6 +109,9 @@ pid_t riscv_fork(const struct fork_s *context)
uintptr_t newtop;
uintptr_t stacktop;
uintptr_t stackutil;
+#ifdef CONFIG_ARCH_FPU
+ uintptr_t *fregs;
+#endif
sinfo("s0:%" PRIxREG " s1:%" PRIxREG " s2:%" PRIxREG " s3:%" PRIxREG ""
" s4:%" PRIxREG "\n",
@@ -228,18 +231,19 @@ pid_t riscv_fork(const struct fork_s *context)
child->cmn.xcp.regs[REG_GP] = newsp; /* Global pointer */
#endif
#ifdef CONFIG_ARCH_FPU
- child->cmn.xcp.fregs[REG_FS0] = context->fs0; /* Saved register fs1 */
- child->cmn.xcp.fregs[REG_FS1] = context->fs1; /* Saved register fs1 */
- child->cmn.xcp.fregs[REG_FS2] = context->fs2; /* Saved register fs2 */
- child->cmn.xcp.fregs[REG_FS3] = context->fs3; /* Saved register fs3 */
- child->cmn.xcp.fregs[REG_FS4] = context->fs4; /* Saved register fs4 */
- child->cmn.xcp.fregs[REG_FS5] = context->fs5; /* Saved register fs5 */
- child->cmn.xcp.fregs[REG_FS6] = context->fs6; /* Saved register fs6 */
- child->cmn.xcp.fregs[REG_FS7] = context->fs7; /* Saved register fs7 */
- child->cmn.xcp.fregs[REG_FS8] = context->fs8; /* Saved register fs8 */
- child->cmn.xcp.fregs[REG_FS9] = context->fs9; /* Saved register fs9 */
- child->cmn.xcp.fregs[REG_FS10] = context->fs10; /* Saved register fs10 */
- child->cmn.xcp.fregs[REG_FS11] = context->fs11; /* Saved register fs11 */
+ fregs = riscv_fpuregs(&child->cmn);
+ fregs[REG_FS0] = context->fs0; /* Saved register fs1 */
+ fregs[REG_FS1] = context->fs1; /* Saved register fs1 */
+ fregs[REG_FS2] = context->fs2; /* Saved register fs2 */
+ fregs[REG_FS3] = context->fs3; /* Saved register fs3 */
+ fregs[REG_FS4] = context->fs4; /* Saved register fs4 */
+ fregs[REG_FS5] = context->fs5; /* Saved register fs5 */
+ fregs[REG_FS6] = context->fs6; /* Saved register fs6 */
+ fregs[REG_FS7] = context->fs7; /* Saved register fs7 */
+ fregs[REG_FS8] = context->fs8; /* Saved register fs8 */
+ fregs[REG_FS9] = context->fs9; /* Saved register fs9 */
+ fregs[REG_FS10] = context->fs10; /* Saved register fs10 */
+ fregs[REG_FS11] = context->fs11; /* Saved register fs11 */
#endif
#ifdef CONFIG_LIB_SYSCALL
diff --git a/arch/risc-v/src/common/riscv_fpu.S b/arch/risc-v/src/common/riscv_fpu.S
index cc88e769dd..11f24b90ca 100644
--- a/arch/risc-v/src/common/riscv_fpu.S
+++ b/arch/risc-v/src/common/riscv_fpu.S
@@ -102,7 +102,11 @@ riscv_savefpu:
li t1, MSTATUS_FS
and t2, t0, t1
li t1, MSTATUS_FS_DIRTY
+#ifdef CONFIG_ARCH_LAZYFPU
bne t2, t1, 1f
+#else
+ blt t2, t1, 1f
+#endif
li t1, ~MSTATUS_FS
and t0, t0, t1
li t1, MSTATUS_FS_CLEAN
diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h
index 836d7354f5..ac16c0bd87 100644
--- a/arch/risc-v/src/common/riscv_internal.h
+++ b/arch/risc-v/src/common/riscv_internal.h
@@ -206,10 +206,26 @@ void riscv_exception_attach(void);
void riscv_fpuconfig(void);
void riscv_savefpu(uintptr_t *regs, uintptr_t *fregs);
void riscv_restorefpu(uintptr_t *regs, uintptr_t *fregs);
+
+/* Get FPU register save area */
+
+static inline uintptr_t *riscv_fpuregs(struct tcb_s *tcb)
+{
+#ifdef CONFIG_ARCH_LAZYFPU
+ /* With lazy FPU the registers are simply in tcb */
+
+ return tcb->xcp.fregs;
+#else
+ /* Otherwise they are after the integer registers */
+
+ return (uintptr_t *)((uintptr_t)tcb->xcp.regs + INT_XCPT_SIZE);
+#endif
+}
#else
# define riscv_fpuconfig()
# define riscv_savefpu(regs, fregs)
# define riscv_restorefpu(regs, fregs)
+# define riscv_fpuregs(tcb)
#endif
/* Save / restore context of task */
@@ -221,7 +237,7 @@ static inline void riscv_savecontext(struct tcb_s *tcb)
#ifdef CONFIG_ARCH_FPU
/* Save current process FPU state to TCB */
- riscv_savefpu(tcb->xcp.regs, tcb->xcp.fregs);
+ riscv_savefpu(tcb->xcp.regs, riscv_fpuregs(tcb));
#endif
}
@@ -232,7 +248,7 @@ static inline void riscv_restorecontext(struct tcb_s *tcb)
#ifdef CONFIG_ARCH_FPU
/* Restore FPU state for next process */
- riscv_restorefpu(tcb->xcp.regs, tcb->xcp.fregs);
+ riscv_restorefpu(tcb->xcp.regs, riscv_fpuregs(tcb));
#endif
}
[nuttx] 07/08: riscv/qemu-rv: Add FPU support back to qemu-rv
Posted by xi...@apache.org.
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/nuttx.git
commit 61460efe3ca7bd4f04d28d74e874060d279af7e8
Author: Ville Juven <vi...@unikie.com>
AuthorDate: Tue Jun 20 13:39:52 2023 +0300
riscv/qemu-rv: Add FPU support back to qemu-rv
The FPU restore issue does not show itself any longer, so FPU support
can be re-enabled.
---
arch/risc-v/Kconfig | 2 ++
boards/risc-v/qemu-rv/rv-virt/configs/citest/defconfig | 1 -
boards/risc-v/qemu-rv/rv-virt/configs/citest64/defconfig | 1 -
3 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig
index f6092dd94c..c6cd81377a 100644
--- a/arch/risc-v/Kconfig
+++ b/arch/risc-v/Kconfig
@@ -163,6 +163,8 @@ config ARCH_CHIP_RV32M1
config ARCH_CHIP_QEMU_RV
bool "QEMU RV"
+ select ARCH_HAVE_FPU
+ select ARCH_HAVE_DPFPU
select ARCH_HAVE_MULTICPU
select ARCH_HAVE_MPU
select ARCH_HAVE_MMU
diff --git a/boards/risc-v/qemu-rv/rv-virt/configs/citest/defconfig b/boards/risc-v/qemu-rv/rv-virt/configs/citest/defconfig
index a080275da0..946b2bf7c4 100644
--- a/boards/risc-v/qemu-rv/rv-virt/configs/citest/defconfig
+++ b/boards/risc-v/qemu-rv/rv-virt/configs/citest/defconfig
@@ -49,7 +49,6 @@ CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_ENVPATH=y
CONFIG_LIBC_EXECFUNCS=y
-CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NET=y
diff --git a/boards/risc-v/qemu-rv/rv-virt/configs/citest64/defconfig b/boards/risc-v/qemu-rv/rv-virt/configs/citest64/defconfig
index e2a5d9e065..031389e0db 100644
--- a/boards/risc-v/qemu-rv/rv-virt/configs/citest64/defconfig
+++ b/boards/risc-v/qemu-rv/rv-virt/configs/citest64/defconfig
@@ -48,7 +48,6 @@ CONFIG_INIT_STACKSIZE=3072
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_ENVPATH=y
CONFIG_LIBC_EXECFUNCS=y
-CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NET=y
[nuttx] 02/08: riscv/fpu: Restore correct lazy-FPU functionality
Posted by xi...@apache.org.
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/nuttx.git
commit b409d72e9db206cbce0672755443e20531101875
Author: Ville Juven <vi...@unikie.com>
AuthorDate: Mon May 15 17:56:15 2023 +0300
riscv/fpu: Restore correct lazy-FPU functionality
- Save the FPU registers into the tcb so they don't get lost if the stack
frame for xcp.regs moves (as it does)
- Handle interger and FPU register save/load separately
- Integer registers are saved/loaded always, like before
- FPU registers are only saved during a context switch:
- Save ONLY if FPU is dirty
- Restore always if FPU has been used (not in FSTATE_OFF, FSTATE_INIT)
- Remove all lazy-FPU related logic from the macros, it is not needed
---
arch/risc-v/include/irq.h | 82 +++++++++-------
arch/risc-v/src/common/riscv_cpupause.c | 4 +-
arch/risc-v/src/common/riscv_exception_common.S | 4 -
arch/risc-v/src/common/riscv_fork.c | 24 ++---
arch/risc-v/src/common/riscv_fork.h | 1 +
arch/risc-v/src/common/riscv_fpu.S | 113 +++++++++++++++++++---
arch/risc-v/src/common/riscv_internal.h | 16 +++
arch/risc-v/src/common/riscv_macros.S | 30 ------
arch/risc-v/src/common/riscv_swint.c | 6 +-
arch/risc-v/src/common/supervisor/riscv_syscall.S | 4 -
10 files changed, 176 insertions(+), 108 deletions(-)
diff --git a/arch/risc-v/include/irq.h b/arch/risc-v/include/irq.h
index a566492e89..5941d7057b 100644
--- a/arch/risc-v/include/irq.h
+++ b/arch/risc-v/include/irq.h
@@ -204,50 +204,52 @@
#endif
#ifdef CONFIG_ARCH_FPU
-# define REG_F0_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 0)
-# define REG_F1_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 1)
-# define REG_F2_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 2)
-# define REG_F3_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 3)
-# define REG_F4_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 4)
-# define REG_F5_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 5)
-# define REG_F6_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 6)
-# define REG_F7_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 7)
-# define REG_F8_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 8)
-# define REG_F9_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 9)
-# define REG_F10_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 10)
-# define REG_F11_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 11)
-# define REG_F12_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 12)
-# define REG_F13_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 13)
-# define REG_F14_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 14)
-# define REG_F15_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 15)
-# define REG_F16_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 16)
-# define REG_F17_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 17)
-# define REG_F18_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 18)
-# define REG_F19_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 19)
-# define REG_F20_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 20)
-# define REG_F21_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 21)
-# define REG_F22_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 22)
-# define REG_F23_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 23)
-# define REG_F24_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 24)
-# define REG_F25_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 25)
-# define REG_F26_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 26)
-# define REG_F27_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 27)
-# define REG_F28_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 28)
-# define REG_F29_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 29)
-# define REG_F30_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 30)
-# define REG_F31_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 31)
-# define REG_FCSR_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 32)
+# define REG_F0_NDX (FPU_REG_SIZE * 0)
+# define REG_F1_NDX (FPU_REG_SIZE * 1)
+# define REG_F2_NDX (FPU_REG_SIZE * 2)
+# define REG_F3_NDX (FPU_REG_SIZE * 3)
+# define REG_F4_NDX (FPU_REG_SIZE * 4)
+# define REG_F5_NDX (FPU_REG_SIZE * 5)
+# define REG_F6_NDX (FPU_REG_SIZE * 6)
+# define REG_F7_NDX (FPU_REG_SIZE * 7)
+# define REG_F8_NDX (FPU_REG_SIZE * 8)
+# define REG_F9_NDX (FPU_REG_SIZE * 9)
+# define REG_F10_NDX (FPU_REG_SIZE * 10)
+# define REG_F11_NDX (FPU_REG_SIZE * 11)
+# define REG_F12_NDX (FPU_REG_SIZE * 12)
+# define REG_F13_NDX (FPU_REG_SIZE * 13)
+# define REG_F14_NDX (FPU_REG_SIZE * 14)
+# define REG_F15_NDX (FPU_REG_SIZE * 15)
+# define REG_F16_NDX (FPU_REG_SIZE * 16)
+# define REG_F17_NDX (FPU_REG_SIZE * 17)
+# define REG_F18_NDX (FPU_REG_SIZE * 18)
+# define REG_F19_NDX (FPU_REG_SIZE * 19)
+# define REG_F20_NDX (FPU_REG_SIZE * 20)
+# define REG_F21_NDX (FPU_REG_SIZE * 21)
+# define REG_F22_NDX (FPU_REG_SIZE * 22)
+# define REG_F23_NDX (FPU_REG_SIZE * 23)
+# define REG_F24_NDX (FPU_REG_SIZE * 24)
+# define REG_F25_NDX (FPU_REG_SIZE * 25)
+# define REG_F26_NDX (FPU_REG_SIZE * 26)
+# define REG_F27_NDX (FPU_REG_SIZE * 27)
+# define REG_F28_NDX (FPU_REG_SIZE * 28)
+# define REG_F29_NDX (FPU_REG_SIZE * 29)
+# define REG_F30_NDX (FPU_REG_SIZE * 30)
+# define REG_F31_NDX (FPU_REG_SIZE * 31)
+# define REG_FCSR_NDX (FPU_REG_SIZE * 32)
# define FPU_XCPT_REGS (FPU_REG_SIZE * 33)
-# define FPU_REG_FULL_SIZE (INT_REG_SIZE * FPU_REG_SIZE)
+# define FPU_XCPT_SIZE (INT_REG_SIZE * FPU_XCPT_REGS)
#else /* !CONFIG_ARCH_FPU */
# define FPU_XCPT_REGS (0)
-# define FPU_REG_FULL_SIZE (0)
+# define FPU_XCPT_SIZE (0)
#endif /* CONFIG_ARCH_FPU */
#define XCPTCONTEXT_REGS (INT_XCPT_REGS + FPU_XCPT_REGS)
-#define XCPTCONTEXT_SIZE (INT_REG_SIZE * XCPTCONTEXT_REGS)
+/* Save only integer regs. FPU is handled separately */
+
+#define XCPTCONTEXT_SIZE (INT_XCPT_SIZE)
/* In assembly language, values have to be referenced as byte address
* offsets. But in C, it is more convenient to reference registers as
@@ -562,9 +564,15 @@ struct xcptcontext
#endif
#endif
- /* Register save area */
+ /* Integer register save area */
uintptr_t *regs;
+
+ /* FPU register save area */
+
+#ifdef CONFIG_ARCH_FPU
+ uintptr_t fregs[FPU_XCPT_REGS];
+#endif
};
#endif /* __ASSEMBLY__ */
diff --git a/arch/risc-v/src/common/riscv_cpupause.c b/arch/risc-v/src/common/riscv_cpupause.c
index 7d30dc5543..87412f7ad4 100644
--- a/arch/risc-v/src/common/riscv_cpupause.c
+++ b/arch/risc-v/src/common/riscv_cpupause.c
@@ -129,7 +129,7 @@ int up_cpu_paused(int cpu)
* of the assigned task list for this CPU.
*/
- riscv_savestate(tcb->xcp.regs);
+ riscv_savecontext(tcb);
/* Wait for the spinlock to be released */
@@ -161,7 +161,7 @@ int up_cpu_paused(int cpu)
* will be made when the interrupt returns.
*/
- riscv_restorestate(tcb->xcp.regs);
+ riscv_restorecontext(tcb);
spin_unlock(&g_cpu_wait[cpu]);
spin_unlock(&g_cpu_resumed[cpu]);
diff --git a/arch/risc-v/src/common/riscv_exception_common.S b/arch/risc-v/src/common/riscv_exception_common.S
index 1f1180d46b..9d78b65c09 100644
--- a/arch/risc-v/src/common/riscv_exception_common.S
+++ b/arch/risc-v/src/common/riscv_exception_common.S
@@ -113,8 +113,6 @@ exception_common:
csrr s0, CSR_EPC
REGSTORE s0, REG_EPC(sp) /* exception PC */
- riscv_savefpu sp
-
/* Setup arg0(exception cause), arg1(context) */
csrr a0, CSR_CAUSE /* exception cause */
@@ -148,8 +146,6 @@ exception_common:
mv sp, a0
- riscv_loadfpu sp
-
REGLOAD s0, REG_EPC(sp) /* restore sepc */
csrw CSR_EPC, s0
diff --git a/arch/risc-v/src/common/riscv_fork.c b/arch/risc-v/src/common/riscv_fork.c
index 53ac2f3740..b1d96598e0 100644
--- a/arch/risc-v/src/common/riscv_fork.c
+++ b/arch/risc-v/src/common/riscv_fork.c
@@ -228,18 +228,18 @@ pid_t riscv_fork(const struct fork_s *context)
child->cmn.xcp.regs[REG_GP] = newsp; /* Global pointer */
#endif
#ifdef CONFIG_ARCH_FPU
- child->cmn.xcp.regs[REG_FS0] = context->fs0; /* Saved register fs1 */
- child->cmn.xcp.regs[REG_FS1] = context->fs1; /* Saved register fs1 */
- child->cmn.xcp.regs[REG_FS2] = context->fs2; /* Saved register fs2 */
- child->cmn.xcp.regs[REG_FS3] = context->fs3; /* Saved register fs3 */
- child->cmn.xcp.regs[REG_FS4] = context->fs4; /* Saved register fs4 */
- child->cmn.xcp.regs[REG_FS5] = context->fs5; /* Saved register fs5 */
- child->cmn.xcp.regs[REG_FS6] = context->fs6; /* Saved register fs6 */
- child->cmn.xcp.regs[REG_FS7] = context->fs7; /* Saved register fs7 */
- child->cmn.xcp.regs[REG_FS8] = context->fs8; /* Saved register fs8 */
- child->cmn.xcp.regs[REG_FS9] = context->fs9; /* Saved register fs9 */
- child->cmn.xcp.regs[REG_FS10] = context->fs10; /* Saved register fs10 */
- child->cmn.xcp.regs[REG_FS11] = context->fs11; /* Saved register fs11 */
+ child->cmn.xcp.fregs[REG_FS0] = context->fs0; /* Saved register fs1 */
+ child->cmn.xcp.fregs[REG_FS1] = context->fs1; /* Saved register fs1 */
+ child->cmn.xcp.fregs[REG_FS2] = context->fs2; /* Saved register fs2 */
+ child->cmn.xcp.fregs[REG_FS3] = context->fs3; /* Saved register fs3 */
+ child->cmn.xcp.fregs[REG_FS4] = context->fs4; /* Saved register fs4 */
+ child->cmn.xcp.fregs[REG_FS5] = context->fs5; /* Saved register fs5 */
+ child->cmn.xcp.fregs[REG_FS6] = context->fs6; /* Saved register fs6 */
+ child->cmn.xcp.fregs[REG_FS7] = context->fs7; /* Saved register fs7 */
+ child->cmn.xcp.fregs[REG_FS8] = context->fs8; /* Saved register fs8 */
+ child->cmn.xcp.fregs[REG_FS9] = context->fs9; /* Saved register fs9 */
+ child->cmn.xcp.fregs[REG_FS10] = context->fs10; /* Saved register fs10 */
+ child->cmn.xcp.fregs[REG_FS11] = context->fs11; /* Saved register fs11 */
#endif
#ifdef CONFIG_LIB_SYSCALL
diff --git a/arch/risc-v/src/common/riscv_fork.h b/arch/risc-v/src/common/riscv_fork.h
index 32cadba8d8..5fbd207af7 100644
--- a/arch/risc-v/src/common/riscv_fork.h
+++ b/arch/risc-v/src/common/riscv_fork.h
@@ -90,6 +90,7 @@
#endif
#ifdef CONFIG_ARCH_FPU
+# define FPU_REG_FULL_SIZE (INT_REG_SIZE * FPU_REG_SIZE)
# define FORK_FS0_OFFSET (FORK_INT_SIZE + 0*FPU_REG_FULL_SIZE)
# define FORK_FS1_OFFSET (FORK_INT_SIZE + 1*FPU_REG_FULL_SIZE)
# define FORK_FS2_OFFSET (FORK_INT_SIZE + 2*FPU_REG_FULL_SIZE)
diff --git a/arch/risc-v/src/common/riscv_fpu.S b/arch/risc-v/src/common/riscv_fpu.S
index 84989ccbf3..9d5feb9390 100644
--- a/arch/risc-v/src/common/riscv_fpu.S
+++ b/arch/risc-v/src/common/riscv_fpu.S
@@ -1,4 +1,4 @@
-/************************************************************************************
+/****************************************************************************
* arch/risc-v/src/common/riscv_fpu.S
*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -16,11 +16,11 @@
* License for the specific language governing permissions and limitations
* under the License.
*
- ************************************************************************************/
+ ****************************************************************************/
-/************************************************************************************
+/****************************************************************************
* Included Files
- ************************************************************************************/
+ ****************************************************************************/
#include <nuttx/config.h>
@@ -29,20 +29,24 @@
#include <arch/irq.h>
#include <arch/mode.h>
+#include "riscv_macros.S"
+
#ifdef CONFIG_ARCH_FPU
-/************************************************************************************
+/****************************************************************************
* Public Symbols
- ************************************************************************************/
+ ****************************************************************************/
.globl riscv_fpuconfig
+ .globl riscv_savefpu
+ .globl riscv_restorefpu
.file "riscv_fpu.S"
-/************************************************************************************
+/****************************************************************************
* Public Functions
- ************************************************************************************/
+ ****************************************************************************/
-/************************************************************************************
+/****************************************************************************
* Name: riscv_fpuconfig
*
* Description:
@@ -57,18 +61,95 @@
* Returned Value:
* This function does not return anything explicitly.
*
- ************************************************************************************/
+ ****************************************************************************/
.type riscv_fpuconfig, function
riscv_fpuconfig:
- li a0, MSTATUS_FS_INIT
- csrs CSR_STATUS, a0
+ li a0, MSTATUS_FS_INIT
+ csrs CSR_STATUS, a0
+
+ fsflags zero
+ fsrm zero
+
+ fence.i
+ ret
+
+/****************************************************************************
+ * Name: riscv_savefpu
+ *
+ * Description:
+ * Given the pointer to a register save area (in A0), save the state of the
+ * floating point registers.
+ *
+ * C Function Prototype:
+ * void riscv_savefpu(uintptr_t *regs, uintptr_t *fregs);
+ *
+ * Input Parameters:
+ * regs - A pointer to the integer registers that contain the status
+ * fregs - A pointer to the register save area in which to save the
+ * floating point registers
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+ .type riscv_savefpu, function
+
+riscv_savefpu:
+
+ REGLOAD t0, REG_INT_CTX(a0)
+ li t1, MSTATUS_FS
+ and t2, t0, t1
+ li t1, MSTATUS_FS_DIRTY
+ bne t2, t1, 1f
+ li t1, ~MSTATUS_FS
+ and t0, t0, t1
+ li t1, MSTATUS_FS_CLEAN
+ or t0, t0, t1
+ REGSTORE t0, REG_INT_CTX(a0)
+
+ riscv_savefpu a1
+
+1:
+ ret
+
+/****************************************************************************
+ * Name: riscv_restorefpu
+ *
+ * Description:
+ * Given the pointer to a register save area (in A0), restore the state of
+ * the floating point registers.
+ *
+ * C Function Prototype:
+ * void riscv_restorefpu(uintptr_t *regs, uintptr_t *fregs);
+ *
+ * Input Parameters:
+ * regs - A pointer to the integer registers that contain the status
+ * fregs - A pointer to the register save area containing the floating
+ * point registers.
+ *
+ * Returned Value:
+ * This function does not return anything explicitly. However, it is
+ * called from interrupt level assembly logic that assumes that r0 is
+ * preserved.
+ *
+ ****************************************************************************/
+
+ .type riscv_restorefpu, function
+
+riscv_restorefpu:
+
+ REGLOAD t0, REG_INT_CTX(a0)
+ li t1, MSTATUS_FS
+ and t2, t0, t1
+ li t1, MSTATUS_FS_INIT
+ ble t2, t1, 1f
- fsflags zero
- fsrm zero
+ riscv_loadfpu a1
- fence.i
- ret
+1:
+ ret
#endif /* CONFIG_ARCH_FPU */
diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h
index 6b385818cb..836d7354f5 100644
--- a/arch/risc-v/src/common/riscv_internal.h
+++ b/arch/risc-v/src/common/riscv_internal.h
@@ -204,8 +204,12 @@ void riscv_exception_attach(void);
#ifdef CONFIG_ARCH_FPU
void riscv_fpuconfig(void);
+void riscv_savefpu(uintptr_t *regs, uintptr_t *fregs);
+void riscv_restorefpu(uintptr_t *regs, uintptr_t *fregs);
#else
# define riscv_fpuconfig()
+# define riscv_savefpu(regs, fregs)
+# define riscv_restorefpu(regs, fregs)
#endif
/* Save / restore context of task */
@@ -213,11 +217,23 @@ void riscv_fpuconfig(void);
static inline void riscv_savecontext(struct tcb_s *tcb)
{
tcb->xcp.regs = (uintptr_t *)CURRENT_REGS;
+
+#ifdef CONFIG_ARCH_FPU
+ /* Save current process FPU state to TCB */
+
+ riscv_savefpu(tcb->xcp.regs, tcb->xcp.fregs);
+#endif
}
static inline void riscv_restorecontext(struct tcb_s *tcb)
{
CURRENT_REGS = (uintptr_t *)tcb->xcp.regs;
+
+#ifdef CONFIG_ARCH_FPU
+ /* Restore FPU state for next process */
+
+ riscv_restorefpu(tcb->xcp.regs, tcb->xcp.fregs);
+#endif
}
/* RISC-V PMP Config ********************************************************/
diff --git a/arch/risc-v/src/common/riscv_macros.S b/arch/risc-v/src/common/riscv_macros.S
index 83626b05b0..5f9bd12f65 100644
--- a/arch/risc-v/src/common/riscv_macros.S
+++ b/arch/risc-v/src/common/riscv_macros.S
@@ -100,13 +100,6 @@
.macro riscv_savefpu in
-#ifdef CONFIG_ARCH_FPU
- REGLOAD t0, REG_INT_CTX(\in)
- li t1, MSTATUS_FS
- and t0, t0, t1
- li t1, MSTATUS_FS_INIT
- ble t0, t1, 1f
-
/* Store all floating point registers */
FSTORE f0, REG_F0(\in)
@@ -145,14 +138,6 @@
frcsr t0
REGSTORE t0, REG_FCSR(\in)
-1:
-
- /* Restore what we have just destroyed (t0, t1) */
-
- REGLOAD t0, REG_T0(\in)
- REGLOAD t1, REG_T1(\in)
-#endif
-
.endm
/****************************************************************************
@@ -216,13 +201,6 @@
.macro riscv_loadfpu out
-#ifdef CONFIG_ARCH_FPU
- REGLOAD t0, REG_INT_CTX(\out)
- li t1, MSTATUS_FS
- and t0, t0, t1
- li t1, MSTATUS_FS_INIT
- ble t0, t1, 1f
-
/* Load all floating point registers */
FLOAD f0, REG_F0(\out)
@@ -263,14 +241,6 @@
REGLOAD t0, REG_FCSR(\out)
fscsr t0
-1:
-
- /* Restore what we have just destroyed (t0, t1) */
-
- REGLOAD t0, REG_T0(\out)
- REGLOAD t1, REG_T1(\out)
-#endif
-
.endm
/****************************************************************************
diff --git a/arch/risc-v/src/common/riscv_swint.c b/arch/risc-v/src/common/riscv_swint.c
index dc2c11f00e..0a262fe700 100644
--- a/arch/risc-v/src/common/riscv_swint.c
+++ b/arch/risc-v/src/common/riscv_swint.c
@@ -153,7 +153,7 @@ int riscv_swint(int irq, void *context, void *arg)
struct tcb_s *next = (struct tcb_s *)regs[REG_A1];
DEBUGASSERT(regs[REG_A1] != 0);
- CURRENT_REGS = (uintptr_t *)next->xcp.regs;
+ riscv_restorecontext(next);
}
break;
@@ -180,8 +180,8 @@ int riscv_swint(int irq, void *context, void *arg)
struct tcb_s *next = (struct tcb_s *)regs[REG_A2];
DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0);
- prev->xcp.regs = (uintptr_t *)CURRENT_REGS;
- CURRENT_REGS = (uintptr_t *)next->xcp.regs;
+ riscv_savecontext(prev);
+ riscv_restorecontext(next);
}
break;
diff --git a/arch/risc-v/src/common/supervisor/riscv_syscall.S b/arch/risc-v/src/common/supervisor/riscv_syscall.S
index 18804a49f1..3e4515fea7 100644
--- a/arch/risc-v/src/common/supervisor/riscv_syscall.S
+++ b/arch/risc-v/src/common/supervisor/riscv_syscall.S
@@ -109,8 +109,6 @@ sys_call6:
addi s0, sp, XCPTCONTEXT_SIZE
REGSTORE s0, REG_SP(sp) /* original SP */
- riscv_savefpu sp
-
mv a0, sp /* a0 = context */
#if CONFIG_ARCH_INTERRUPTSTACK > 15
@@ -127,8 +125,6 @@ sys_call6:
mv sp, a0 /* use sp, as a0 gets wiped */
- riscv_loadfpu sp
-
REGLOAD s0, REG_EPC(sp) /* restore epc */
csrw CSR_EPC, s0
[nuttx] 03/08: riscv/riscv_fpu: Clear the full FPU status/control register on boot
Posted by xi...@apache.org.
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/nuttx.git
commit 0ea9debfceacb9e1989cdfc2572695a67a2a8116
Author: Ville Juven <vi...@unikie.com>
AuthorDate: Thu Jul 27 11:05:19 2023 +0300
riscv/riscv_fpu: Clear the full FPU status/control register on boot
Instead of clearing the fields individually, just wipe the whole register.
This can be done because flags and rm are just parts of the fcsr.
31 8 5 0
+--------------+--------+-----------+
| | | |
| RESERVED | FRM | FSTATUS |
| | | |
+--------------+--------+-----------+
FCSR
---
arch/risc-v/src/common/riscv_fpu.S | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/risc-v/src/common/riscv_fpu.S b/arch/risc-v/src/common/riscv_fpu.S
index 9d5feb9390..cc88e769dd 100644
--- a/arch/risc-v/src/common/riscv_fpu.S
+++ b/arch/risc-v/src/common/riscv_fpu.S
@@ -69,8 +69,7 @@ riscv_fpuconfig:
li a0, MSTATUS_FS_INIT
csrs CSR_STATUS, a0
- fsflags zero
- fsrm zero
+ fscsr zero
fence.i
ret