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 2022/04/07 13:55:43 UTC

[incubator-nuttx] branch master updated: MPFS: Prepare support for S-mode

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/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new d38b4965f8 MPFS: Prepare support for S-mode
d38b4965f8 is described below

commit d38b4965f809a95b07f899d996ca3487f713f351
Author: Ville Juven <vi...@unikie.com>
AuthorDate: Wed Apr 6 15:09:05 2022 +0300

    MPFS: Prepare support for S-mode
    
    - Access to PLIC via S-mode registers
    - Access to IRQs via S-mode registers / definitions
    - Initialize S-mode registers upon boot
    - Initialize per CPU area before nx_start
    
    NOTE: S-mode requires a companion SW (SBI) which is not yet implemented,
    thus S-mode is not usable as is, yet.
---
 arch/risc-v/src/mpfs/hardware/mpfs_plic.h |  4 +++-
 arch/risc-v/src/mpfs/mpfs_head.S          | 20 +++++++++-------
 arch/risc-v/src/mpfs/mpfs_irq.c           | 39 +++++++++++++++----------------
 arch/risc-v/src/mpfs/mpfs_irq_dispatch.c  | 14 +++++------
 arch/risc-v/src/mpfs/mpfs_plic.c          | 20 +++++++++++++---
 arch/risc-v/src/mpfs/mpfs_start.c         | 15 ++++++++++++
 6 files changed, 72 insertions(+), 40 deletions(-)

diff --git a/arch/risc-v/src/mpfs/hardware/mpfs_plic.h b/arch/risc-v/src/mpfs/hardware/mpfs_plic.h
index 11513b7161..67223d14b4 100755
--- a/arch/risc-v/src/mpfs/hardware/mpfs_plic.h
+++ b/arch/risc-v/src/mpfs/hardware/mpfs_plic.h
@@ -102,7 +102,9 @@
 #define MPFS_PLIC_MTHRESHOLD_OFFSET  (0x0000)
 #define MPFS_PLIC_MCLAIM_OFFSET      (0x0004)
 #define MPFS_PLIC_STHRESHOLD_OFFSET  (0x1000)
-#define MPFS_PLIC_SCLAIM_OFFSET      (0x1004)
+#define MPFS_PLIC_SCLAIM_OFFSET      (0x1004) /* From hart base */
+#define MPFS_PLIC_CLAIM_S_OFFSET     (0x1000) /* From mclaim to sclaim */
+#define MPFS_PLIC_THRESHOLD_S_OFFSET (0x1000) /* From mthresh to sthresh */
 
 #define MPFS_PLIC_H0_MTHRESHOLD  (MPFS_PLIC_BASE + 0x200000)
 #define MPFS_PLIC_H0_MCLAIM      (MPFS_PLIC_BASE + 0x200004)
diff --git a/arch/risc-v/src/mpfs/mpfs_head.S b/arch/risc-v/src/mpfs/mpfs_head.S
index e375dce060..30c94f513e 100755
--- a/arch/risc-v/src/mpfs/mpfs_head.S
+++ b/arch/risc-v/src/mpfs/mpfs_head.S
@@ -100,6 +100,17 @@ __start:
   csrr a0, mhartid
   beqz a0, .skip_e51
 
+  /* Clear sscratch if u54 */
+
+  csrw sscratch, zero
+  csrw scause, zero
+  csrw sepc, zero
+
+  /* Disable all interrupts in sie */
+
+  csrw sie, zero
+  csrw sip, zero
+
   /* Init delegation registers, mideleg, medeleg, if a U54
    * These are not initialised by the hardware and come up in a random state
    */
@@ -116,15 +127,6 @@ __start:
 
   sfence.vma x0, x0
 
-  /* Enable accelerator if present, setting ignored on E51
-   * 15,16 = MSTATUS_XS, 17,18 = MSTATUS_MPRV
-   * not defined on riscv-v/include/csr.h
-   */
-
-  /*  li      t0, (1 << 15) | (1 << 16) | (1 << 17) | (1 << 18) */
-  li t0, 0x00018000 /* MSTATUS_XS */
-  csrs    mstatus, t0
-
 .skip_e51:
 
 /* initialize global pointer, global data
diff --git a/arch/risc-v/src/mpfs/mpfs_irq.c b/arch/risc-v/src/mpfs/mpfs_irq.c
index 3657f4f901..ce9ff8f919 100755
--- a/arch/risc-v/src/mpfs/mpfs_irq.c
+++ b/arch/risc-v/src/mpfs/mpfs_irq.c
@@ -56,10 +56,6 @@ void up_irqinitialize(void)
 
   up_irq_save();
 
-  /* Disable timer interrupt (in case of hotloading with debugger) */
-
-  up_disable_irq(RISCV_IRQ_MTIMER);
-
   /* Disable all global interrupts for current hart */
 
   uintptr_t iebase = mpfs_plic_get_iebase();
