Skip to content

PolarFire SoC M-Mode: Fix L2 scratchpad init, QSPI programmer and WDT support#747

Open
dgarske wants to merge 2 commits intowolfSSL:masterfrom
dgarske:polarfire_soc_mmode
Open

PolarFire SoC M-Mode: Fix L2 scratchpad init, QSPI programmer and WDT support#747
dgarske wants to merge 2 commits intowolfSSL:masterfrom
dgarske:polarfire_soc_mmode

Conversation

@dgarske
Copy link
Copy Markdown
Contributor

@dgarske dgarske commented Apr 13, 2026

PolarFire SoC M-Mode: Fix L2 scratchpad init, QSPI programmer, and add WDT support

Summary

  • Fix critical L2 cache/scratchpad initialization bug causing random illegal-instruction traps during crypto verification on E51 M-mode
  • Fix UART QSPI programmer stalling on USB-UART bridge bulk writes
  • Add WATCHDOG build option with boot ROM default restoration
  • Add stack overflow detection and stack painting diagnostics
  • Add STRIP_ELF and build-time safety checks

L2 Scratchpad Fix (root cause of TRAP cause=2)

The eNVM→L2 Scratchpad copy in boot_riscv_start.S wrote through the D-cache with WAY_MASK_E51_DCACHE = 0xFF (cache ways 0-7). Stores landed in cache and never reached the scratchpad SRAM (ways 8-11). The I-cache later fetched from the uninitialized scratchpad and got zeros, causing non-deterministic illegal-instruction traps during SHA384/ECDSA verification.

Fix: set WAY_MASK_E51_DCACHE = 0xF00 (scratchpad ways) before the copy, restore to 0xFF after. This follows the HSS mss_l2_cache.c config_l2_cache() pattern.

Also added fence rw,rw before fence.i after the copy — the standard RISC-V pattern for ensuring store visibility before I-cache invalidation.

QSPI Programmer Fix

The USB-UART bridge on the PolarFire Video Kit stalls when receiving bulk serial writes (256 bytes at once). The fix sends data in 8-byte pieces with 10ms inter-piece delays in mpfs_qspi_prog.py.

Additionally, the QSPI programmer now uses uart_qspi_puts() (direct UART register writes) instead of wolfBoot_printf() / uart_write() for all protocol messages. The uart_write() function inserts \r before \n, which can corrupt the binary ACK/data protocol.

QSPI transfer block error messages are now guarded by #ifdef DEBUG_QSPI to prevent them from leaking into the UART during the binary protocol phase.

Watchdog Timer Support

New WATCHDOG build option (follows the s32k1xx pattern):

  • Default (disabled): WDT disabled in hal_init(), restored to boot ROM defaults in hal_prepare_boot() before do_boot()
  • Enabled (-DWATCHDOG): WDT kept running with configurable timeout (WATCHDOG_TIMEOUT_MS, default 30s) — large enough to cover ECDSA P-384 verify (~5s) without needing per-operation refresh

Either way, hal_prepare_boot() restores the boot ROM WDT default so the application receives a normal watchdog.

Trap Handler Improvements

  • Trap handler now always prints and halts on synchronous exceptions (previously required DEBUG_BOOT, causing silent infinite mret loops without it)
  • With DEBUG_BOOT: prints SP value and detects stack overflow by comparing against _main_hart_stack_bottom linker symbol

Build Safety

  • STRIP_ELF=1: Makefile strips debug symbols before signing (149KB → 5KB for M-mode L2 Scratch fit)
  • Linker ASSERT: build fails if wolfBoot binary overlaps the image load address
  • Runtime overlap guard in wolfBoot_ramboot() checks image destination against _end
  • STACK_PAINTING diagnostic: paints stack with sentinel at boot, reports peak usage after verification
  • MCR RTS assertion in UART init for USB-UART bridge flow control

Config Changes (polarfire_mpfs250_m_qspi.config)

  • UART_QSPI_PROGRAM=1 (enabled by default for M-mode)
  • STRIP_ELF=1 (required for L2 Scratch fit)
  • STACK_SIZE_PER_HART=0 (secondary harts unused in M-mode)
  • WOLFBOOT_LOAD_ADDRESS=0x0A020200 (128KB reserved for wolfBoot growth)
  • DEBUG_BOOT commented out (production default)

@dgarske dgarske self-assigned this Apr 13, 2026
Copilot AI review requested due to automatic review settings April 13, 2026 21:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Fixes PolarFire SoC MPFS250 M-mode boot stability and robustness by correcting L2 scratchpad initialization, hardening the UART QSPI programmer path, and adding optional watchdog support with safer boot handoff.

Changes:

  • Fix L2 scratchpad copy on E51 by routing D-cache stores to scratchpad ways and adding appropriate fences.
  • Make UART QSPI programmer more reliable on USB-UART bridges and reduce protocol corruption risks by using direct UART output.
  • Add WATCHDOG build option plus build/runtime safety checks (linker ASSERT + RAM overlap guard) and documentation updates.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tools/scripts/mpfs_qspi_prog.py Throttles UART writes to avoid USB-UART bulk-write stalls.
src/update_ram.c Adds runtime guard to prevent RAM image load overlapping wolfBoot region.
src/boot_riscv_start.S Fixes MPFS250 L2 scratchpad initialization (D-cache way mask + fences).
src/boot_riscv.c Ensures synchronous traps always print and halt; adds optional stack overflow diagnostics.
hal/mpfs250.h Adds MPFS watchdog register definitions and a QSPI reset bit define.
hal/mpfs250.c Implements watchdog handling, QSPI programmer UART output changes, and RTS assertion.
hal/mpfs250-m.ld Reduces stack size and adds linker-time overlap ASSERT using WOLFBOOT_LOAD_ADDRESS.
docs/Targets.md Documents M-mode optional flags and stack overflow detection.
config/examples/polarfire_mpfs250_m_qspi.config Enables UART QSPI programmer by default; adds STRIP_ELF and WATCHDOG flag docs; adjusts load address/stack settings.
Makefile Adds optional ELF stripping before signing; wires WOLFBOOT_LOAD_ADDRESS into linker script templating.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread hal/mpfs250.c
Comment thread hal/mpfs250.c
Comment thread Makefile
Comment thread tools/scripts/mpfs_qspi_prog.py
Comment thread docs/Targets.md Outdated
Comment thread hal/mpfs250.c Outdated
@dgarske dgarske assigned danielinux and wolfSSL-Bot and unassigned dgarske Apr 14, 2026
@dgarske dgarske requested a review from danielinux April 14, 2026 16:29
@dgarske dgarske added the Later It won't be fixed in the upcoming release label Apr 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Later It won't be fixed in the upcoming release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants