@@ -1839,24 +1839,35 @@ XSPI2 NOR Flash (memory-mapped at 0x70000000):
18391839 0x70020000 Boot partition (1MB, app runs from here via XIP)
18401840 0x70120000 Update partition (1MB, device-relative: 0x00120000)
18411841
1842- AXISRAM (0x34000000 ):
1842+ AXISRAM — without TrustZone (non-secure alias ):
18431843 0x34000000 wolfBoot (loaded to SRAM via SWD or Boot ROM FSBL copy)
18441844 0x34020000 Stack / work area
1845+
1846+ AXISRAM — with TrustZone (TZEN=1, secure alias):
1847+ 0x24000000 wolfBoot (secure SRAM — IDAU marks 0x24xxxxxx as secure)
1848+ 0x24020000 Stack / work area (secure)
1849+ 0x34000000 Application SRAM (SAU region: non-secure)
18451850```
18461851
18471852### Build and Flash
18481853
18491854Use the example configuration and build:
18501855
18511856```sh
1857+ # Without TrustZone:
18521858cp config/examples/stm32n6.config .config
18531859make
18541860make flash
1861+
1862+ # With TrustZone:
1863+ cp config/examples/stm32n6-tz.config .config
1864+ make
1865+ make flash
18551866```
18561867
18571868` make flash ` uses OpenOCD with the stmqspi driver to:
185818691 . Program the signed application to NOR flash at 0x70020000
1859- 2 . Load wolfBoot to SRAM at 0x34000000
1870+ 2 . Load wolfBoot to SRAM (0x24000000 for TZEN=1, 0x34000000 otherwise)
186018713 . Start wolfBoot, which verifies and boots the application via XIP
18611872
18621873Prerequisites:
@@ -1872,11 +1883,66 @@ make TARGET=stm32n6 SIGN=ECC256
18721883
18731884The example config uses:
18741885- ` EXT_FLASH=1 ` with ` PART_UPDATE_EXT=1 ` and ` PART_SWAP_EXT=1 `
1875- - Boot partition at 0x70020000 (XIP, not marked EXT)
1886+ - ` PART_BOOT_EXT ` — boot partition reads use ext_flash API during updates
1887+ (required because boot and update share the same XSPI2 NOR flash)
1888+ - ` RAM_CODE=1 ` — flash functions placed in ` .ramcode ` for XIP safety
1889+ - ` DEBUG_UART=1 ` — USART1 output for boot messages and test-app
1890+ - Boot partition at 0x70020000 (XIP for app execution)
18761891- Update/swap partitions use device-relative offsets
18771892- 4KB sector size (` WOLFBOOT_SECTOR_SIZE=0x1000 ` )
18781893- ECC256 + SHA256 for signature verification
18791894
1895+ ### TrustZone Support (TZEN=1)
1896+
1897+ The STM32N6 Cortex-M55 always boots in secure mode. Unlike older STM32 parts
1898+ (H5, L5, U5), there is no ` TZEN ` option byte — TrustZone is always available
1899+ via the hardware IDAU (Implementation-Defined Attribution Unit).
1900+
1901+ wolfBoot supports two modes:
1902+
1903+ ** Without TrustZone** (` stm32n6.config ` ): wolfBoot runs from the non-secure SRAM
1904+ alias at ` 0x34000000 ` . A blanket SAU NSC region covers the entire address space,
1905+ allowing access to all peripherals and memory. The application boots in the same
1906+ (non-secure) state.
1907+
1908+ ** With TrustZone** (` stm32n6-tz.config ` , ` TZEN=1 ` ): wolfBoot runs from the secure
1909+ SRAM alias at ` 0x24000000 ` . The SAU is configured with specific regions:
1910+
1911+ | SAU Region | Address Range | Type | Purpose |
1912+ | ------------| ---------------| ------| ---------|
1913+ | 0 (NSC) | 0x24010000–0x2401FFFF | Non-Secure Callable | Gateway veneers |
1914+ | 1 (NS) | 0x70000000–0x7FFFFFFF | Non-Secure | XSPI2 flash (app XIP) |
1915+ | 2 (NS) | 0x34000000–0x343FFFFF | Non-Secure | App SRAM |
1916+ | 3 (NS) | 0x40000000–0x4FFFFFFF | Non-Secure | Peripheral NS aliases |
1917+ | * default* | * all other* | Secure | wolfBoot SRAM, secure peripherals |
1918+
1919+ wolfBoot uses secure peripheral aliases (0x56xxx RCC, 0x52xxx USART, 0x58xxx XSPI2).
1920+ The application runs in non-secure state and uses non-secure aliases (0x46xxx, 0x42xxx).
1921+ The flash script automatically selects the correct SRAM load address based on the
1922+ ` TZEN ` setting in ` .config ` .
1923+
1924+ ### SAU Configuration (non-TrustZone)
1925+
1926+ Without ` TZEN=1 ` , wolfBoot configures SAU region 0 to cover the entire 4GB address
1927+ space as Non-Secure Callable (NSC), allowing the CPU to access all peripherals and
1928+ memory regions regardless of IDAU attribution.
1929+
1930+ ### Shared Flash: PART_BOOT_EXT
1931+
1932+ The boot and update partitions reside on the same XSPI2 NOR flash. During
1933+ firmware updates, wolfBoot must read boot partition data while also issuing SPI
1934+ commands to write the update/swap partitions. Since the XSPI2 cannot be in
1935+ memory-mapped (XIP) and SPI command mode simultaneously, the boot partition
1936+ must be accessed via SPI commands during updates.
1937+
1938+ The config sets ` PART_BOOT_EXT ` so all boot partition reads during the update
1939+ swap use ` ext_flash_read() ` (SPI commands) instead of XIP. The ` ext_flash_* `
1940+ functions in ` hal/stm32n6.c ` accept both absolute memory-mapped addresses
1941+ (0x70xxxxxx) and device-relative offsets, converting automatically.
1942+
1943+ The application still boots via XIP — ` do_boot() ` jumps to the memory-mapped
1944+ address at 0x70020400.
1945+
18801946### XIP Constraints
18811947
18821948Since the application executes directly from NOR flash via XSPI2 memory-mapped
@@ -1885,9 +1951,19 @@ mode, the following constraints apply:
18851951- The application must NOT call ` hal_init() ` — XSPI2 is already configured by
18861952 wolfBoot for memory-mapped mode. Reinitializing XSPI2 would disable XIP and
18871953 crash the CPU.
1888- - Calling ` wolfBoot_success() ` requires all flash write functions to be placed
1889- in RAM (RAMFUNCTION). The HAL flash functions in ` hal/stm32n6.c ` need the
1890- RAMFUNCTION attribute for this to work from an XIP application.
1954+ - ` RAM_CODE=1 ` must be set so that flash write functions are tagged RAMFUNCTION
1955+ and placed in ` .ramcode ` . The test-app's startup code copies ` .ramcode ` to
1956+ RAM, allowing ` wolfBoot_success() ` and other flash operations to execute
1957+ from RAM while XSPI2 is in SPI command mode.
1958+ - The ` nor_flash_write() ` function buffers data to a stack-local array before
1959+ issuing SPI commands, since the source data pointer may reference XIP flash
1960+ that becomes inaccessible when XSPI2 leaves memory-mapped mode.
1961+
1962+ ### UART Clock
1963+
1964+ USART1 kernel clock defaults to PCLK2. With the PLL1 configuration
1965+ (IC2 = 400 MHz, AHB prescaler /2, APB2 prescaler /1), PCLK2 = 200 MHz.
1966+ The BRR is calculated accordingly for 115200 baud.
18911967
18921968### Flash Script Options
18931969
@@ -1914,11 +1990,12 @@ and start it:
19141990
19151991``` sh
19161992reset halt
1917- load_image wolfboot.bin 0x34000000 bin
1993+ # Use 0x24000000 for TZEN=1, 0x34000000 for non-TZ
1994+ load_image wolfboot.bin 0x24000000 bin
19181995reg msplim_s 0x00000000
19191996reg psplim_s 0x00000000
1920- reg msp 0x34020000
1921- mww 0xE000ED08 0x34000000
1997+ reg msp 0x24020000
1998+ mww 0xE000ED08 0x24000000
19221999resume < entry_address>
19232000```
19242001
0 commit comments