Skip to content

Commit 5d71feb

Browse files
dgarskedanielinux
authored andcommitted
PolarFire SoC M-Mode: Fix L2 scratchpad init, QSPI programmer, and add WDT support
1 parent bc454d9 commit 5d71feb

10 files changed

Lines changed: 229 additions & 60 deletions

File tree

Makefile

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,11 +455,20 @@ test-app/image_v1_signed.bin: $(BOOT_IMG) keytools_check
455455
@echo "\t[SIGN] $(BOOT_IMG)"
456456
@echo "\tSECONDARY_SIGN_OPTIONS=$(SECONDARY_SIGN_OPTIONS)"
457457
@echo "\tSECONDARY_PRIVATE_KEY=$(SECONDARY_PRIVATE_KEY)"
458-
458+
ifeq ($(STRIP_ELF),1)
459+
@echo "\t[STRIP] $(BOOT_IMG)"
460+
$(Q)$(OBJCOPY) --strip-debug $(BOOT_IMG) $(BOOT_IMG).stripped
461+
$(Q)(test $(SIGN) = NONE) || $(SIGN_ENV) $(SIGN_TOOL) $(SIGN_OPTIONS) \
462+
$(SECONDARY_SIGN_OPTIONS) $(BOOT_IMG).stripped $(PRIVATE_KEY) \
463+
$(SECONDARY_PRIVATE_KEY) 1 || true
464+
$(Q)(test $(SIGN) = NONE) && $(SIGN_ENV) $(SIGN_TOOL) $(SIGN_OPTIONS) $(BOOT_IMG).stripped 1 || true
465+
$(Q)mv test-app/image.elf_v1_signed.bin test-app/image_v1_signed.bin
466+
else
459467
$(Q)(test $(SIGN) = NONE) || $(SIGN_ENV) $(SIGN_TOOL) $(SIGN_OPTIONS) \
460468
$(SECONDARY_SIGN_OPTIONS) $(BOOT_IMG) $(PRIVATE_KEY) \
461469
$(SECONDARY_PRIVATE_KEY) 1 || true
462470
$(Q)(test $(SIGN) = NONE) && $(SIGN_ENV) $(SIGN_TOOL) $(SIGN_OPTIONS) $(BOOT_IMG) 1 || true
471+
endif
463472

464473
test-app/image.elf: wolfboot.elf
465474
$(Q)$(MAKE) -C test-app WOLFBOOT_ROOT="$(WOLFBOOT_ROOT)" ELF_FLASH_SCATTER="$(ELF_FLASH_SCATTER)" image.elf
@@ -541,6 +550,7 @@ $(LSCRIPT): $(LSCRIPT_IN) FORCE
541550
sed -e "s/@WOLFBOOT_LOAD_BASE@/$(WOLFBOOT_LOAD_BASE)/g" | \
542551
sed -e "s/@BOOTLOADER_START@/$(BOOTLOADER_START)/g" | \
543552
sed -e "s/@IMAGE_HEADER_SIZE@/$(IMAGE_HEADER_SIZE)/g" | \
553+
sed -e "s/@WOLFBOOT_LOAD_ADDRESS@/$(WOLFBOOT_LOAD_ADDRESS)/g" | \
544554
sed -e "s/@FSP_S_LOAD_BASE@/$(FSP_S_LOAD_BASE)/g" | \
545555
sed -e "s/@WOLFBOOT_L2LIM_SIZE@/$(WOLFBOOT_L2LIM_SIZE)/g" | \
546556
sed -e "s/@L2SRAM_ADDR@/$(L2SRAM_ADDR)/g" \

config/examples/polarfire_mpfs250_m_qspi.config

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,29 @@ WOLFTPM?=0
3838
ELF?=1
3939
#DEBUG_ELF?=1
4040

