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.