@@ -104,7 +100,9 @@ void up_irqinitialize(void)
 
   /* Attach the ecall interrupt handler */
 
+#ifndef CONFIG_ARCH_USE_S_MODE
   irq_attach(RISCV_IRQ_ECALLM, riscv_swint, NULL);
+#endif
 
 #ifndef CONFIG_BUILD_FLAT
   irq_attach(RISCV_IRQ_ECALLU, riscv_swint, NULL);
@@ -130,17 +128,17 @@ void up_disable_irq(int irq)
 {
   int extirq = 0;
 
-  if (irq == RISCV_IRQ_MSOFT)
+  if (irq == RISCV_IRQ_SOFT)
     {
-      /* Read mstatus & clear machine software interrupt enable in mie */
+      /* Read m/sstatus & clear machine software interrupt enable in m/sie */
 
-      CLEAR_CSR(mie, MIE_MSIE);
+      CLEAR_CSR(CSR_IE, IE_SIE);
     }
-  else if (irq == RISCV_IRQ_MTIMER)
+  else if (irq == RISCV_IRQ_TIMER)
     {
-      /* Read mstatus & clear machine timer interrupt enable in mie */
+      /* Read m/sstatus & clear timer interrupt enable in m/sie */
 
-      CLEAR_CSR(mie, MIE_MTIE);
+      CLEAR_CSR(CSR_IE, IE_TIE);
     }
   else if (irq >= MPFS_IRQ_EXT_START)
     {
@@ -173,17 +171,17 @@ void up_enable_irq(int irq)
 {
   int extirq;
 
-  if (irq == RISCV_IRQ_MSOFT)
+  if (irq == RISCV_IRQ_SOFT)
     {
-      /* Read mstatus & set machine software interrupt enable in mie */
+      /* Read m/sstatus & set machine software interrupt enable in m/sie */
 
-      SET_CSR(mie, MIE_MSIE);
+      SET_CSR(CSR_IE, IE_SIE);
     }
-  else if (irq == RISCV_IRQ_MTIMER)
+  else if (irq == RISCV_IRQ_TIMER)
     {
-      /* Read mstatus & set machine timer interrupt enable in mie */
+      /* Read m/sstatus & set timer interrupt enable in m/sie */
 
-      SET_CSR(mie, MIE_MTIE);
+      SET_CSR(CSR_IE, IE_TIE);
     }
   else if (irq >= MPFS_IRQ_EXT_START)
     {
@@ -228,12 +226,13 @@ irqstate_t up_irq_enable(void)
 {
   irqstate_t oldstat;
 
-  /* Enable MEIE (machine external interrupt enable) */
+  /* Enable external interrupts (mie/sie) */
+
+  SET_CSR(CSR_IE, IE_EIE);
 
-  SET_CSR(mie, MIE_MEIE);
+  /* Read and enable global interrupts (M/SIE) in m/sstatus */
 
-  /* Read mstatus & set machine interrupt enable (MIE) in mstatus */
+  oldstat = READ_AND_SET_CSR(CSR_STATUS, STATUS_IE);
 
-  oldstat = READ_AND_SET_CSR(mstatus, MSTATUS_MIE);
   return oldstat;
 }
diff --git a/arch/risc-v/src/mpfs/mpfs_irq_dispatch.c b/arch/risc-v/src/mpfs/mpfs_irq_dispatch.c
index 168446df0e..51e3537a9d 100755
--- a/arch/risc-v/src/mpfs/mpfs_irq_dispatch.c
+++ b/arch/risc-v/src/mpfs/mpfs_irq_dispatch.c
@@ -49,7 +49,7 @@
 void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
 {
   int irq = (vector & 0x3f);
-  uintptr_t *mepc = regs;
+  uintptr_t *epc = regs;
 
   /* Check if fault happened  */
 
@@ -71,29 +71,29 @@ void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
 
   uintptr_t claim_address = mpfs_plic_get_claimbase();
 
-  if (irq == RISCV_IRQ_MEXT)
+  if (irq == RISCV_IRQ_EXT)
     {
       uint32_t ext = getreg32(claim_address);
 
-      /* Add the value to nuttx irq which is offset to the mext */
+      /* Add the value to nuttx irq which is offset to the ext */
 
       irq = MPFS_IRQ_EXT_START + ext;
     }
 
-  /* NOTE: In case of ecall, we need to adjust mepc in the context */
+  /* NOTE: In case of ecall, we need to adjust epc in the context */
 
   if (irq == RISCV_IRQ_ECALLM || irq == RISCV_IRQ_ECALLU)
     {
-      *mepc += 4;
+      *epc += 4;
     }
 
   /* Acknowledge the interrupt */
 
   riscv_ack_irq(irq);
 
-  /* MEXT means no interrupt */
+  /* EXT means no interrupt */
 
-  if (irq != RISCV_IRQ_MEXT && irq != MPFS_IRQ_INVALID)
+  if (irq != RISCV_IRQ_EXT && irq != MPFS_IRQ_INVALID)
     {
       /* Deliver the IRQ */
 
diff --git a/arch/risc-v/src/mpfs/mpfs_plic.c b/arch/risc-v/src/mpfs/mpfs_plic.c
index 98277ae05b..3de194c2e1 100644
--- a/arch/risc-v/src/mpfs/mpfs_plic.c
+++ b/arch/risc-v/src/mpfs/mpfs_plic.c
@@ -39,6 +39,18 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
+/* Offset to privilege mode, note that hart0 does not have S-mode */
+
+#ifdef CONFIG_ARCH_USE_S_MODE
+#  define MPFS_PLIC_IEPRIV_OFFSET         (MPFS_HART_SIE_OFFSET)
+#  define MPFS_PLIC_CLAIMPRIV_OFFSET      (MPFS_PLIC_CLAIM_S_OFFSET)
+#  define MPFS_PLIC_THRESHOLDPRIV_OFFSET  (MPFS_PLIC_THRESHOLD_S_OFFSET)
+#else
+#  define MPFS_PLIC_IEPRIV_OFFSET         (0)
+#  define MPFS_PLIC_CLAIMPRIV_OFFSET      (0)
+#  define MPFS_PLIC_THRESHOLDPRIV_OFFSET  (0)
+#endif
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -65,7 +77,8 @@ uintptr_t mpfs_plic_get_iebase(void)
     }
   else
     {
-      iebase = MPFS_PLIC_H1_MIE0 + (hart_id - 1) * MPFS_HART_MIE_OFFSET;
+      iebase = MPFS_PLIC_H1_MIE0 + MPFS_PLIC_IEPRIV_OFFSET +
+        (hart_id - 1) * MPFS_HART_MIE_OFFSET;
     }
 
   return iebase;
@@ -93,7 +106,7 @@ uintptr_t mpfs_plic_get_claimbase(void)
     }
   else
     {
-      claim_address = MPFS_PLIC_H1_MCLAIM +
+      claim_address = MPFS_PLIC_H1_MCLAIM + MPFS_PLIC_CLAIMPRIV_OFFSET +
         (hart_id - 1) * MPFS_PLIC_NEXTHART_OFFSET;
     }
 
@@ -123,7 +136,8 @@ uintptr_t mpfs_plic_get_thresholdbase(void)
   else
     {
       threshold_address = MPFS_PLIC_H1_MTHRESHOLD +
-        (hart_id - 1) * MPFS_PLIC_NEXTHART_OFFSET;
+          MPFS_PLIC_THRESHOLDPRIV_OFFSET +
+          (hart_id - 1) * MPFS_PLIC_NEXTHART_OFFSET;
     }
 
   return threshold_address;
diff --git a/arch/risc-v/src/mpfs/mpfs_start.c b/arch/risc-v/src/mpfs/mpfs_start.c
index ea4e004dd2..8c318218d9 100755
--- a/arch/risc-v/src/mpfs/mpfs_start.c
+++ b/arch/risc-v/src/mpfs/mpfs_start.c
@@ -34,7 +34,9 @@
 #include "mpfs_ddr.h"
 #include "mpfs_cache.h"
 #include "mpfs_userspace.h"
+
 #include "riscv_internal.h"
+#include "riscv_percpu.h"
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -46,6 +48,10 @@
 #  define showprogress(c)
 #endif
 
+#if defined (CONFIG_BUILD_KERNEL) && !defined (CONFIG_ARCH_USE_S_MODE)
+#  error "Target requires kernel in S-mode, enable CONFIG_ARCH_USE_S_MODE"
+#endif
+
 /****************************************************************************
  * Public Data
  ****************************************************************************/
@@ -169,6 +175,15 @@ void __mpfs_start(uint64_t mhartid)
 
   mpfs_boardinitialize();
 
+#ifdef CONFIG_ARCH_USE_S_MODE
+  /* Initialize the per CPU areas */
+
+  if (mhartid != 0)
+    {
+      riscv_percpu_add_hart(mhartid);
+    }
+#endif /* CONFIG_ARCH_USE_S_MODE */
+
   /* Initialize the caches.  Should only be executed from E51 (hart 0) to be
    * functional.  Consider the caches already configured if running without
    * the CONFIG_MPFS_BOOTLOADER -option.