Skip to content

Commit 8351b49

Browse files
committed
Add wolfBoot port for STM32N6 (NUCLEO-N657X0-Q)
Co-authored-by: Aidan Garske <aidan@wolfssl.com>
1 parent c3d255d commit 8351b49

18 files changed

Lines changed: 2496 additions & 11 deletions

File tree

.github/workflows/test-configs.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,18 @@ jobs:
456456
arch: arm
457457
config-file: ./config/examples/stm32h5-dualbank.config
458458

459+
stm32n6_test:
460+
uses: ./.github/workflows/test-build.yml
461+
with:
462+
arch: arm
463+
config-file: ./config/examples/stm32n6.config
464+
465+
stm32n6_tz_test:
466+
uses: ./.github/workflows/test-build.yml
467+
with:
468+
arch: arm
469+
config-file: ./config/examples/stm32n6-tz.config
470+
459471
stm32h5_tz_test:
460472
uses: ./.github/workflows/test-build.yml
461473
with:

Makefile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,11 @@ ifeq ($(TARGET),stm32h5)
242242
# Don't build a contiguous image
243243
MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin
244244
endif
245+
246+
ifeq ($(TARGET),stm32n6)
247+
# Don't build a contiguous image
248+
MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin
249+
endif
245250
endif # TZEN=1
246251

247252
ifeq ($(TARGET),x86_64_efi)
@@ -289,6 +294,11 @@ ifeq ($(TARGET),zynq7000)
289294
MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin
290295
endif
291296

297+
ifeq ($(TARGET),stm32n6)
298+
# wolfBoot runs from SRAM, app from XIP on external NOR - no contiguous factory.bin
299+
MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin
300+
endif
301+
292302
ifeq ($(TARGET),rp2350)
293303
MAIN_TARGET:=include/target.h keytools wolfboot_signing_private_key.der pico-sdk-info
294304
endif
@@ -684,6 +694,12 @@ stack-usage: wolfboot.bin
684694
image-header-size: wolfboot.bin
685695
$(Q)echo $(IMAGE_HEADER_SIZE) > .image_header_size
686696

697+
## Target-specific flash targets
698+
ifeq ($(TARGET),stm32n6)
699+
flash: wolfboot.bin test-app/image_v1_signed.bin
700+
$(Q)tools/scripts/stm32n6_flash.sh --skip-build
701+
endif
702+
687703

688704
cppcheck:
689705
cppcheck -f --enable=warning --enable=portability \

arch.mk

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,18 @@ ifeq ($(ARCH),ARM)
290290

291291
endif
292292

293+
ifeq ($(TARGET),stm32n6)
294+
CORTEX_M55=1
295+
CFLAGS+=-Ihal
296+
ARCH_FLASH_OFFSET=0x70000000
297+
# Boot ROM copies FSBL from NOR to AXISRAM2 at 0x34180400.
298+
# The signing -la flag in the flash script must match.
299+
WOLFBOOT_ORIGIN=0x34180400
300+
EXT_FLASH=1
301+
PART_UPDATE_EXT=1
302+
PART_SWAP_EXT=1
303+
endif
304+
293305
ifeq ($(TARGET),rp2350)
294306
CORTEX_M33=1
295307
CFLAGS+=-Ihal
@@ -442,12 +454,22 @@ else
442454
CORTEXM_ARM_EXTRA_CFLAGS+=-DWOLFSSL_ARMASM -DWOLFSSL_ARMASM_NO_HW_CRYPTO \
443455
-DWOLFSSL_ARMASM_NO_NEON -DWOLFSSL_ARMASM_THUMB2
444456
endif
457+
ifeq ($(CORTEX_M55),1)
458+
CORTEX_M33=1
459+
CFLAGS+=-mcpu=cortex-m55 -DCORTEX_M55
460+
LDFLAGS+=-mcpu=cortex-m55
461+
endif
445462
ifeq ($(CORTEX_M33),1)
446-
CFLAGS+=-mcpu=cortex-m33 -DCORTEX_M33
447-
LDFLAGS+=-mcpu=cortex-m33
463+
CFLAGS+=-DCORTEX_M33
464+
ifneq ($(CORTEX_M55),1)
465+
CFLAGS+=-mcpu=cortex-m33
466+
LDFLAGS+=-mcpu=cortex-m33
467+
endif
448468
ifeq ($(TZEN),1)
449469
ifneq (,$(findstring stm32,$(TARGET)))
450-
OBJS+=hal/stm32_tz.o
470+
ifneq ($(TARGET),stm32n6)
471+
OBJS+=hal/stm32_tz.o
472+
endif
451473
endif
452474
CFLAGS+=-mcmse
453475
SECURE_LDFLAGS+=-Wl,--cmse-implib -Wl,--out-implib=./src/wolfboot_tz_nsc.o

