PolarFire SoC M-Mode, QSPI and L2-LIM support#667
PolarFire SoC M-Mode, QSPI and L2-LIM support#667dgarske wants to merge 3 commits intowolfSSL:masterfrom
Conversation
eba460a to
c9486a9
Compare
c9486a9 to
acfd97b
Compare
63adfa7 to
dd0a6be
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds Machine Mode (M-mode) support for PolarFire SoC MPFS250T, enabling wolfBoot to run directly from eNVM without requiring HSS (Hart Software Services) or DDR. The implementation boots from eNVM, executes from L2 Scratchpad SRAM, and loads signed applications from SC QSPI flash into on-chip LIM.
Changes:
- Added M-mode boot path with multi-hart support, L2 cache configuration, and per-hart UART
- Extended HAL with SC QSPI flash driver and UART-based QSPI programmer
- Refactored shared code (SDHCI, SCB mailbox, linker scripts) for both S-mode and M-mode builds
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| test-app/vector_riscv.S | Simplified to use mret for M-mode payload |
| test-app/startup_riscv.c | Updated to use M-mode CSRs (mtvec, mcause) |
| test-app/app_mpfs250.c | Removed duplicate UART/HAL init to avoid clearing TX FIFO |
| test-app/RISCV64-mpfs250.ld | Added dummy _main_hart_hls symbol |
| src/vector_riscv.S | Refactored to use MODE_PREFIX macro for CSR access |
| src/update_disk.c | Fixed unused variable warning with conditional compilation |
| src/sdhci.c | Moved power init into card init, added udelay helper, refined debug flags |
| src/boot_riscv_start.S | Added comprehensive M-mode boot sequence with eNVM-to-L2 copy |
| src/boot_riscv.c | Added M-mode to S-mode transition support and direct M-mode jump |
| hal/riscv.h | Extended with CLINT, L2 cache, and additional MSTATUS definitions |
| hal/mpfs250.h | Added L2 cache, UART mapping, HLS structures, and M-mode peripherals |
| hal/mpfs250.c | Refactored with L2 init, multi-hart support, and UART QSPI programmer |
| hal/mpfs250-m.ld | New M-mode linker script for eNVM + L2 SRAM layout |
| docs/Targets.md | Added M-mode documentation and updated S-mode references |
| config/examples/polarfire_mpfs250_m_qspi.config | New M-mode configuration file |
| config/examples/polarfire_mpfs250.config | Updated DTS comment and debug flag name |
| arch.mk | Added M-mode vs S-mode build logic with appropriate flags |
| .github/workflows/test-configs.yml | Added CI tests for M-mode configs |
| .gdbinit | Updated for RISC-V debugging |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 20 out of 20 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
c8aa0b5 to
0d5563a
Compare
0d5563a to
a59bd61
Compare
a59bd61 to
9b3b7e5
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 21 changed files in this pull request and generated 13 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 24 out of 24 changed files in this pull request and generated 13 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 28 changed files in this pull request and generated 9 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Adds support for running wolfBoot in **Machine Mode (M-mode)** on the PolarFire SoC MPFS250T, booting from eNVM and loading a signed application from **SC QSPI flash** into on-chip LIM (Loosely Integrated Memory). No HSS (Hart Software Services) or DDR is required. It also extends the existing PolarFire HAL with multi-hart support, L2 cache configuration, per-hart UART, and refactors shared code (SDHCI, SCB mailbox, linker/test-app) for both S-mode and M-mode builds.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 26 out of 27 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 28 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| /* Set up per-hart stack: base + (hartid+1)*STACK_SIZE_PER_HART */ | ||
| csrr a0, mhartid | ||
| la t0, _secondary_hart_stack_base | ||
| li t1, STACK_SIZE_PER_HART | ||
| addi a1, a0, 1 | ||
| mul t2, a1, t1 |
There was a problem hiding this comment.
The secondary-hart stack calculation uses (hartid + 1) * STACK_SIZE_PER_HART. With _secondary_hart_stack_base sized for only 4 secondary stacks, hart 4 computes an SP that can land above the secondary region and overlap the main stack. Use hartid * STACK_SIZE_PER_HART (for harts 1–4) or expand the reserved region/base to match the (hartid+1) indexing scheme.
| /* Set up per-hart stack: base + (hartid+1)*STACK_SIZE_PER_HART */ | |
| csrr a0, mhartid | |
| la t0, _secondary_hart_stack_base | |
| li t1, STACK_SIZE_PER_HART | |
| addi a1, a0, 1 | |
| mul t2, a1, t1 | |
| /* Set up per-hart stack: base + hartid*STACK_SIZE_PER_HART */ | |
| csrr a0, mhartid | |
| la t0, _secondary_hart_stack_base | |
| li t1, STACK_SIZE_PER_HART | |
| mul t2, a0, t1 |
| timeout = 10000; | ||
| while ((SCBCTRL_REG(SERVICES_CR_OFFSET) & SERVICES_CR_REQ_MASK) && timeout > 0) { | ||
| timeout--; | ||
| } | ||
|
|
||
| if (mpfs_scb_wait_clear(SERVICES_SR_OFFSET, SERVICES_SR_BUSY_MASK, | ||
| timeout) < 0) { | ||
| if (timeout == 0) { | ||
| wolfBoot_printf("SCB mailbox request timeout\n"); | ||
| return -3; | ||
| } | ||
|
|
||
| status = (SCBCTRL_REG(SERVICES_SR_OFFSET) >> SERVICES_SR_STATUS_SHIFT) | ||
| & 0xFFFF; | ||
| if (status != 0) { | ||
| return -4; | ||
| /* Wait for busy bit to clear (command completed) */ | ||
| timeout = 10000; | ||
| while (mpfs_scb_mailbox_busy() && timeout > 0) { | ||
| timeout--; | ||
| } |
There was a problem hiding this comment.
These SCB mailbox wait loops decrement a small fixed counter without any delay, so timeouts will elapse extremely quickly on a fast core and can fail even when the SCB would complete normally. Consider using a time-based timeout (e.g., hal_get_timer_us) or at least include a bounded delay per iteration, and/or reuse the existing mpfs_scb_wait_clear() with a meaningful timeout value.
| volatile uint32_t shared_mem_marker; /* 0x08: Init marker */ | ||
| volatile uint32_t shared_mem_status; /* 0x0C: Status */ | ||
| volatile uint64_t* shared_mem; /* 0x10: Shared memory pointer */ | ||
| volatile uint64_t reserved[2]; /* 0x18: Reserved/padding */ |
There was a problem hiding this comment.
HLS_DATA is annotated as 64 bytes, but the fields shown total 40 bytes on RV64 (16 bytes of u32s + 8-byte pointer + 16 bytes reserved). This is easy to get wrong given the assembly allocates/clears 64 bytes for HLS. Either adjust the struct padding to actually be 64 bytes (e.g., increase the reserved space) or correct the size/comments and ensure all users agree on the layout.
| volatile uint64_t reserved[2]; /* 0x18: Reserved/padding */ | |
| volatile uint64_t reserved[5]; /* 0x18: Reserved/padding to 64 bytes total */ |
| | Configuration | Config File | Boot Mode | Storage | Memory | HSS | | ||
| |---------------|-------------|-----------|---------|--------|-----| | ||
| | **SDCard** | `polarfire_mpfs250.config` | S-mode (U54 via HSS) | SD Card | DDR | Yes | | ||
| | **eMMC** | `polarfire_mpfs250.config` + `DISK_EMMC=1` | S-mode (U54 via HSS) | eMMC | DDR | Yes | | ||
| | **QSPI (S-mode)** | `polarfire_mpfs250_qspi.config` | S-mode (U54 via HSS) | MSS or SC QSPI | DDR | Yes | | ||
| | **QSPI + L2-LIM** | `polarfire_mpfs250_hss_l2lim.config` | S-mode (U54 via HSS) | SC QSPI | L2-LIM (no DDR) | Yes | | ||
| | **M-Mode (no HSS)** | `polarfire_mpfs250_m_qspi.config` | M-mode (E51, no HSS) | SC QSPI | L2 Scratchpad | No | |
There was a problem hiding this comment.
These markdown tables start each row with ||, which typically renders as an extra empty column (or breaks table formatting depending on the renderer). Use a single leading | for proper GitHub-flavored markdown tables.
Adds support for running wolfBoot in Machine Mode (M-mode) on the PolarFire SoC MPFS250T, booting from eNVM and loading a signed application from SC QSPI flash into on-chip LIM (Loosely Integrated Memory). No HSS (Hart Software Services) or DDR is required. It also extends the existing PolarFire HAL with multi-hart support, L2 cache configuration, per-hart UART, and refactors shared code (SDHCI, SCB mailbox, linker/test-app) for both S-mode and M-mode builds.