riscv/nsbi: prefer PMP settings in device hook

This adjusts sbi_start behavior so that if SBI late initialization hook
is defined, PMP setting is assumed to be fully done in the hook, because
the default PMP operation may fail for various reasons such as lacking
free entries or the default setting doesn't work on devices like QEMU
v6.2.

Signed-off-by: Yanfeng Liu <yfliu2008@qq.com>
This commit is contained in:
Yanfeng Liu 2024-07-10 15:54:20 +08:00 committed by Xiang Xiao
parent f9cc33468f
commit 5e551632dd
3 changed files with 44 additions and 30 deletions

View File

@ -81,6 +81,10 @@
#define RESET_WAIT_USEC 100
/* PMP openall flag */
#define PMP_NAPOT_RWX (PMPCFG_A_NAPOT | PMPCFG_RWX_MASK)
/****************************************************************************
* Private Variables
****************************************************************************/
@ -163,13 +167,14 @@ bool k230_hart_is_big(void)
void k230_hart_big_stop(void)
{
if (k230_hart_is_big()) return;
if (!k230_hart_is_big())
{
/* 0x10001 set RESET */
putreg32(RESET_RQST_BIT | RESET_RQST_ENW, K230_CPU1_RESET);
up_udelay(RESET_WAIT_USEC);
sinfo("reg: %" PRIx32 "\n", getreg32(K230_CPU1_RESET));
}
}
/****************************************************************************
@ -179,11 +184,11 @@ void k230_hart_big_stop(void)
void k230_hart_big_boot(uintptr_t addr)
{
if (k230_hart_is_big()) return;
if (!k230_hart_is_big())
{
/* learned from U-Boot baremetal and RTT sysctl_reset_cpu */
if (addr) putreg32(addr, K230_CPU1_BOOTA);
putreg32(addr, K230_CPU1_BOOTA);
sinfo("addr=%"PRIxPTR"\n", addr);
/* 0x10001000 clear DONE bit */
@ -200,6 +205,7 @@ void k230_hart_big_boot(uintptr_t addr)
putreg32(RESET_RQST_ENW, K230_CPU1_RESET);
up_udelay(RESET_WAIT_USEC);
}
}
#endif /* !defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_NUTTSBI) */
@ -217,5 +223,9 @@ void sbi_late_initialize(void)
putreg32(1, K230_PLIC_CTRL);
k230_hart_init();
/* Open everything for PMP */
DEBUGASSERT(riscv_append_pmp_region(PMP_NAPOT_RWX, 0, 0) == 0);
}
#endif

View File

@ -169,7 +169,11 @@ void sbi_set_mtimecmp(uint64_t value);
* Description:
* Conduct any device specific initialization before entering S-mode from
* NUTTSBI as some chips need such preparations. This function still runs
* in M-mode.
* in M-mode. Things like PMP setting up or device specific prepration
* before entering S-mode can be done here.
*
* If this is enabled, PMP setup logic in sbi_start.c is bypassed so that
* PMP management is done at one place.
*
****************************************************************************/

View File

@ -36,7 +36,7 @@
* Preprocecssor definitions
****************************************************************************/
#define NAPOT_OPENALL (PMPCFG_A_NAPOT | PMPCFG_RWX_MASK)
#define NAPOT_RWX (PMPCFG_A_NAPOT | PMPCFG_RWX_MASK)
/****************************************************************************
* Private Functions
@ -113,19 +113,19 @@ void sbi_start(void)
WRITE_CSR(CSR_MCOUNTEREN, UINT32_C(~0));
WRITE_CSR(CSR_SCOUNTEREN, UINT32_C(~0));
#ifdef CONFIG_NUTTSBI_LATE_INIT
/* Do device specific initialization as needed */
sbi_late_initialize();
#endif
/* Set program counter to __start_s */
WRITE_CSR(CSR_MEPC, __start_s);
/* Open everything for PMP */
#ifdef CONFIG_NUTTSBI_LATE_INIT
/* Do device specific handling */
DEBUGASSERT(riscv_append_pmp_region(NAPOT_OPENALL, 0, 0) == 0);
sbi_late_initialize();
#else
/* Open everything for PMP, may fail if no empty entry left */
DEBUGASSERT(riscv_append_pmp_region(NAPOT_RWX, 0, 0) == 0);
#endif
/* Then jump to the S-mode start function */