@@ -797,9 +797,10 @@ The PolarFire SoC is a 64-bit RISC-V SoC featuring a five-core CPU cluster (1×
797797
798798### PolarFire SoC Files
799799
800- ` hal/mpfs250.c ` - Hardware abstraction layer implementation (UART and uSD )
800+ ` hal/mpfs250.c ` - Hardware abstraction layer (UART, QSPI, SD/eMMC, multi-hart )
801801` hal/mpfs250.h ` - Register definitions and hardware interfaces
802- ` hal/mpfs250.ld ` - Linker script for the platform
802+ ` hal/mpfs250.ld ` - Linker script for S-mode (HSS-based boot)
803+ ` hal/mpfs250-m.ld ` - Linker script for M-mode (eNVM + L2 SRAM)
803804` hal/mpfs.dts ` - Device tree source
804805` hal/mpfs.yaml ` - HSS payload generator configuration
805806` hal/mpfs250.its ` - Example FIT image creation template
@@ -1363,11 +1364,105 @@ ML-DSA 87 verify 200 ops took 1.077 sec, avg 5.385 ms, 185.704 ops/
13631364Benchmark complete
13641365```
13651366
1366- ### PolarFire TODO
1367+ ### PolarFire Machine Mode (M-Mode) Support
13671368
1368- * Add support for full HSS replacement using wolfboot
1369- - Machine level assembly startup
1370- - DDR driver
1369+ wolfBoot supports running directly in Machine Mode (M-mode) on PolarFire SoC,
1370+ replacing the Hart Software Services (HSS) as the first-stage bootloader. In
1371+ M-mode, wolfBoot runs on the E51 monitor core and loads a signed application
1372+ from SC QSPI flash to on-chip LIM (Loosely Integrated Memory).
1373+
1374+ #### M-Mode Features
1375+
1376+ * Runs on E51 monitor core (hart 0) directly from eNVM
1377+ * Executes from L2 Scratchpad SRAM (256KB at 0x0A000000)
1378+ * Loads signed application from SC QSPI flash to LIM (0x08000000)
1379+ * No HSS or DDR required — boots entirely from on-chip memory
1380+ * Wakes and manages secondary U54 harts via IPI
1381+ * Per-hart UART output (each hart uses its own MMUART)
1382+ * ECC384 + SHA384 signature verification
1383+
1384+ #### M-Mode Files
1385+
1386+ | File | Description |
1387+ |------|-------------|
1388+ | `config/examples/polarfire_mpfs250_m_qspi.config` | M-mode + SC QSPI configuration |
1389+ | `hal/mpfs250-m.ld` | M-mode linker script (eNVM + L2 SRAM) |
1390+ | `hal/mpfs250.c` | HAL with QSPI driver, UART, L2 cache init |
1391+ | `src/boot_riscv_start.S` | M-mode assembly startup |
1392+
1393+ #### Building for M-Mode
1394+
1395+ ```sh
1396+ # Copy M-mode QSPI configuration
1397+ cp config/examples/polarfire_mpfs250_m_qspi.config .config
1398+
1399+ # Build wolfBoot and signed test-app
1400+ make clean
1401+ make
1402+ ```
1403+
1404+ This produces:
1405+ - `wolfboot.elf` — bootloader for eNVM (~26KB)
1406+ - `test-app/image_v1_signed.bin` — signed application for QSPI flash
1407+
1408+ #### Flashing
1409+
1410+ M-mode requires programming two targets:
1411+
1412+ 1. **eNVM** (wolfBoot): Programmed via JTAG using mpfsBootmodeProgrammer (bootmode 1)
1413+ 2. **QSPI flash** (signed application): Programmed via Libero/FPExpress SPI programming
1414+
1415+ ```sh
1416+ # Set SoftConsole installation directory
1417+ export SC_INSTALL_DIR=/opt/Microchip/SoftConsole-v2022.2-RISC-V-747
1418+
1419+ # Flash wolfboot.elf to eNVM
1420+ $SC_INSTALL_DIR/eclipse/jre/bin/java -jar \
1421+ $SC_INSTALL_DIR/extras/mpfs/mpfsBootmodeProgrammer.jar \
1422+ --bootmode 1 --die MPFS250T --package FCG1152 --workdir $PWD wolfboot.elf
1423+
1424+ # Flash test-app/image_v1_signed.bin to QSPI at offset 0x20000
1425+ # (use Libero SoC Design Suite SPI flash programming)
1426+ ```
1427+
1428+ #### M-Mode Boot Flow
1429+
1430+ 1. **eNVM Reset Vector** (0x20220100): CPU starts, copies code to L2 SRAM
1431+ 2. **L2 SRAM Execution** (0x0A000000): wolfBoot runs from scratchpad
1432+ 3. **Hardware Init**: L2 cache configuration, UART setup
1433+ 4. **QSPI Init**: SC QSPI controller (0x37020100), JEDEC ID read, 4-byte address mode
1434+ 5. **Image Load**: Read signed image from QSPI flash (0x20000) to LIM (0x08000200)
1435+ 6. **Verify & Boot**: SHA384 integrity check, ECC384 signature verification, jump to app
1436+
1437+ #### M-Mode QSPI Partition Layout
1438+
1439+ The SC QSPI flash (Micron MT25QL01G, 128MB) is partitioned as:
1440+
1441+ | Region | Address | Size |
1442+ |--------|---------|------|
1443+ | Boot partition | 0x00020000 | ~32MB |
1444+ | Update partition | 0x02000000 | ~32MB |
1445+ | Swap partition | 0x04000000 | 64KB |
1446+
1447+ #### M-Mode UART Mapping
1448+
1449+ | Hart | Core | MMUART | USB Device |
1450+ |------|------|--------|------------|
1451+ | 0 | E51 | MMUART0 | /dev/ttyUSB0 |
1452+ | 1 | U54_1 | MMUART1 | /dev/ttyUSB1 |
1453+ | 2 | U54_2 | MMUART2 | N/A |
1454+ | 3 | U54_3 | MMUART3 | N/A |
1455+ | 4 | U54_4 | MMUART4 | N/A |
1456+
1457+ #### M-Mode Notes
1458+
1459+ * The E51 core is rv64imac (no FPU or crypto extensions). wolfBoot is compiled
1460+ with `NO_ASM=1` to use portable C crypto implementations and
1461+ `-march=rv64imac -mabi=lp64` for correct code generation.
1462+ * CLINT MTIME counter is not running in bare-metal M-mode (no HSS), so
1463+ `udelay()` uses a calibrated busy loop instead of the timer CSR.
1464+ * DDR initialization support is available on the `polarfire_ddr` branch for
1465+ use cases that require loading larger applications to DDR memory.
13711466
13721467
13731468## STM32F7
0 commit comments