41+
# Strip debug symbols from test-app ELF before signing.
42+
# Required for M-mode: unstripped ELF (~150KB) is too large for L2 Scratch.
43+
# Stripped ELF is typically ~5KB.
44+
STRIP_ELF?=1
45+
46+
# Watchdog timer configuration (default: disabled)
47+
# When commented out, the WDT is disabled in hal_init() and re-enabled
48+
# with the boot ROM default in hal_prepare_boot() before do_boot.
49+
# Uncomment -DWATCHDOG to keep the WDT enabled with a generous timeout
50+
# for the duration of wolfBoot. Verify is bounded at ~5s; default 30s
51+
# avoids the need to pet the WDT during long ECDSA verify.
52+
#CFLAGS_EXTRA+=-DWATCHDOG
53+
#CFLAGS_EXTRA+=-DWATCHDOG_TIMEOUT_MS=30000
54+
4155
OPTIMIZATION_LEVEL=1
4256

4357
# M-Mode Configuration
4458
# Runs on E51 core in Machine Mode from L2 SRAM
4559
RISCV_MMODE?=1
4660

47-
# Stack size per hart (reduced for L2 SRAM constraints)
48-
CFLAGS_EXTRA+=-DSTACK_SIZE_PER_HART=8192
61+
# Stack size per hart: set to 0 for M-mode (only E51/hart 0 runs;
62+
# secondary harts park in eNVM WFI loop and never use L2 Scratch stacks)
63+
CFLAGS_EXTRA+=-DSTACK_SIZE_PER_HART=0
4964

5065
# E51 core lacks RISC-V crypto extensions (Zknh), use portable C implementations
5166
NO_ASM?=1
@@ -57,7 +72,7 @@ SPI_FLASH?=0
5772

5873
# SPI Flash Controller Selection:
5974
# MPFS_SC_SPI: Use SC QSPI Controller (0x37020100) for fabric-connected flash.
60-
# Direct register access to System Controller's QSPI instance.
75+
# Required for Video Kit (flash is fabric-connected, not on MSS pins).
6176
# DEFAULT: Use MSS QSPI Controller (0x21000000) for external flash
6277
# on MSS QSPI pins.
6378
CFLAGS_EXTRA+=-DMPFS_SC_SPI
@@ -71,12 +86,12 @@ DISK_EMMC?=0
7186
WOLFBOOT_ORIGIN?=0x0A000000
7287

7388
# Load application to L2 Scratchpad (above wolfBoot code, below stack)
74-
# wolfBoot occupies ~40KB at 0x0A000000, stack is 64KB at top of 256KB.
89+
# wolfBoot is ~36KB; 128KB reserved for growth headroom.
7590
# Note: update_ram places header at (LOAD_ADDRESS - IMAGE_HEADER_SIZE),
7691
# so offset by header size to keep header aligned.
7792
# IMPORTANT: Strip debug symbols from test-app ELF before signing to keep
78-
# the image small enough to fit in L2 Scratchpad (~150KB available).
79-
WOLFBOOT_LOAD_ADDRESS?=0x0A010200
93+
# the image small enough to fit in L2 Scratchpad (~95KB available).
94+
WOLFBOOT_LOAD_ADDRESS?=0x0A020200
8095

8196
# Flash geometry (64 KB sector to match QSPI flash)
8297
WOLFBOOT_SECTOR_SIZE?=0x10000
@@ -104,9 +119,11 @@ CFLAGS_EXTRA+=-DWOLFBOOT_SHA_BLOCK_SIZE=4096
104119
# Uncomment to run test during hal_init()
105120
#CFLAGS_EXTRA+=-DTEST_EXT_FLASH
106121

107-
# UART QSPI programmer (disabled by default)
108-
# When enabled, wolfBoot prompts on UART at startup to receive a signed firmware
109-
# image and write it to QSPI flash -- no Libero/JTAG tool required for updates.
122+
# UART QSPI programmer (enabled for M-mode)
123+
# In M-mode, QSPI flash is not accessible via Libero/JTAG, so this UART-based
124+
# programmer is the primary method to load the test-app image into QSPI.
125+
# wolfBoot prompts on UART at startup ("Press P within 3s") to receive a signed
126+
# firmware image and write it to QSPI flash.
110127
# Use: python3 tools/scripts/mpfs_qspi_prog.py <port> <image.bin> [qspi_offset]
111128
# Requires EXT_FLASH=1 (already set) and DEBUG_UART=1.
112-
UART_QSPI_PROGRAM?=0
129+
UART_QSPI_PROGRAM?=1

