Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/test-configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,21 @@ jobs:
with:
arch: riscv64
config-file: ./config/examples/polarfire_mpfs250_qspi.config
# M-mode + LPDDR4 build: point LIBERO_FPGA_CONFIG_DIR at the in-tree
# CI stub so MPFS_DDR_INIT actually compiles in CI (the upstream config
# leaves the var empty so real boards must override it explicitly).
microchip_mpfs250_m_test:
uses: ./.github/workflows/test-build-riscv.yml
with:
arch: riscv64
config-file: ./config/examples/polarfire_mpfs250_m.config
Comment thread
dgarske marked this conversation as resolved.
make-args: LIBERO_FPGA_CONFIG_DIR=tools/ci/mpfs_libero_stub
microchip_mpfs250_m_qspi_test:
uses: ./.github/workflows/test-build-riscv.yml
with:
arch: riscv64
config-file: ./config/examples/polarfire_mpfs250_m_qspi.config
make-args: LIBERO_FPGA_CONFIG_DIR=tools/ci/mpfs_libero_stub

raspi3_test:
uses: ./.github/workflows/test-build.yml
Expand Down
6 changes: 6 additions & 0 deletions arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,12 @@ ifeq ($(ARCH),RISCV64)
CFLAGS+=-DWOLFBOOT_RISCV_MMODE -DWOLFBOOT_DUALBOOT
# Use M-mode specific linker script
LSCRIPT_IN:=hal/$(TARGET)-m.ld
# MPFS DDR init pulls LIBERO_SETTING_* values from a Libero/HSS-generated
# fpga_design_config.h. Setting LIBERO_FPGA_CONFIG_DIR enables DDR init
# and adds the directory to the include search path.
ifneq ($(LIBERO_FPGA_CONFIG_DIR),)
CFLAGS+=-DMPFS_DDR_INIT -I$(LIBERO_FPGA_CONFIG_DIR)
endif
else
# Supervisor Mode: Running under HSS
CFLAGS+=-DWOLFBOOT_DUALBOOT
Expand Down
164 changes: 164 additions & 0 deletions config/examples/polarfire_mpfs250_m.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# PolarFire SoC MPFS250T M-Mode (Machine Mode) with LPDDR4 + SD card
#
# Standalone wolfBoot replacing HSS:
# 1. eNVM (0x20220100) -> L2_SCRATCH (0x0A000000) - wolfBoot starts
# 2. M-mode init: PLLs, DDR controller, LPDDR4 training (Video Kit)
# 3. Load signed Linux kernel/DTB from SD card to DDR (0x8E000000 / 0x8A000000)
# 4. Verify ECC384/SHA384 signature
# 5. Drop to S-mode and jump to kernel
#
# Flash via mpfsBootmodeProgrammer (bootmode 1):
# java -jar mpfsBootmodeProgrammer.jar --bootmode 1 --die MPFS250T \
# --package FCG1152 --workdir $PWD wolfboot.elf

ARCH?=RISCV64
TARGET?=mpfs250
SIGN?=ECC384
HASH?=SHA384
IMAGE_HEADER_SIZE=512
WOLFBOOT_VERSION?=1
ARMORED?=0
DEBUG?=0
DEBUG_SYMBOLS?=1
DEBUG_UART?=1
VTOR?=1
EXT_FLASH?=0
SPI_FLASH?=0
NO_XIP?=1
NVM_FLASH_WRITEONCE?=0
UART_FLASH?=0
V?=0
NO_MPU?=1
RAM_CODE?=0
SPMATH?=0
SPMATHALL?=1
DUALBANK_SWAP?=0
PKA?=0
ENCRYPT=0
WOLFTPM?=0
ELF?=1
#DEBUG_ELF?=1

OPTIMIZATION_LEVEL=1

# M-Mode configuration: runs on E51 from L2 SRAM
RISCV_MMODE?=1

# Stack size per hart (L2 SRAM constraints)
CFLAGS_EXTRA+=-DSTACK_SIZE_PER_HART=8192

# E51 core lacks RISC-V crypto extensions (Zknh), use portable C
NO_ASM?=1

