|
25 | 25 |
|
26 | 26 | #include "image.h" |
27 | 27 | #include "loader.h" |
| 28 | +#ifdef DEBUG_BOOT |
| 29 | +#include "printf.h" |
| 30 | +#endif |
28 | 31 | #include "hal/riscv.h" |
29 | 32 |
|
30 | 33 | #ifdef TARGET_mpfs250 |
@@ -180,21 +183,92 @@ int WEAKFUNCTION hal_dts_fixup(void* dts_addr) |
180 | 183 | } |
181 | 184 | #endif |
182 | 185 |
|
| 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 | + |
183 | 196 | #ifdef MMU |
184 | 197 | void do_boot(const uint32_t *app_offset, const uint32_t* dts_offset) |
185 | 198 | #else |
186 | 199 | void do_boot(const uint32_t *app_offset) |
187 | 200 | #endif |
188 | 201 | { |
| 202 | +#if __riscv_xlen == 64 |
| 203 | + unsigned long hartid; |
| 204 | +#endif |
| 205 | +#ifdef MMU |
| 206 | + unsigned long dts_addr; |
| 207 | +#endif |
| 208 | + |
189 | 209 | #ifdef MMU |
190 | 210 | 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"); |
191 | 230 | #endif |
192 | 231 |
|
193 | 232 | /* Relocate trap vector table to application */ |
194 | 233 | reloc_trap_vector(app_offset); |
195 | 234 |
|
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(); |
198 | 272 | } |
199 | 273 |
|
200 | 274 | void isr_empty(void) |
|
0 commit comments