Skip to content

Commit 5c9733b

Browse files
committed
Fix for Yocto Linux boot issue with smpboot and hartid.
1 parent 8acb3eb commit 5c9733b

1 file changed

Lines changed: 81 additions & 2 deletions

File tree

src/boot_riscv.c

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525

2626
#include "image.h"
2727
#include "loader.h"
28+
#ifdef DEBUG_BOOT
29+
#include "printf.h"
30+
#endif
2831
#include "hal/riscv.h"
2932

3033
#ifdef TARGET_mpfs250
@@ -180,21 +183,97 @@ int WEAKFUNCTION hal_dts_fixup(void* dts_addr)
180183
}
181184
#endif
182185

186+
/* Get the hartid saved by boot_riscv_start.S in the tp register */
187+
static inline unsigned long get_boot_hartid(void)
188+
{
189+
unsigned long hartid;
190+
asm volatile("mv %0, tp" : "=r"(hartid));
191+
return hartid;
192+
}
193+
183194
#ifdef MMU
184195
void do_boot(const uint32_t *app_offset, const uint32_t* dts_offset)
185196
#else
186197
void do_boot(const uint32_t *app_offset)
187198
#endif
188199
{
200+
unsigned long hartid;
201+
#ifdef MMU
202+
unsigned long dts_addr;
203+
#endif
204+
189205
#ifdef MMU
190206
hal_dts_fixup((uint32_t*)dts_offset);
207+
dts_addr = (unsigned long)dts_offset;
208+
#endif
209+
210+
/* Get the hartid that was saved by boot_riscv_start.S in tp register.
211+
* This is the hartid passed to wolfBoot by the prior boot stage (e.g., HSS).
212+
* For MPFS, this should be 1-4 (U54 cores), never 0 (E51 monitor core). */
213+
hartid = get_boot_hartid();
214+
215+
#ifdef DEBUG_BOOT
216+
wolfBoot_printf("do_boot: hartid=%lu, entry=0x%lx",
217+
hartid, (unsigned long)app_offset);
218+
#ifdef MMU
219+
wolfBoot_printf(", dts=0x%lx", dts_addr);
220+
#endif
221+
wolfBoot_printf("\n");
191222
#endif
192223

193224
/* Relocate trap vector table to application */
194225
reloc_trap_vector(app_offset);
195226

196-
/* Jump to application entry point */
197-
asm volatile("jr %0":: "r"((uint8_t *)(app_offset)));
227+
/*
228+
* RISC-V Linux kernel boot requirements (Documentation/arch/riscv/boot.rst):
229+
* a0 = hartid of the current core
230+
* a1 = physical address of the device tree blob (DTB)
231+
* satp = 0 (MMU disabled)
232+
*
233+
* For SMP systems using ordered booting (preferred), only the boot hart
234+
* enters the kernel. Secondary harts are started via SBI HSM extension.
235+
*/
236+
237+
#if __riscv_xlen == 64
238+
asm volatile(
239+
/* Disable MMU by clearing satp (required for kernel entry) */
240+
#ifdef WOLFBOOT_RISCV_SMODE
241+
"csrw satp, zero\n"
242+
"sfence.vma\n"
243+
#endif
244+
/* Set up kernel entry arguments:
245+
* a0 = hartid (from our local variable)
246+
* a1 = DTB address (or 0 if no MMU/DTB)
247+
*/
248+
"mv a0, %0\n"
249+
#ifdef MMU
250+
"mv a1, %1\n"
251+
#else
252+
"mv a1, zero\n"
253+
#endif
254+
/* Jump to kernel entry point */
255+
#ifdef MMU
256+
"jr %2\n"
257+
#else
258+
"jr %1\n"
259+
#endif
260+
:
261+
: "r"(hartid),
262+
#ifdef MMU
263+
"r"(dts_addr),
264+
"r"(app_offset)
265+
#else
266+
"r"(app_offset)
267+
#endif
268+
: "a0", "a1"
269+
);
270+
#else /* RV32 */
271+
/* RV32: typically bare-metal without Linux, simpler boot */
272+
asm volatile("jr %0" : : "r"(app_offset));
273+
#endif
274+
275+
/* Should never reach here */
276+
__builtin_unreachable();
198277
}
199278

200279
void isr_empty(void)

0 commit comments

Comments
 (0)