# Enable LPDDR4 init in hal_init() by pointing at the Libero/HSS-generated
# fpga_design_config directory for this board. The directory must contain
# fpga_design_config.h and its sub-headers (memory_map/, ddr/, clocks/, ...).
# Typical sources:
# - HSS Video Kit build:
# <hss>/build/boards/mpfs-video-kit/fpga_design_config
# - Libero MSS Configurator export for the design.
# The -I path is added and -DMPFS_DDR_INIT is set automatically when this is
# non-empty (see arch.mk). Override on the command line for one-off builds:
# make LIBERO_FPGA_CONFIG_DIR=/path/to/fpga_design_config
LIBERO_FPGA_CONFIG_DIR?=

# Boot Linux: drop to S-mode after wolfBoot verifies kernel
CFLAGS_EXTRA+=-DWOLFBOOT_MMODE_SMODE_BOOT

# SD card storage for kernel image (no QSPI flash)
DISK_SDCARD?=1
DISK_EMMC?=0

# wolfBoot in L2 SRAM (256KB available)
WOLFBOOT_ORIGIN?=0x0A000000

# 4KB sector size (SD card flow is partition-based, not flash-erase-based)
WOLFBOOT_SECTOR_SIZE?=0x1000

# Scratch address where the signed FIT image is staged before signature
# verification + FIT parse. Placed early in DDR (32 MB into 2 GB) so we
# stay within the fully-trained region near 0x80000000 - the LPDDR4 TIP
# completes BCLK_SCLK only (train_stat=0x1) on this Video Kit and higher
# DDR addresses (e.g. 0x8E000000) have shown intermittent write
# corruption during long disk loads.
# After the FIT is parsed:
# kernel is copied to 0x80200000 (FIT-internal "load")
# DTB is copied to WOLFBOOT_LOAD_DTS_ADDRESS (0x8A000000)
# Layout:
# 0x80200000 - 0x814FFFFF : kernel (~19 MB after parse)
# 0x82000000 - 0x832FFFFF : FIT scratch (~19 MB - overwritten on next boot)
# 0x8A000000 - 0x8A004FFF : DTB
WOLFBOOT_LOAD_ADDRESS?=0x82000000

# DTB load address in DDR
WOLFBOOT_LOAD_DTS_ADDRESS?=0x8A000000

# Use update_disk loader (partition A/B numbering instead of flash addresses).
# BOOT_PART_A / BOOT_PART_B are 0-indexed GPT entry numbers. GPT partitions
# in our SD card layout (see tools/scripts/program-sdcard.sh):
# index 0 (parted "boot" 1 MiB - 33 MiB) -> active boot FIT
# index 1 (parted "update" 33 MiB - 65 MiB) -> inactive/update slot
# index 2 (parted "rootfs" 65 MiB - end) -> Linux rootfs
WOLFBOOT_NO_PARTITIONS=1
CFLAGS_EXTRA+=-DBOOT_PART_A=0
CFLAGS_EXTRA+=-DBOOT_PART_B=1

# Speed up disk partition read (512KB chunks - max DMA size)
CFLAGS_EXTRA+=-DDISK_BLOCK_SIZE=0x80000

# Disable SDMA on the Cadence SD4HC. SDMA hangs silently at first
# multi-block read on the Video Kit (Cadence boundary-cross bug).
# Use PIO single-block reads instead.
CFLAGS_EXTRA+=-DSDHCI_SDMA_DISABLED

# Force single-block (CMD17) reads. Multi-block PIO suffers a BRR
# race on Arasan/Cadence-family controllers; single-block avoids it.
CFLAGS_EXTRA+=-DSDHCI_FORCE_SINGLE_BLOCK_READ

# MPFS250 Video Kit cache-pressure workaround: sustained PIO writes to
# cached DDR thrash L2 cache enough to corrupt L2 Scratch (where the
# M-mode stack lives) and cause a cause=2 epc=0 trap during the post-
# block CMD13 wait. OR the destination address with this alias mask so
# PIO writes hit the non-cached DDR window (0x82000000 -> 0xC2000000)
# and bypass L2 entirely. Upper layers still read the buffer at the
# cached address; L2 misses and fetches the data back from DDR.
CFLAGS_EXTRA+=-DSDHCI_PIO_WRITE_NONCACHED_ALIAS=0x40000000UL

