|
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,97 @@ int WEAKFUNCTION hal_dts_fixup(void* dts_addr) |
180 | 183 | } |
181 | 184 | #endif |
182 | 185 |
|
| 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 | + |
183 | 194 | #ifdef MMU |
184 | 195 | void do_boot(const uint32_t *app_offset, const uint32_t* dts_offset) |
185 | 196 | #else |
186 | 197 | void do_boot(const uint32_t *app_offset) |
187 | 198 | #endif |
188 | 199 | { |
| 200 | + unsigned long hartid; |
| 201 | +#ifdef MMU |
| 202 | + unsigned long dts_addr; |
| 203 | +#endif |
| 204 | + |
189 | 205 | #ifdef MMU |
190 | 206 | 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"); |
191 | 222 | #endif |
192 | 223 |
|
193 | 224 | /* Relocate trap vector table to application */ |
194 | 225 | reloc_trap_vector(app_offset); |
195 | 226 |
|
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(); |
198 | 277 | } |
199 | 278 |
|
200 | 279 | void isr_empty(void) |
|
0 commit comments