docs/Targets.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,28 @@ Key build settings that differ between configurations:
828828
> **Note:** All configurations require `NO_ASM=1` because the MPFS250 U54/E51 cores lack RISC-V
829829
> crypto extensions (Zknh); wolfBoot uses portable C implementations for all cryptographic operations.
830830
831+
### M-Mode Optional Build Flags
832+
833+
These flags apply to `polarfire_mpfs250_m_qspi.config` and are added via `CFLAGS_EXTRA+=-D...`.
834+
835+
| Flag | Default | Description |
836+
|------|---------|-------------|
837+
| `WATCHDOG` | undefined (disabled) | When defined, the E51 watchdog timer is **kept enabled** during wolfBoot operation with a generous timeout. When undefined, the WDT is **disabled** in `hal_init()` and re-enabled with the boot ROM default in `hal_prepare_boot()` before jumping to the application. Either way, the application receives a normal WDT. |
838+
| `WATCHDOG_TIMEOUT_MS` | `30000` (30 s) | Watchdog timeout in milliseconds when `WATCHDOG` is defined. ECDSA P-384 verification on E51 with portable C math is bounded at ~5 s; the default 30 s avoids any need to refresh the WDT during the long verify call. |
839+
840+
#### Stack overflow detection
841+
842+
The trap handler in `src/boot_riscv.c` automatically detects stack overflow on synchronous exceptions. When a trap fires with `SP < _main_hart_stack_bottom`, it prints:
843+
844+
```
845+
TRAP: cause=2 epc=A000740 tval=0 sp=A02FFE8
846+
STACK OVERFLOW: sp=A02FFE8 < bottom=A030000 (under by 24)
847+
```
848+
849+
This is helpful for diagnosing illegal-instruction TRAPs at random valid `.text` addresses, which are the classic signature of stack overflow corrupting the return address.
850+
851+
The current `STACK_SIZE` in `hal/mpfs250-m.ld` is **32 KB**. Measured peak for ECC384 + SHA384 + SPMATHALL + NO_ASM is ~6 KB (5x headroom).
852+
831853
### PolarFire SoC Files
832854

833855
`hal/mpfs250.c` - Hardware abstraction layer (UART, QSPI, SD/eMMC, multi-hart)

hal/mpfs250-m.ld

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ MEMORY
3333
}
3434

3535
/* Stack size for the boot hart (E51 in M-mode)
36-
* ECC384 signature verification with sp_int needs significant stack
37-
* for big number temporaries and point multiplication */
38-
PROVIDE(STACK_SIZE = 64k);
36+
* ECC384 + SHA384 + SPMATHALL + NO_ASM measured peak: ~6KB.
37+
* 32KB provides 5x headroom. */
38+
PROVIDE(STACK_SIZE = 32k);
3939

4040
SECTIONS
4141
{
@@ -115,9 +115,9 @@ PROVIDE(_start_heap = _end);
115115
*
116116
* Stack sizes (defined in config or header):
117117
* STACK_SIZE_PER_HART = 8192 (8KB per hart)
118-
* STACK_SIZE = 64K (64KB for main hart E51)
118+
* STACK_SIZE = 32K (32KB for main hart E51)
119119
*
120-
* Total stack area: STACK_SIZE + 4 * STACK_SIZE_PER_HART = 48KB
120+
* Total stack area: STACK_SIZE + 4 * STACK_SIZE_PER_HART
121121
*/
122122
PROVIDE(STACK_SIZE_PER_HART = 8192);
123123

@@ -144,3 +144,8 @@ PROVIDE(__global_pointer$ = _global_pointer);
144144

145145
/* Size of text section to copy (for startup code) */
146146
PROVIDE(_text_size = _end_text - _start_text_sram);
147+
148+
/* Build-time safety: ensure wolfBoot binary does not overlap image load area.
149+
* Image header is loaded at (WOLFBOOT_LOAD_ADDRESS - IMAGE_HEADER_SIZE). */
150+
ASSERT(_end <= @WOLFBOOT_LOAD_ADDRESS@ - @IMAGE_HEADER_SIZE@,
151+
"ERROR: wolfBoot binary overlaps image load area! Increase WOLFBOOT_LOAD_ADDRESS")

0 commit comments

Comments
 (0)