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 2024/10/18 11:35:05 UTC
(nuttx) 02/03: riscv/mpfs: Add boilerplate code for SMP
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 a33e63097accaaa3f718dc262d0ad8a90360c9b5
Author: Ville Juven <vi...@unikie.com>
AuthorDate: Fri Oct 11 13:21:59 2024 +0300
riscv/mpfs: Add boilerplate code for SMP
---
arch/risc-v/Kconfig | 1 +
arch/risc-v/src/mpfs/hardware/mpfs_clint.h | 2 ++
arch/risc-v/src/mpfs/mpfs_head.S | 15 ++++++---------
arch/risc-v/src/mpfs/mpfs_irq.c | 10 ++++++++++
arch/risc-v/src/mpfs/mpfs_shead.S | 12 ++++++++++--
arch/risc-v/src/mpfs/mpfs_start.c | 13 +++++++++++++
6 files changed, 42 insertions(+), 11 deletions(-)
diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig
index 052954b6d0..538e90a133 100644
--- a/arch/risc-v/Kconfig
+++ b/arch/risc-v/Kconfig
@@ -203,6 +203,7 @@ config ARCH_CHIP_MPFS
select ARCH_RV_ISA_C
select ARCH_HAVE_FPU
select ARCH_HAVE_DPFPU
+ select ARCH_HAVE_MULTICPU
select ARCH_HAVE_MPU
select ARCH_MMU_TYPE_SV39
select ARCH_HAVE_ADDRENV
diff --git a/arch/risc-v/src/mpfs/hardware/mpfs_clint.h b/arch/risc-v/src/mpfs/hardware/mpfs_clint.h
index a15d849267..b83c14e0d7 100644
--- a/arch/risc-v/src/mpfs/hardware/mpfs_clint.h
+++ b/arch/risc-v/src/mpfs/hardware/mpfs_clint.h
@@ -39,4 +39,6 @@
#define MPFS_CLINT_MTIME (MPFS_CLINT_BASE + 0xbff8)
+#define RISCV_IPI MPFS_CLINT_MSIP0
+
#endif /* __ARCH_RISCV_SRC_MPFS_HARDWARE_MPFS_CLINT_H */
diff --git a/arch/risc-v/src/mpfs/mpfs_head.S b/arch/risc-v/src/mpfs/mpfs_head.S
index b223c84ec7..e691be33f5 100644
--- a/arch/risc-v/src/mpfs/mpfs_head.S
+++ b/arch/risc-v/src/mpfs/mpfs_head.S
@@ -29,6 +29,7 @@
#include "chip.h"
#include "mpfs_memorymap.h"
#include "riscv_internal.h"
+#include "riscv_macros.S"
/****************************************************************************
* Public Symbols
@@ -183,21 +184,17 @@ __start:
/* Set stack pointer to the idle thread stack */
+#ifdef CONFIG_SMP
+ addi a1, a0, -1 /* Only cores 1...3 can participate in SMP */
+ riscv_set_inital_sp MPFS_IDLESTACK_BASE, SMP_STACK_SIZE, a1
+#else
la sp, MPFS_IDLESTACK_TOP
+#endif
/* Jump to __mpfs_start with mhartid in a0 */
tail __mpfs_start
- /* We shouldn't return from __mpfs_start
- * in case of return, loop forever. nop's added so can be seen in debugger
- */
-
-1:
- nop
- nop
- j 1b
-
.global _init
.global _fini
diff --git a/arch/risc-v/src/mpfs/mpfs_irq.c b/arch/risc-v/src/mpfs/mpfs_irq.c
index 5ee1a744ed..ff5cec7f3f 100644
--- a/arch/risc-v/src/mpfs/mpfs_irq.c
+++ b/arch/risc-v/src/mpfs/mpfs_irq.c
@@ -33,6 +33,8 @@
#include <nuttx/irq.h>
#include "riscv_internal.h"
+#include "riscv_ipi.h"
+
#include "mpfs.h"
#include "mpfs_plic.h"
@@ -96,6 +98,14 @@ void up_irqinitialize(void)
riscv_exception_attach();
+#ifdef CONFIG_SMP
+ /* Clear IPI for CPU0 */
+
+ riscv_ipi_clear(0);
+
+ up_enable_irq(RISCV_IRQ_SOFT);
+#endif
+
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* And finally, enable interrupts */
diff --git a/arch/risc-v/src/mpfs/mpfs_shead.S b/arch/risc-v/src/mpfs/mpfs_shead.S
index b73127f437..bd6e479cf1 100644
--- a/arch/risc-v/src/mpfs/mpfs_shead.S
+++ b/arch/risc-v/src/mpfs/mpfs_shead.S
@@ -95,5 +95,13 @@ __start:
/* Set stack pointer and jump to start */
- la sp, MPFS_IDLESTACK_TOP
- j __mpfs_start
+#ifdef CONFIG_SMP
+ addi a1, a0, -1 /* Only cores 1...3 can participate in SMP */
+ riscv_set_inital_sp MPFS_IDLESTACK_BASE, SMP_STACK_SIZE, a1
+#else
+ la sp, MPFS_IDLESTACK_TOP
+#endif
+
+ /* Jump to __mpfs_start with mhartid in a0 */
+
+ tail __mpfs_start
diff --git a/arch/risc-v/src/mpfs/mpfs_start.c b/arch/risc-v/src/mpfs/mpfs_start.c
index a7559da105..3e18a4b96b 100644
--- a/arch/risc-v/src/mpfs/mpfs_start.c
+++ b/arch/risc-v/src/mpfs/mpfs_start.c
@@ -81,6 +81,13 @@ void __mpfs_start(uint64_t mhartid)
riscv_fpuconfig();
}
+ /* CPU 0 handles the boot, the rest wait */
+
+ if (riscv_hartid_to_cpuid(mhartid) != 0)
+ {
+ goto cpux;
+ }
+
/* Clear .bss. We'll do this inline (vs. calling memset) just to be
* certain that there are no issues with the state of global variables.
*/
@@ -185,6 +192,12 @@ void __mpfs_start(uint64_t mhartid)
showprogress('a');
+cpux:
+
+#ifdef CONFIG_SMP
+ riscv_cpu_boot(riscv_hartid_to_cpuid(mhartid));
+#endif
+
while (true)
{
asm("WFI");