config/examples/stm32n6-tz.config

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
ARCH?=ARM
2+
TARGET?=stm32n6
3+
TZEN?=1
4+
SIGN?=ECC256
5+
HASH?=SHA256
6+
DEBUG?=0
7+
DEBUG_UART?=1
8+
VTOR?=1
9+
NO_ASM?=0
10+
NO_MPU=1
11+
SPI_FLASH?=0
12+
ALLOW_DOWNGRADE?=0
13+
NVM_FLASH_WRITEONCE?=0
14+
WOLFBOOT_VERSION?=1
15+
V?=0
16+
SPMATH?=1
17+
RAM_CODE?=1
18+
WOLFBOOT_SECTOR_SIZE?=0x1000
19+
WOLFBOOT_PARTITION_SIZE?=0x100000
20+
# Boot partition: secure alias (0x70180000). N6 IDAU appears hard-
21+
# wired Secure for the low 1 MB of XSPI2 (0x70000000..0x700FFFFF) and
22+
# deferring to SAU above 0x70100000 -- ST's Template_Isolation_XIP
23+
# reference puts its NS app at 0x70180000 for this reason. SAU REG[2]
24+
# classifies the boot partition window NS so the secure CPU's reads
25+
# (during verify) and the NS CPU's XIP fetches (post-BLXNS) both
26+
# succeed through the same address.
27+
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x70180000
28+
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x00280000
29+
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x00170000
30+
IMAGE_HEADER_SIZE?=1024
31+
# Boot partition is on the same XSPI2 NOR flash as update/swap.
32+
# PART_BOOT_EXT routes boot partition reads through ext_flash API (SPI
33+
# commands) instead of XIP, avoiding bus faults when XSPI2 toggles
34+
# between memory-mapped and command mode during firmware updates.
35+
CFLAGS_EXTRA+=-DPART_BOOT_EXT
36+
BOOTLOADER_PARTITION_SIZE=0x40000
37+
# NSC veneers: placed in the NS alias of the top 4 KB of wolfBoot's
38+
# 256 KB AXISRAM2 region. Physical bytes are shared with FLASH (same
39+
# SRAM); SAU promotes this NS view to NSC so secure-gateway stubs are
40+
# reachable via BLXNS from the NS app. WOLFCRYPT_TZ is off in this
41+
# config, so the section is empty -- but the linker requires a home.
42+
WOLFBOOT_NSC_ADDRESS?=0x2418F000
43+
WOLFBOOT_NSC_SIZE?=0x1000
44+
# Keyvault unused while WOLFCRYPT_TZ=0; reserve a small dummy region
45+
# so the H5-derived linker template substitutes cleanly.
46+
WOLFBOOT_KEYVAULT_ADDRESS?=0x2418E000
47+
WOLFBOOT_KEYVAULT_SIZE?=0x1000

config/examples/stm32n6.config

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
ARCH?=ARM
2+
TARGET?=stm32n6
3+
SIGN?=ECC256
4+
HASH?=SHA256
5+
DEBUG?=0
6+
DEBUG_UART?=1
7+
VTOR?=1
8+
NO_ASM?=0
9+
NO_MPU=1
10+
SPI_FLASH?=0
11+
ALLOW_DOWNGRADE?=0
12+
NVM_FLASH_WRITEONCE?=0
13+
WOLFBOOT_VERSION?=1
14+
V?=0
15+
SPMATH?=1
16+
RAM_CODE?=1
17+
WOLFBOOT_SECTOR_SIZE?=0x1000
18+
WOLFBOOT_PARTITION_SIZE?=0x100000
19+
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x70020000
20+
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x00120000
21+
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x00010000
22+
IMAGE_HEADER_SIZE?=1024
23+
# Boot partition is on the same XSPI2 NOR flash as update/swap.
24+
# PART_BOOT_EXT ensures boot partition reads go through ext_flash API
25+
# (SPI commands) instead of XIP, avoiding bus faults when XSPI2 toggles
26+
# between memory-mapped and command mode during firmware updates.
27+
CFLAGS_EXTRA+=-DPART_BOOT_EXT
28+
# Enable verbose fault handler so a hardfault prints registers via UART
29+
CFLAGS_EXTRA+=-DDEBUG_HARDFAULT
30+
BOOTLOADER_PARTITION_SIZE=0x40000

