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");