Skip to content

Commit 846581f

Browse files
committed
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 <[email protected]>
1 parent fe45d8a commit 846581f

File tree

3 files changed

+45
-31
lines changed

3 files changed

+45
-31
lines changed

arch/risc-v/src/k230/k230_hart.c

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@
8181

8282
#define RESET_WAIT_USEC 100
8383

84+
/* PMP openall flag */
85+
86+
#define PMP_NAPOT_RWX (PMPCFG_A_NAPOT | PMPCFG_RWX_MASK)
87+
8488
/****************************************************************************
8589
* Private Variables
8690
****************************************************************************/
@@ -163,13 +167,14 @@ bool k230_hart_is_big(void)
163167

164168
void k230_hart_big_stop(void)
165169
{
166-
if (k230_hart_is_big()) return;
167-
168-
/* 0x10001 set RESET */
169-
170-
putreg32(RESET_RQST_BIT | RESET_RQST_ENW, K230_CPU1_RESET);
171-
up_udelay(RESET_WAIT_USEC);
172-
sinfo("reg: %" PRIx32 "\n", getreg32(K230_CPU1_RESET));
170+
if (!k230_hart_is_big())
171+
{
172+
/* 0x10001 set RESET */
173+
174+
putreg32(RESET_RQST_BIT | RESET_RQST_ENW, K230_CPU1_RESET);
175+
up_udelay(RESET_WAIT_USEC);
176+
sinfo("reg: %" PRIx32 "\n", getreg32(K230_CPU1_RESET));
177+
}
173178
}
174179

175180
/****************************************************************************
@@ -179,27 +184,28 @@ void k230_hart_big_stop(void)
179184

180185
void k230_hart_big_boot(uintptr_t addr)
181186
{
182-
if (k230_hart_is_big()) return;
187+
if (!k230_hart_is_big() && addr != NULL)
188+
{
189+
/* learned from U-Boot baremetal and RTT sysctl_reset_cpu */
183190

184-
/* learned from U-Boot baremetal and RTT sysctl_reset_cpu */
191+
putreg32(addr, K230_CPU1_BOOTA);
192+
sinfo("addr=%"PRIxPTR"\n", addr);
185193

186-
if (addr) putreg32(addr, K230_CPU1_BOOTA);
187-
sinfo("addr=%"PRIxPTR"\n", addr);
194+
/* 0x10001000 clear DONE bit */
188195

189-
/* 0x10001000 clear DONE bit */
196+
putreg32(RESET_DONE_BIT | RESET_DONE_ENW, K230_CPU1_RESET);
197+
up_udelay(RESET_WAIT_USEC);
190198

191-
putreg32(RESET_DONE_BIT | RESET_DONE_ENW, K230_CPU1_RESET);
192-
up_udelay(RESET_WAIT_USEC);
199+
/* 0x10001 set RQST bit */
193200

194-
/* 0x10001 set RQST bit */
201+
putreg32(RESET_RQST_BIT | RESET_RQST_ENW, K230_CPU1_RESET);
202+
up_udelay(RESET_WAIT_USEC);
195203

196-
putreg32(RESET_RQST_BIT | RESET_RQST_ENW, K230_CPU1_RESET);
197-
up_udelay(RESET_WAIT_USEC);
204+
/* 0x10000 clear RQST bit */
198205

199-
/* 0x10000 clear RQST bit */
200-
201-
putreg32(RESET_RQST_ENW, K230_CPU1_RESET);
202-
up_udelay(RESET_WAIT_USEC);
206+
putreg32(RESET_RQST_ENW, K230_CPU1_RESET);
207+
up_udelay(RESET_WAIT_USEC);
208+
}
203209
}
204210

205211
#endif /* !defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_NUTTSBI) */
@@ -217,5 +223,9 @@ void sbi_late_initialize(void)
217223

218224
putreg32(1, K230_PLIC_CTRL);
219225
k230_hart_init();
226+
227+
/* Open everything for PMP */
228+
229+
DEBUGASSERT(riscv_append_pmp_region(PMP_NAPOT_RWX, 0, 0) == 0);
220230
}
221231
#endif

arch/risc-v/src/nuttsbi/sbi_internal.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,11 @@ void sbi_set_mtimecmp(uint64_t value);
169169
* Description:
170170
* Conduct any device specific initialization before entering S-mode from
171171
* NUTTSBI as some chips need such preparations. This function still runs
172-
* in M-mode.
172+
* in M-mode. Things like PMP setting up or device specific prepration
173+
* before entering S-mode can be done here.
174+
*
175+
* If this is enabled, PMP setup logic in sbi_start.c is bypassed so that
176+
* PMP management is done at one place.
173177
*
174178
****************************************************************************/
175179

arch/risc-v/src/nuttsbi/sbi_start.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
* Preprocecssor definitions
3737
****************************************************************************/
3838

39-
#define NAPOT_OPENALL (PMPCFG_A_NAPOT | PMPCFG_RWX_MASK)
39+
#define NAPOT_RWX (PMPCFG_A_NAPOT | PMPCFG_RWX_MASK)
4040

4141
/****************************************************************************
4242
* Private Functions
@@ -113,19 +113,19 @@ void sbi_start(void)
113113
WRITE_CSR(CSR_MCOUNTEREN, UINT32_C(~0));
114114
WRITE_CSR(CSR_SCOUNTEREN, UINT32_C(~0));
115115

116-
#ifdef CONFIG_NUTTSBI_LATE_INIT
117-
/* Do device specific initialization as needed */
118-
119-
sbi_late_initialize();
120-
#endif
121-
122116
/* Set program counter to __start_s */
123117

124118
WRITE_CSR(CSR_MEPC, __start_s);
125119

126-
/* Open everything for PMP */
120+
#ifdef CONFIG_NUTTSBI_LATE_INIT
121+
/* Do device specific handling */
122+
123+
sbi_late_initialize();
124+
#else
125+
/* Open everything for PMP, may fail if no empty entry left */
127126

128-
DEBUGASSERT(riscv_append_pmp_region(NAPOT_OPENALL, 0, 0) == 0);
127+
DEBUGASSERT(riscv_append_pmp_region(NAPOT_RWX, 0, 0) == 0);
128+
#endif
129129

130130
/* Then jump to the S-mode start function */
131131

0 commit comments

Comments
 (0)