config/openocd/openocd_stm32n6.cfg

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# OpenOCD config for NUCLEO-N657X0-Q with MX25UM51245G NOR on XSPI2
2+
3+
source [find interface/stlink.cfg]
4+
transport select swd
5+
6+
set CHIPNAME stm32n6x
7+
set WORKAREASIZE 0x10000
8+
9+
source [find target/stm32n6x.cfg]
10+
11+
# Work-area above wolfBoot SRAM region
12+
$_TARGETNAME configure -work-area-phys 0x34020000 -work-area-size $WORKAREASIZE -work-area-backup 0
13+
14+
# XSPI2 NOR flash bank (memory-mapped at 0x70000000, regs at 0x5802A000)
15+
set XSPI2_BANK_ID [llength [flash list]]
16+
flash bank $CHIPNAME.xspi2 stmqspi 0x70000000 0 0 0 $CHIPNAME.cpu 0x5802A000
17+
18+
# Mark VDDIO supplies valid (required for XSPI2 GPIO)
19+
proc pwr_enable_io_supply {} {
20+
mmw 0x5602825C 0x00040000 0 ;# RCC_AHB4ENR: PWR clock
21+
mmw 0x56024834 0x00000100 0 ;# SVMCR1: VDDIO4SV
22+
mmw 0x56024838 0x00000100 0 ;# SVMCR2: VDDIO5SV
23+
mmw 0x5602483C 0x00000300 0 ;# SVMCR3: VDDIO2SV + VDDIO3SV
24+
}
25+
26+
# Port N GPIO for XSPI2 (PN0-PN11, AF9, very high speed)
27+
proc xspi2_gpio_init {} {
28+
mmw 0x5602825C 0x00002000 0 ;# RCC_AHB4ENR: GPION clock
29+
sleep 1
30+
mmw 0x56023400 0x00AAAAAA 0x00555555 ;# MODER: AF mode
31+
mmw 0x56023408 0x00FFFFFF 0 ;# OSPEEDR: very high
32+
mmw 0x5602340C 0 0x00FFFFFF ;# PUPDR: no pull
33+
mww 0x56023420 0x99999999 ;# AFRL: AF9
34+
mww 0x56023424 0x00009999 ;# AFRH: AF9
35+
}
36+
37+
# XSPI2 init: single-SPI, /16 prescaler, NOR reset, enter mmap mode
38+
proc xspi2_init {} {
39+
mmw 0x56028260 0x00003000 0 ;# RCC_AHB5ENR: XSPI2 + XSPIM clocks
40+
mmw 0x56028248 0x00000008 0 ;# RCC_MISCENR: XSPI PHY comp clock
41+
sleep 1
42+
43+
mww 0x5802A000 0x00000000 ;# CR: disable
44+
sleep 1
45+
mww 0x5802A008 0x001A0308 ;# DCR1: DLYBYP, DEVSIZE=26, CSHT=3
46+
mww 0x5802A00C 0x0000000F ;# DCR2: prescaler /16
47+
sleep 1
48+
mww 0x5802A000 0x00000001 ;# CR: enable
49+
50+
# NOR flash software reset (0x66 + 0x99)
51+
mmw 0x5802A000 0x00000002 0 ;# abort
52+
sleep 1
53+
mww 0x5802A024 0x0000000B ;# FCR: clear flags
54+
mww 0x5802A100 0x00000001 ;# CCR: IMODE=single
55+
mww 0x5802A108 0x00000000 ;# TCR: no dummy
56+
mww 0x5802A110 0x00000066 ;# IR: Reset Enable
57+
sleep 1
58+
59+
mmw 0x5802A000 0x00000002 0 ;# abort
60+
sleep 1
61+
mww 0x5802A024 0x0000000B
62+
mww 0x5802A100 0x00000001
63+
mww 0x5802A108 0x00000000
64+
mww 0x5802A110 0x00000099 ;# IR: Reset Memory
65+
sleep 10
66+
67+
xspi2_mem_mapped
68+
}
69+
70+
# Memory-mapped fast-read mode (single-SPI, 4-byte addr, 8 dummy cycles)
71+
proc xspi2_mem_mapped {} {
72+
mmw 0x5802A000 0x00000002 0 ;# abort
73+
sleep 1
74+
mww 0x5802A000 0x30000001 ;# CR: mmap + enable
75+
mww 0x5802A100 0x01003101 ;# CCR: IMODE=1, ADMODE=1, ADSIZE=3, DMODE=1
76+
mww 0x5802A108 0x40000008 ;# TCR: DCYC=8, SSHIFT
77+
mww 0x5802A110 0x0000000C ;# IR: Fast Read 4B
78+
}
79+
80+
# Set NOR flash params manually (SFDP not readable in single-SPI mode)
81+
proc xspi2_flash_set {} {
82+
global XSPI2_BANK_ID
83+
stmqspi set $XSPI2_BANK_ID MX25UM51245G 0x4000000 0x100 0x13 0 0x12 0x60 0x1000 0x21
84+
}
85+
86+
# Full reinit for use when XSPI2 may already be configured
87+
proc xspi2_reinit {} {
88+
global XSPI2_BANK_ID
89+
pwr_enable_io_supply
90+
xspi2_gpio_init
91+
xspi2_init
92+
xspi2_flash_set
93+
flash probe $XSPI2_BANK_ID
94+
xspi2_flash_set
95+
}
96+
97+
$_TARGETNAME configure -event reset-init {
98+
global XSPI2_BANK_ID
99+
pwr_enable_io_supply
100+
xspi2_gpio_init
101+
xspi2_init
102+
xspi2_flash_set
103+
flash probe $XSPI2_BANK_ID
104+
# Re-set after probe (stmqspi driver quirk)
105+
xspi2_flash_set
106+
}
107+
108+
init

0 commit comments

Comments
 (0)