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.
This commit is contained in:
parent
3a26cf6a02
commit
d38b4965f8
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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(mie, MIE_MEIE);
|
||||
SET_CSR(CSR_IE, IE_EIE);
|
||||
|
||||
/* Read mstatus & set machine interrupt enable (MIE) in mstatus */
|
||||
/* Read and enable global interrupts (M/SIE) in m/sstatus */
|
||||
|
||||
oldstat = READ_AND_SET_CSR(CSR_STATUS, STATUS_IE);
|
||||
|
||||
oldstat = READ_AND_SET_CSR(mstatus, MSTATUS_MIE);
|
||||
return oldstat;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user