Skip to content

Commit 2e54cf7

Browse files
dgarskedanielinux
authored andcommitted
Fix for Yocto Linux boot issue with smpboot and hartid.
1 parent 609fd81 commit 2e54cf7

File tree

1 file changed

+76
-2
lines changed

1 file changed

+76
-2
lines changed

src/boot_riscv.c

Lines changed: 76 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,92 @@ int WEAKFUNCTION hal_dts_fixup(void* dts_addr)
180183
}
181184
#endif
182185

186+
#if __riscv_xlen == 64
187+
/* Get the hartid saved by boot_riscv_start.S in the tp register */
188+
static inline unsigned long get_boot_hartid(void)
189+
{
190+
unsigned long hartid;
191+
asm volatile("mv %0, tp" : "=r"(hartid));
192+
return hartid;
193+
}
194+
#endif
195+
183196
#ifdef MMU
184197
void do_boot(const uint32_t *app_offset, const uint32_t* dts_offset)
185198
#else
186199
void do_boot(const uint32_t *app_offset)
187200
#endif
188201
{
202+
#if __riscv_xlen == 64
203+
unsigned long hartid;
204+
#endif
205+
#ifdef MMU
206+
unsigned long dts_addr;
207+
#endif
208+
189209
#ifdef MMU
190210
hal_dts_fixup((uint32_t*)dts_offset);
211+
dts_addr = (unsigned long)dts_offset;
212+
#endif
213+
214+
#if __riscv_xlen == 64
215+
/* Get the hartid that was saved by boot_riscv_start.S in tp register.
216+
* This is the hartid passed to wolfBoot by the prior boot stage (e.g., HSS).
217+
* For MPFS, this should be 1-4 (U54 cores), never 0 (E51 monitor core). */
218+
hartid = get_boot_hartid();
219+
#endif
220+
221+
#ifdef DEBUG_BOOT
222+
wolfBoot_printf("do_boot: entry=0x%lx", (unsigned long)app_offset);
223+
#if __riscv_xlen == 64
224+
wolfBoot_printf(", hartid=%lu", hartid);
225+
#endif
226+
#ifdef MMU
227+
wolfBoot_printf(", dts=0x%lx", dts_addr);
228+
#endif
229+
wolfBoot_printf("\n");
191230
#endif
192231

193232
/* Relocate trap vector table to application */
194233
reloc_trap_vector(app_offset);
195234

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

200274
void isr_empty(void)

0 commit comments

Comments
 (0)