# Video Kit routes the SD slot's Card Detect (CD#) signal through the FPGA
# fabric rather than MSSIO, so the SDHCI controller's hardware CI/CDPL
# detection always reads 'no card' in M-mode (no fabric configuration).
# Force the SD bring-up code to assume a card is present.
CFLAGS_EXTRA+=-DSDHCI_FORCE_CARD_DETECT

# Optional encryption (kernel signed+encrypted with AES-256)
#CUSTOM_ENCRYPT_KEY=1
#ENCRYPT=1
#ENCRYPT_WITH_AES256=1
#OBJS_EXTRA=src/my_custom_encrypt_key.o

# Used by test-application/ELF wrapper
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x80200000
WOLFBOOT_PARTITION_SIZE=0x4000000

# Debug options (useful for initial M-mode + DDR bring-up)
CFLAGS_EXTRA+=-DDEBUG_BOOT
#CFLAGS_EXTRA+=-DDEBUG_SDHCI
#CFLAGS_EXTRA+=-DDEBUG_DISK
#CFLAGS_EXTRA+=-DDISK_TEST
# DDR pattern test (256 KB triple-write at cached 0x82000000) is
# DISABLED once disk-load works. Its CPU writes thrash L2 cache
# enough to corrupt L2 Scratch (where the M-mode stack lives) on the
# return from mpfs_ddr_init(). Now that mpfs_clear_bootup_cache_ways
# does PDMA pre-fill via the non-cached path, the pattern test is
# redundant -- the MTC 256 B sanity inside the retry loop already
# verifies DDR works end-to-end before pre-fill runs.
#CFLAGS_EXTRA+=-DMPFS_DDR_PATTERN_TEST
# Verbose register-level DDR tracing. KEEP ENABLED until the timing
# sensitivity in run_training is fixed -- the DBG_DDR printf delays
# during the post-ZQ-cal phase appear to be required for TIP to
# reach train_stat=0x1D consistently. Removing -DDEBUG_DDR causes
# train_stat to stick at 0x1.
CFLAGS_EXTRA+=-DDEBUG_DDR
# Phase 3.9 ruled out: kicking PHY_TRAINING_START=1 does not advance
# TIP past BCLK_SCLK. Macro left for posterity, off by default.
#CFLAGS_EXTRA+=-DMPFS_DDR_KICK_TRAINING_START
52 changes: 39 additions & 13 deletions docs/Targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ The PolarFire SoC is a 64-bit RISC-V SoC featuring a five-core CPU cluster (1×

### Supported Boot Configurations

Five ready-to-use config templates cover all supported boot mode / storage / memory combinations:
Six ready-to-use config templates cover all supported boot mode / storage / memory combinations:

| Configuration | Config File | Boot Mode | Storage | Memory | HSS |
|---------------|-------------|-----------|---------|--------|-----|
Expand All @@ -811,21 +811,47 @@ Five ready-to-use config templates cover all supported boot mode / storage / mem
| **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 |
| **M-Mode + DDR** | `polarfire_mpfs250_m.config` | M-mode (E51, no HSS) | SD Card | LPDDR4 (DDR) | No |

The **M-Mode + DDR** configuration brings up the LPDDR4 controller from
the E51 in M-mode (no HSS), then loads a signed FIT image from SD card
and hands off to a U54 hart in S-mode for Linux. Because all
LIBERO_SETTING_\* values are board-specific, this build pulls them from
a Libero/HSS-generated `fpga_design_config.h` pointed at by the
`LIBERO_FPGA_CONFIG_DIR` makefile variable - typical sources are an
HSS Video Kit build at
`<hss>/build/boards/mpfs-video-kit/fpga_design_config` or a Libero MSS
Configurator export. Setting `LIBERO_FPGA_CONFIG_DIR` automatically
defines `MPFS_DDR_INIT` and adds the directory to the include path
(see `arch.mk`); when unset, the DDR HAL is excluded and the build
still produces a working M-mode wolfBoot without DDR. Add
`-DDEBUG_DDR` to `CFLAGS_EXTRA` for verbose register-level traces
during bring-up.

A compile-only stub `tools/ci/mpfs_libero_stub/fpga_design_config.h`
exists for GitHub Actions: every `LIBERO_SETTING_*` symbol referenced
by the HAL is defined to `0` so the M-Mode + DDR build path stays
under continuous integration. The stub is **not** runnable - real
boards must point `LIBERO_FPGA_CONFIG_DIR` at the actual Libero / HSS
output.

Key build settings that differ between configurations:

| Setting | SDCard | eMMC | QSPI | L2-LIM | M-Mode |
|---------|--------|------|------|--------|--------|
| `WOLFBOOT_ORIGIN` | `0x80000000` | `0x80000000` | `0x80000000` | `0x08040000` | `0x0A000000` |
| `WOLFBOOT_LOAD_ADDRESS` | `0x8E000000` | `0x8E000000` | `0x8E000000` | `0x08060000` | `0x0A010200` |
| `EXT_FLASH` | 0 | 0 | 1 | 1 | 1 |
| `DISK_SDCARD` | 1 | 0 | 0 | 0 | 0 |
| `DISK_EMMC` | 0 | 1 | 0 | 0 | 0 |
| `MPFS_L2LIM` | – | – | – | 1 | – |
| `RISCV_MMODE` | – | – | – | – | 1 |
| Linker script | `mpfs250.ld` | `mpfs250.ld` | `mpfs250.ld` | `mpfs250-hss.ld` | `mpfs250-m.ld` |
| HSS YAML | `mpfs.yaml` | `mpfs.yaml` | `mpfs.yaml` | `mpfs-l2lim.yaml` | N/A |
| `ELF` output | 1 | 1 | 1 | 0 (raw .bin) | 1 |
| Setting | SDCard | eMMC | QSPI | L2-LIM | M-Mode | M-Mode + DDR |
|---------|--------|------|------|--------|--------|--------------|
| `WOLFBOOT_ORIGIN` | `0x80000000` | `0x80000000` | `0x80000000` | `0x08040000` | `0x0A000000` | `0x0A000000` |
| `WOLFBOOT_LOAD_ADDRESS` | `0x8E000000` | `0x8E000000` | `0x8E000000` | `0x08060000` | `0x0A010200` | `0x82000000` |
| `WOLFBOOT_LOAD_DTS_ADDRESS` | `0x8A000000` | `0x8A000000` | `0x8A000000` | – | – | `0x8A000000` |
| `EXT_FLASH` | 0 | 0 | 1 | 1 | 1 | 0 |
| `DISK_SDCARD` | 1 | 0 | 0 | 0 | 0 | 1 |
| `DISK_EMMC` | 0 | 1 | 0 | 0 | 0 | 0 |
| `MPFS_L2LIM` | – | – | – | 1 | – | – |
| `RISCV_MMODE` | – | – | – | – | 1 | 1 |
| `LIBERO_FPGA_CONFIG_DIR` | – | – | – | – | – | required |
| `WOLFBOOT_MMODE_SMODE_BOOT` | – | – | – | – | – | 1 |
| Linker script | `mpfs250.ld` | `mpfs250.ld` | `mpfs250.ld` | `mpfs250-hss.ld` | `mpfs250-m.ld` | `mpfs250-m.ld` |
| HSS YAML | `mpfs.yaml` | `mpfs.yaml` | `mpfs.yaml` | `mpfs-l2lim.yaml` | N/A | N/A |
| `ELF` output | 1 | 1 | 1 | 0 (raw .bin) | 1 | 1 |

> **Note:** All configurations require `NO_ASM=1` because the MPFS250 U54/E51 cores lack RISC-V
> crypto extensions (Zknh); wolfBoot uses portable C implementations for all cryptographic operations.
Expand Down
Loading
Loading