From c1887cd636f89ebe60fa9a3b687b00ca1def73f6 Mon Sep 17 00:00:00 2001 From: Mattia Moffa Date: Tue, 11 Nov 2025 01:07:21 +0100 Subject: [PATCH 1/5] Various STM32 TrustZone improvements - New config flags for flash geometry - New script to automatically set option bytes - End of stack address fix for the STM32U5 test app - STM32U5 support for NUCLEO-U575ZI-Q (previously only supported discovery board) --- Makefile | 6 + .../stm32h5-tz-dualbank-otp-lms.config | 4 + .../examples/stm32h5-tz-dualbank-otp.config | 4 + config/examples/stm32h5-tz-dualbank.config | 4 + config/examples/stm32h5-tz.config | 4 + config/examples/stm32l5-wolfcrypt-tz.config | 4 + config/examples/stm32u5-wolfcrypt-tz.config | 4 + config/examples/stm32u5.config | 4 + docs/STM32-TZ.md | 11 ++ hal/stm32_tz.c | 9 +- hal/stm32h5.ld | 7 +- hal/stm32l5.ld | 6 +- hal/stm32u5.c | 16 ++- hal/stm32u5.h | 11 ++ hal/stm32u5.ld | 6 +- include/target.h.in | 10 ++ test-app/ARM-stm32u5-ns.ld | 2 +- test-app/app_stm32u5.c | 54 ++++++++- tools/scripts/set-stm32-tz-option-bytes.sh | 107 ++++++++++++++++++ 19 files changed, 251 insertions(+), 22 deletions(-) create mode 100755 tools/scripts/set-stm32-tz-option-bytes.sh diff --git a/Makefile b/Makefile index 453501cc22..32002b51e7 100644 --- a/Makefile +++ b/Makefile @@ -402,6 +402,10 @@ $(LSCRIPT): $(LSCRIPT_IN) FORCE sed -e "s/@ARCH_FLASH_OFFSET@/$(ARCH_FLASH_OFFSET)/g" | \ sed -e "s/@BOOTLOADER_PARTITION_SIZE@/$(BOOTLOADER_PARTITION_SIZE)/g" | \ sed -e "s/@WOLFBOOT_ORIGIN@/$(WOLFBOOT_ORIGIN)/g" | \ + sed -e "s/@WOLFBOOT_KEYVAULT_ADDRESS@/$(WOLFBOOT_KEYVAULT_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_KEYVAULT_SIZE@/$(WOLFBOOT_KEYVAULT_SIZE)/g" | \ + sed -e "s/@WOLFBOOT_NSC_ADDRESS@/$(WOLFBOOT_NSC_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_NSC_SIZE@/$(WOLFBOOT_NSC_SIZE)/g" | \ sed -e "s/@WOLFBOOT_PARTITION_BOOT_ADDRESS@/$(WOLFBOOT_PARTITION_BOOT_ADDRESS)/g" | \ sed -e "s/@WOLFBOOT_PARTITION_SIZE@/$(WOLFBOOT_PARTITION_SIZE)/g" | \ sed -e "s/@WOLFBOOT_PARTITION_UPDATE_ADDRESS@/$(WOLFBOOT_PARTITION_UPDATE_ADDRESS)/g" | \ @@ -480,6 +484,8 @@ include/target.h: $(TARGET_H_TEMPLATE) FORCE $(Q)cat $(TARGET_H_TEMPLATE) | \ sed -e "s/@WOLFBOOT_PARTITION_SIZE@/$(WOLFBOOT_PARTITION_SIZE)/g" | \ sed -e "s/@WOLFBOOT_SECTOR_SIZE@/$(WOLFBOOT_SECTOR_SIZE)/g" | \ + sed -e "s/@WOLFBOOT_NSC_ADDRESS@/$(WOLFBOOT_NSC_ADDRESS)/g" | \ + sed -e "s/@WOLFBOOT_NSC_SIZE@/$(WOLFBOOT_NSC_SIZE)/g" | \ sed -e "s/@WOLFBOOT_PARTITION_BOOT_ADDRESS@/$(WOLFBOOT_PARTITION_BOOT_ADDRESS)/g" | \ sed -e "s/@WOLFBOOT_PARTITION_UPDATE_ADDRESS@/$(WOLFBOOT_PARTITION_UPDATE_ADDRESS)/g" | \ sed -e "s/@WOLFBOOT_PARTITION_SWAP_ADDRESS@/$(WOLFBOOT_PARTITION_SWAP_ADDRESS)/g" | \ diff --git a/config/examples/stm32h5-tz-dualbank-otp-lms.config b/config/examples/stm32h5-tz-dualbank-otp-lms.config index 7ffe9ccd20..1459c47f82 100644 --- a/config/examples/stm32h5-tz-dualbank-otp-lms.config +++ b/config/examples/stm32h5-tz-dualbank-otp-lms.config @@ -20,6 +20,10 @@ RAM_CODE?=1 DUALBANK_SWAP?=1 WOLFBOOT_PARTITION_SIZE?=0xA0000 WOLFBOOT_SECTOR_SIZE?=0x2000 +WOLFBOOT_KEYVAULT_ADDRESS?=0x0C040000 +WOLFBOOT_KEYVAULT_SIZE?=0x1C000 +WOLFBOOT_NSC_ADDRESS?=0x0C05C000 +WOLFBOOT_NSC_SIZE?=0x4000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08060000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0C160000 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0xFFFFFFFF diff --git a/config/examples/stm32h5-tz-dualbank-otp.config b/config/examples/stm32h5-tz-dualbank-otp.config index af7421eff7..56eb631736 100644 --- a/config/examples/stm32h5-tz-dualbank-otp.config +++ b/config/examples/stm32h5-tz-dualbank-otp.config @@ -20,6 +20,10 @@ RAM_CODE?=1 DUALBANK_SWAP?=1 WOLFBOOT_PARTITION_SIZE?=0xA0000 WOLFBOOT_SECTOR_SIZE?=0x2000 +WOLFBOOT_KEYVAULT_ADDRESS?=0x0C040000 +WOLFBOOT_KEYVAULT_SIZE?=0x1C000 +WOLFBOOT_NSC_ADDRESS?=0x0C05C000 +WOLFBOOT_NSC_SIZE?=0x4000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08060000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0C160000 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0xFFFFFFFF diff --git a/config/examples/stm32h5-tz-dualbank.config b/config/examples/stm32h5-tz-dualbank.config index 3eaf2f16ad..68e59e5c55 100644 --- a/config/examples/stm32h5-tz-dualbank.config +++ b/config/examples/stm32h5-tz-dualbank.config @@ -20,6 +20,10 @@ RAM_CODE?=1 DUALBANK_SWAP?=1 WOLFBOOT_PARTITION_SIZE?=0xA0000 WOLFBOOT_SECTOR_SIZE?=0x2000 +WOLFBOOT_KEYVAULT_ADDRESS?=0x0C040000 +WOLFBOOT_KEYVAULT_SIZE?=0x1C000 +WOLFBOOT_NSC_ADDRESS?=0x0C05C000 +WOLFBOOT_NSC_SIZE?=0x4000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08060000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0C160000 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0xFFFFFFFF diff --git a/config/examples/stm32h5-tz.config b/config/examples/stm32h5-tz.config index aeb4d6a52d..b76b63e7e2 100644 --- a/config/examples/stm32h5-tz.config +++ b/config/examples/stm32h5-tz.config @@ -20,6 +20,10 @@ RAM_CODE?=1 DUALBANK_SWAP?=0 WOLFBOOT_PARTITION_SIZE?=0xA0000 WOLFBOOT_SECTOR_SIZE?=0x2000 +WOLFBOOT_KEYVAULT_ADDRESS?=0x0C040000 +WOLFBOOT_KEYVAULT_SIZE?=0x1C000 +WOLFBOOT_NSC_ADDRESS?=0x0C05C000 +WOLFBOOT_NSC_SIZE?=0x4000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08060000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0C100000 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0C1A0000 diff --git a/config/examples/stm32l5-wolfcrypt-tz.config b/config/examples/stm32l5-wolfcrypt-tz.config index 8c19d235d4..da470f2a4a 100644 --- a/config/examples/stm32l5-wolfcrypt-tz.config +++ b/config/examples/stm32l5-wolfcrypt-tz.config @@ -20,6 +20,10 @@ RAM_CODE?=0 DUALBANK_SWAP?=0 WOLFBOOT_PARTITION_SIZE?=0x1F800 WOLFBOOT_SECTOR_SIZE?=0x800 +WOLFBOOT_KEYVAULT_ADDRESS?=0x0C020000 +WOLFBOOT_KEYVAULT_SIZE?=0x18000 +WOLFBOOT_NSC_ADDRESS?=0xC038000 +WOLFBOOT_NSC_SIZE?=0x8000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08040000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x805F800 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0807F000 diff --git a/config/examples/stm32u5-wolfcrypt-tz.config b/config/examples/stm32u5-wolfcrypt-tz.config index d629895c42..207f8a415e 100644 --- a/config/examples/stm32u5-wolfcrypt-tz.config +++ b/config/examples/stm32u5-wolfcrypt-tz.config @@ -20,6 +20,10 @@ RAM_CODE?=0 DUALBANK_SWAP?=0 WOLFBOOT_PARTITION_SIZE?=0x1F800 WOLFBOOT_SECTOR_SIZE?=0x800 +WOLFBOOT_KEYVAULT_ADDRESS?=0x0C020000 +WOLFBOOT_KEYVAULT_SIZE?=0x18000 +WOLFBOOT_NSC_ADDRESS?=0x0C038000 +WOLFBOOT_NSC_SIZE?=0x8000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08040000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x805F800 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0807F000 diff --git a/config/examples/stm32u5.config b/config/examples/stm32u5.config index f3571f9cac..fdf0eaa08c 100644 --- a/config/examples/stm32u5.config +++ b/config/examples/stm32u5.config @@ -22,6 +22,10 @@ RAM_CODE?=0 DUALBANK_SWAP?=0 WOLFBOOT_PARTITION_SIZE?=0x1F800 WOLFBOOT_SECTOR_SIZE?=0x800 +WOLFBOOT_KEYVAULT_ADDRESS?=0x0C020000 +WOLFBOOT_KEYVAULT_SIZE?=0x18000 +WOLFBOOT_NSC_ADDRESS?=0x0C038000 +WOLFBOOT_NSC_SIZE?=0x8000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08040000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x805F800 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0807F000 diff --git a/docs/STM32-TZ.md b/docs/STM32-TZ.md index 72cdaaf4e2..2e7b0dccc3 100644 --- a/docs/STM32-TZ.md +++ b/docs/STM32-TZ.md @@ -55,6 +55,17 @@ image header size must be supplied as an environment variable. For example: IMAGE_HEADER_SIZE=1024 ./tools/keytools/sign --sha256 --ecc256 myapp.bin wolfboot_signing_private_key.der 1 ``` +### Setting option bytes automatically + +In order to use wolfBoot with an STM32 device, the device's option bytes need +to be consistent with wolfBoot's configuration. The script at +[tools/scripts/set-stm32-tz-option-bytes.sh](tools/scripts/set-stm32-tz-option-bytes.sh) +will attempt to read the wolfBoot `.config` file and automatically calculate +and set your device's TrustZone-related option bytes according to it, using +`STM32_Programmer_CLI`, which is part of the +[STM32CubeProg](https://www.st.com/en/development-tools/stm32cubeprog.html) +tool. + ### NSC API wolfBoot provides a few Non-Secure Callable functions to allow a non-secure diff --git a/hal/stm32_tz.c b/hal/stm32_tz.c index 52b33e160f..acada7bab9 100644 --- a/hal/stm32_tz.c +++ b/hal/stm32_tz.c @@ -37,6 +37,7 @@ #include "image.h" #include "hal.h" +#include "target.h" #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && (!defined(FLAGS_HOME) || !defined(DISABLE_BACKUP)) @@ -297,7 +298,8 @@ void hal_tz_sau_init(void) /* SAU is set up before staging. Set up all areas as secure. */ /* Non-secure callable: NSC functions area */ - sau_init_region(0, 0x0C040000, 0x0C05FFFF, 1); + sau_init_region(0, WOLFBOOT_NSC_ADDRESS, + WOLFBOOT_NSC_ADDRESS + WOLFBOOT_NSC_SIZE - 1, 1); /* Secure: application flash area (first bank) */ sau_init_region(1, WOLFBOOT_PARTITION_BOOT_ADDRESS, FLASH_BANK2_BASE - 1, 0); @@ -331,10 +333,11 @@ void hal_tz_sau_init(void) void hal_tz_sau_init(void) { /* Non-secure callable: NSC functions area */ - sau_init_region(0, 0x0C038000, 0x0C040000, 1); + sau_init_region(0, WOLFBOOT_NSC_ADDRESS, + WOLFBOOT_NSC_ADDRESS + WOLFBOOT_NSC_SIZE - 1, 1); /* Non-secure: application flash area */ - sau_init_region(1, 0x08040000, 0x0807FFFF, 0); + sau_init_region(1, WOLFBOOT_PARTITION_BOOT_ADDRESS, WOLFBOOT_PARTITION_BOOT_ADDRESS + 2 * WOLFBOOT_PARTITION_SIZE - 1, 0); /* Non-secure RAM region in SRAM1/SRAM2 */ sau_init_region(2, 0x20020000, 0x2003FFFF, 0); diff --git a/hal/stm32h5.ld b/hal/stm32h5.ld index 7807163818..a24b0e2ad2 100644 --- a/hal/stm32h5.ld +++ b/hal/stm32h5.ld @@ -1,12 +1,11 @@ MEMORY { - /* If FLASH_KEYVAULT or FLASH_NSC length is adjusted FLASH length needs adjusted too */ - FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ - 0x20000 + FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @WOLFBOOT_KEYVAULT_ADDRESS@ - @ARCH_FLASH_OFFSET@ RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 0x20000 RAM_KV (rw): ORIGIN = 0x30020000, LENGTH = 0x10000 RAM_HEAP (rw): ORIGIN = 0x30030000, LENGTH = 0x10000 /* 64KB Heap for wolfcrypt/PKCS11 */ - FLASH_KEYVAULT(rw): ORIGIN = @WOLFBOOT_ORIGIN@ + LENGTH(FLASH), LENGTH = 0x1C000 - FLASH_NSC(rx): ORIGIN = @WOLFBOOT_ORIGIN@ + LENGTH(FLASH) + LENGTH(FLASH_KEYVAULT), LENGTH = 0x4000 + FLASH_KEYVAULT(rw): ORIGIN = @WOLFBOOT_KEYVAULT_ADDRESS@, LENGTH = @WOLFBOOT_KEYVAULT_SIZE@ + FLASH_NSC(rx): ORIGIN = @WOLFBOOT_NSC_ADDRESS@, LENGTH = @WOLFBOOT_NSC_SIZE@ } SECTIONS diff --git a/hal/stm32l5.ld b/hal/stm32l5.ld index 03148ec35b..1d08c544ba 100644 --- a/hal/stm32l5.ld +++ b/hal/stm32l5.ld @@ -1,11 +1,11 @@ MEMORY { - FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ - 0x20000 + FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @WOLFBOOT_KEYVAULT_ADDRESS@ - @ARCH_FLASH_OFFSET@ RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 0x00012000 RAM_HEAP (rw): ORIGIN = 0x30012000, LENGTH = 0xc000 /* 49152 B Heap for wolfcrypt/PKCS11 */ RAM_KV (rw): ORIGIN = 0x3001e000, LENGTH = 0x2000 - FLASH_KEYVAULT(rw): ORIGIN = @WOLFBOOT_ORIGIN@ + 0x20000, LENGTH = 0x18000 - FLASH_NSC(rx): ORIGIN = @WOLFBOOT_ORIGIN@ + 0x38000, LENGTH = 0x8000 + FLASH_KEYVAULT(rw): ORIGIN = @WOLFBOOT_KEYVAULT_ADDRESS@, LENGTH = @WOLFBOOT_KEYVAULT_SIZE@ + FLASH_NSC(rx): ORIGIN = @WOLFBOOT_NSC_ADDRESS@, LENGTH = @WOLFBOOT_NSC_SIZE@ } SECTIONS diff --git a/hal/stm32u5.c b/hal/stm32u5.c index 9156cd7f39..05d63519c1 100644 --- a/hal/stm32u5.c +++ b/hal/stm32u5.c @@ -471,14 +471,22 @@ void RAMFUNCTION hal_flash_dualbank_swap(void) static void led_unsecure() { - uint32_t pin; - +#ifdef STM32_DISCOVERY /* Enable clock for User LED GPIOs */ RCC_AHB2ENR1_CLOCK_ER|= GPIOH_AHB2ENR1_CLOCK_ER; /* Un-secure User LED GPIO pins */ - GPIOH_SECCFGR&=~(1< /* linker script variables */ + extern const uint32_t _wolfboot_nsc_address[]; + extern const uint32_t _wolfboot_nsc_size[]; extern const uint32_t _wolfboot_partition_boot_address[]; extern const uint32_t _wolfboot_partition_size[]; extern const uint32_t _wolfboot_partition_update_address[]; extern const uint32_t _wolfboot_partition_swap_address[]; /* create plain integers from linker script variables */ + static const uint32_t WOLFBOOT_NSC_ADDRESS = (uint32_t)_wolfboot_nsc_address; + static const uint32_t WOLFBOOT_NSC_SIZE = (uint32_t)_wolfboot_nsc_size; static const uint32_t WOLFBOOT_PARTITION_BOOT_ADDRESS = (uint32_t)_wolfboot_partition_boot_address; static const uint32_t WOLFBOOT_PARTITION_SIZE = (uint32_t)_wolfboot_partition_size; static const uint32_t WOLFBOOT_PARTITION_UPDATE_ADDRESS = (uint32_t)_wolfboot_partition_update_address; @@ -73,6 +77,12 @@ #endif /* use values provided on input template parsing */ + #ifndef WOLFBOOT_NSC_ADDRESS + #define WOLFBOOT_NSC_ADDRESS @WOLFBOOT_NSC_ADDRESS@ + #endif + #ifndef WOLFBOOT_NSC_SIZE + #define WOLFBOOT_NSC_SIZE @WOLFBOOT_NSC_SIZE@ + #endif #ifndef WOLFBOOT_PARTITION_BOOT_ADDRESS #define WOLFBOOT_PARTITION_BOOT_ADDRESS @WOLFBOOT_PARTITION_BOOT_ADDRESS@ #endif diff --git a/test-app/ARM-stm32u5-ns.ld b/test-app/ARM-stm32u5-ns.ld index 0b641e55b5..50c2d02f51 100644 --- a/test-app/ARM-stm32u5-ns.ld +++ b/test-app/ARM-stm32u5-ns.ld @@ -1,7 +1,7 @@ MEMORY { FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ - RAM (rwx) : ORIGIN = 0x20040000, LENGTH = 64K /* Run in lowmem */ + RAM (rwx) : ORIGIN = 0x20020000, LENGTH = 128K } SECTIONS diff --git a/test-app/app_stm32u5.c b/test-app/app_stm32u5.c index 5134d5a716..dc028fa0c3 100644 --- a/test-app/app_stm32u5.c +++ b/test-app/app_stm32u5.c @@ -30,20 +30,36 @@ #include "wolfboot/wolfboot.h" #include "target.h" +#ifdef STM32_DISCOVERY #define LED_BOOT_PIN (7) /* PH7 - Discovery - Green Led */ -#define LED_USR_PIN (6) /* PH6 - Discovery - Red Led */ +#define LED_USR_PIN (6) /* PH6 - Discovery - Red Led */ +#else +#define LED_BOOT_PIN (7) /* PC7 - Nucleo-U575ZI-Q - Green Led */ +#define LED_USR_PIN (2) /* PG2 - Nucleo-U575ZI-Q - Red Led */ +#endif /*Non-Secure */ #define RCC_BASE (0x46020C00) /* RM0456 - Table 4 */ #define PWR_BASE (0x46020800) /* RM0456 - Table 4 */ +#define GPIOC_BASE 0x42020800 +#define GPIOG_BASE 0x42021800 #define GPIOH_BASE 0x42021C00 +#define GPIOC_MODER (*(volatile uint32_t *)(GPIOC_BASE + 0x00)) +#define GPIOC_PUPDR (*(volatile uint32_t *)(GPIOC_BASE + 0x0C)) +#define GPIOC_BSRR (*(volatile uint32_t *)(GPIOC_BASE + 0x18)) + +#define GPIOG_MODER (*(volatile uint32_t *)(GPIOG_BASE + 0x00)) +#define GPIOG_PUPDR (*(volatile uint32_t *)(GPIOG_BASE + 0x0C)) +#define GPIOG_BSRR (*(volatile uint32_t *)(GPIOG_BASE + 0x18)) -#define GPIOH_MODER (*(volatile uint32_t *)(GPIOH_BASE + 0x00)) -#define GPIOH_PUPDR (*(volatile uint32_t *)(GPIOH_BASE + 0x0C)) -#define GPIOH_BSRR (*(volatile uint32_t *)(GPIOH_BASE + 0x18)) +#define GPIOH_MODER (*(volatile uint32_t *)(GPIOH_BASE + 0x00)) +#define GPIOH_PUPDR (*(volatile uint32_t *)(GPIOH_BASE + 0x0C)) +#define GPIOH_BSRR (*(volatile uint32_t *)(GPIOH_BASE + 0x18)) #define RCC_AHB2ENR1_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0x8C )) +#define GPIOC_AHB2ENR1_CLOCK_ER (1 << 2) +#define GPIOG_AHB2ENR1_CLOCK_ER (1 << 6) #define GPIOH_AHB2ENR1_CLOCK_ER (1 << 7) #define PWR_CR2 (*(volatile uint32_t *)(PWR_BASE + 0x04)) @@ -54,7 +70,11 @@ static void boot_led_on(void) uint32_t reg; uint32_t pin = LED_BOOT_PIN; +#ifdef STM32_DISCOVERY RCC_AHB2ENR1_CLOCK_ER|= GPIOH_AHB2ENR1_CLOCK_ER; +#else + RCC_AHB2ENR1_CLOCK_ER|= GPIOC_AHB2ENR1_CLOCK_ER; +#endif /* Delay after an RCC peripheral clock enabling */ reg = RCC_AHB2ENR1_CLOCK_ER; @@ -63,15 +83,26 @@ static void boot_led_on(void) PWR_CR2 |= PWR_CR2_IOSV; #endif +#ifdef STM32_DISCOVERY reg = GPIOH_MODER & ~(0x03 << (pin * 2)); GPIOH_MODER = reg | (1 << (pin * 2)); GPIOH_PUPDR &= ~(0x03 << (pin * 2)); GPIOH_BSRR |= (1 << (pin + 16)); +#else + reg = GPIOC_MODER & ~(0x03 << (pin * 2)); + GPIOC_MODER = reg | (1 << (pin * 2)); + GPIOC_PUPDR &= ~(0x03 << (pin * 2)); + GPIOC_BSRR |= (1 << pin); +#endif } static void boot_led_off(void) { +#ifdef STM32_DISCOVERY GPIOH_BSRR |= (1 << (LED_BOOT_PIN)); +#else + GPIOC_BSRR |= (1 << (LED_BOOT_PIN + 16)); +#endif } void usr_led_on(void) @@ -79,19 +110,34 @@ void usr_led_on(void) uint32_t reg; uint32_t pin = LED_USR_PIN; +#ifdef STM32_DISCOVERY RCC_AHB2ENR1_CLOCK_ER|= GPIOH_AHB2ENR1_CLOCK_ER; +#else + RCC_AHB2ENR1_CLOCK_ER|= GPIOG_AHB2ENR1_CLOCK_ER; +#endif /* Delay after an RCC peripheral clock enabling */ reg = RCC_AHB2ENR1_CLOCK_ER; +#ifdef STM32_DISCOVERY reg = GPIOH_MODER & ~(0x03 << (pin * 2)); GPIOH_MODER = reg | (1 << (pin * 2)); GPIOH_PUPDR &= ~(0x03 << (pin * 2)); GPIOH_BSRR |= (1 << (pin + 16)); +#else + reg = GPIOG_MODER & ~(0x03 << (pin * 2)); + GPIOG_MODER = reg | (1 << (pin * 2)); + GPIOG_PUPDR &= ~(0x03 << (pin * 2)); + GPIOG_BSRR |= (1 << pin); +#endif } void usr_led_off(void) { +#ifdef STM32_DISCOVERY GPIOH_BSRR |= (1 << (LED_USR_PIN)); +#else + GPIOG_BSRR |= (1 << (LED_USR_PIN + 16)); +#endif } void main(void) diff --git a/tools/scripts/set-stm32-tz-option-bytes.sh b/tools/scripts/set-stm32-tz-option-bytes.sh new file mode 100755 index 0000000000..b4d3dd2547 --- /dev/null +++ b/tools/scripts/set-stm32-tz-option-bytes.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +# Automatically sets required option bytes on STM32 boards based on .config + +if ! which STM32_Programmer_CLI > /dev/null 2>&1; then + echo "Error: please make sure STM32_Programmer_CLI is installed and in your PATH." >&2 + exit 1 +fi + +if [ ! -f .config ]; then + echo "Error: .config file not found. Copy a file from config/examples into .config." >&2 + exit 1 +fi + + +TARGET="$(awk -F '?=|:=|=' '$1 == "TARGET" { print $2 }' .config)" +if [ -z "$TARGET" -o \( "$TARGET" != "stm32h5" -a "$TARGET" != "stm32l5" -a "$TARGET" != "stm32u5" \) ]; then + echo "Error: target found in .config: '$TARGET'." >&2 + echo "This script only supports the targets stm32h5, stm32l5 and stm32u5." >&2 + exit 1 +fi + +TZEN="$(awk -F '?=|:=|=' '$1 == "TZEN" { print $2 }' .config)" +if [ -z "$TZEN" -o "$TZEN" != 1 ]; then + echo "Error: this script requires a .config with TZEN=1" >&2 + exit 1 +fi + +FLASH_OFFSET=0x08000000 + +WOLFBOOT_PARTITION_BOOT_ADDRESS="$(awk -F '?=|:=|=' '$1 == "WOLFBOOT_PARTITION_BOOT_ADDRESS" { print $2 }' .config)" +WOLFBOOT_PARTITION_SIZE="$(awk -F '?=|:=|=' '$1 == "WOLFBOOT_PARTITION_SIZE" { print $2 }' .config)" +WOLFBOOT_SECTOR_SIZE="$(awk -F '?=|:=|=' '$1 == "WOLFBOOT_SECTOR_SIZE" { print $2 }' .config)" +DUALBANK_SWAP="$(awk -F '?=|:=|=' '$1 == "DUALBANK_SWAP" { print $2 }' .config)" + +last_wolfboot_sector=$(((WOLFBOOT_PARTITION_BOOT_ADDRESS - FLASH_OFFSET - 1) / WOLFBOOT_SECTOR_SIZE)) +last_wolfboot_sector_hex="$(printf "0x%x" "$last_wolfboot_sector")" + +last_partition_sector=$((last_wolfboot_sector + WOLFBOOT_PARTITION_SIZE / WOLFBOOT_SECTOR_SIZE)) +last_partition_sector_hex="$(printf "0x%x" "$last_partition_sector")" + +declare -a obn # option bytes names +declare -a obv # option bytes values +oblen=0 # length of the above arrays + +# add option bytes entry +function add_ob() { + obn[$oblen]="$1" + obv[$oblen]="$2" + ((oblen++)) +} + +add_ob TZEN 0xB4 +add_ob SWAP_BANK 0x0 + +if [ "$TARGET" = stm32h5 ]; then + add_ob SECBOOTADD 0xC0000 + add_ob SECWM1_STRT 0x0 + add_ob SECWM1_END $last_wolfboot_sector_hex + add_ob SECWM2_STRT 0x0 + add_ob SECWM2_END $last_partition_sector_hex +elif [ "$TARGET" = stm32u5 ]; then + add_ob nSWBOOT0 0x0 + add_ob nBOOT0 0x1 + add_ob SECBOOTADD0 0xC0000 + add_ob SECWM1_PSTRT 0x0 + add_ob SECWM1_PEND $last_wolfboot_sector_hex + add_ob SECWM2_PSTRT 0x7f + add_ob SECWM2_PEND 0x0 +elif [ "$TARGET" = stm32l5 ]; then + add_ob DBANK 0x1 + add_ob nSWBOOT0 0x0 + add_ob nBOOT0 0x1 + add_ob SECBOOTADD0 0x180000 + add_ob SECWM1_PSTRT 0x0 + add_ob SECWM1_PEND $last_wolfboot_sector_hex + add_ob SECWM2_PSTRT 0x7f + add_ob SECWM2_PEND 0x0 +fi + +echo "Setting the following option bytes:" + +oblist="" + +for ((i = 0; i < oblen; i++)); do + echo -e "\t${obn[$i]}" = "${obv[$i]}" + oblist="$oblist ${obn[$i]}=${obv[$i]}" +done + +echo -n "Confirm? [Y/n] " +read confirm +confirm="${confirm,,}" + +[ -n "$confirm" -a "$confirm" != "y" ] && exit 0 + +echo Setting option bytes... + +STM32_Programmer_CLI -c port=swd -ob $oblist +ret=$? + +if [ $ret -eq 0 ]; then + echo "Option bytes set successfully." +else + echo "Failed setting option bytes." +fi + +exit $ret From 7b4457eac32ff035e783a911586feaf739abb890 Mon Sep 17 00:00:00 2001 From: Mattia Moffa Date: Tue, 11 Nov 2025 16:07:45 +0100 Subject: [PATCH 2/5] Fix stm32h5.config --- config/examples/stm32h5.config | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/examples/stm32h5.config b/config/examples/stm32h5.config index 61a340fd3c..7192f65090 100644 --- a/config/examples/stm32h5.config +++ b/config/examples/stm32h5.config @@ -20,6 +20,10 @@ RAM_CODE?=0 DUALBANK_SWAP?=0 WOLFBOOT_PARTITION_SIZE?=0xA0000 WOLFBOOT_SECTOR_SIZE?=0x2000 +WOLFBOOT_KEYVAULT_ADDRESS?=0x0C040000 +WOLFBOOT_KEYVAULT_SIZE?=0x1C000 +WOLFBOOT_NSC_ADDRESS?=0x0C05C000 +WOLFBOOT_NSC_SIZE?=0x4000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08060000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08100000 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x081A0000 From ce480a098f85c50222373d4bc541be91e09637f1 Mon Sep 17 00:00:00 2001 From: Mattia Moffa Date: Wed, 19 Nov 2025 16:40:15 +0100 Subject: [PATCH 3/5] Non-TZ nRF5340 fixes --- arch.mk | 6 +++ config/examples/nrf5340.config | 4 +- config/examples/nrf5340_net.config | 4 +- docs/Targets.md | 12 +++++- hal/nrf5340.c | 10 +++++ hal/nrf5340.h | 23 ++++++++++-- test-app/Makefile | 3 +- tools/scripts/nrf5340/app.gdbinit | 7 ++++ tools/scripts/nrf5340/build_flash.sh | 55 +++++++++++++++++++++------- tools/scripts/nrf5340/net.gdbinit | 7 ++++ 10 files changed, 108 insertions(+), 23 deletions(-) create mode 100644 tools/scripts/nrf5340/app.gdbinit create mode 100644 tools/scripts/nrf5340/net.gdbinit diff --git a/arch.mk b/arch.mk index 7c0335c546..61ffb9ddd4 100644 --- a/arch.mk +++ b/arch.mk @@ -687,6 +687,12 @@ ifeq ($(TARGET),mcxw) $(MCUXPRESSO_DRIVERS)/drivers/fsl_romapi.o endif +ifeq ($(TARGET),nrf5340_net) + # Net core doesn't support DSP and FP + CFLAGS+=-mcpu=cortex-m33+nodsp+nofp + LDFLAGS+=-mcpu=cortex-m33+nodsp+nofp +endif + ifeq ($(TARGET),imx_rt) CFLAGS+=\ -I$(MCUXPRESSO_DRIVERS) \ diff --git a/config/examples/nrf5340.config b/config/examples/nrf5340.config index 83be6bdaae..2b463d9713 100644 --- a/config/examples/nrf5340.config +++ b/config/examples/nrf5340.config @@ -26,8 +26,8 @@ QSPI_FLASH?=1 # Flash is 4KB pages (app) WOLFBOOT_SECTOR_SIZE?=0x1000 -# Application offset (reserve 48KB for wolfBoot) -WOLFBOOT_PARTITION_BOOT_ADDRESS?=0xC000 +# Application offset (reserve 64KB for wolfBoot) +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x10000 # Application Partition Size (952KB) WOLFBOOT_PARTITION_SIZE?=0xEE000 diff --git a/config/examples/nrf5340_net.config b/config/examples/nrf5340_net.config index bc18a07606..31964ed4a4 100644 --- a/config/examples/nrf5340_net.config +++ b/config/examples/nrf5340_net.config @@ -30,8 +30,8 @@ ARCH_FLASH_OFFSET=0x01000000 # Flash is 2KB pages WOLFBOOT_SECTOR_SIZE?=0x800 -# Application offset (reserve 48KB for wolfBoot) -WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x0100C000 +# Application offset (reserve 64KB for wolfBoot) +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x01010000 # Application Partition Size (184KB) WOLFBOOT_PARTITION_SIZE?=0x2E000 diff --git a/docs/Targets.md b/docs/Targets.md index ba83258018..12e4f7c5bf 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -2735,14 +2735,22 @@ Debugging with JLink: 1) Start GDB Server: ``` +# To debug the app core: JLinkGDBServer -device nRF5340_xxAA_APP -if SWD -port 3333 +# To debug the net core: +JLinkGDBServer -device nRF5340_xxAA_NET -if SWD -port 3334 ``` 2) Start GDB -This will use .gdbinit, but can supply `wolfboot.elf -ex "target remote localhost:3333"` if permissions not allowing. ``` -arm-none-eabi-gdb +cd tools/scripts/nrf5340 + +# To debug the app core: +arm-none-eabi-gdb -x app.gdbinit +# To debug the net core: +arm-none-eabi-gdb -x net.gdbinit + b main mon reset c diff --git a/hal/nrf5340.c b/hal/nrf5340.c index 60e231a6ec..4d42e2f67c 100644 --- a/hal/nrf5340.c +++ b/hal/nrf5340.c @@ -340,6 +340,14 @@ void ext_flash_unlock(void) } #endif /* TARGET_nrf5340_net */ +static void hal_handle_approtect(void) { +#ifdef DEBUG_SYMBOLS + /* Needed to allow debugger access */ + CTRLAP_APPROTECT_DISABLE = 0x50FA50FA; + CTRLAP_SECUREAPPROTECT_DISABLE = 0x50FA50FA; +#endif +} + static void clock_init(void) { #ifdef TARGET_nrf5340_app @@ -692,6 +700,8 @@ void hal_init(void) clock_init(); + hal_handle_approtect(); + #ifdef DEBUG_UART uart_init(); #ifdef __WOLFBOOT diff --git a/hal/nrf5340.h b/hal/nrf5340.h index 0098e29c44..397cd250a5 100644 --- a/hal/nrf5340.h +++ b/hal/nrf5340.h @@ -113,10 +113,27 @@ void sleep_us(uint32_t usec); #define SPU_FLASHREGION_PERM_LOCK (1 << 8) /* The content of this register can't be changed until the next reset */ #endif -/* OTP */ -#define UICR_BASE (0x00FF8000UL) +/* UICR */ +#ifdef TARGET_nrf5340_app + #define UICR_BASE (0x00FF8000UL) +#else + #define UICR_BASE (0x01FF8000UL) +#endif #define UICR_USER (UICR_BASE) -#define UICR_OTP (UICR_BASE + 0x100) +#define UICR_APPROTECT (*(volatile uint32_t *)(UICR_BASE + 0x000)) +#define UICR_SECUREAPPROTECT (*(volatile uint32_t *)(UICR_BASE + 0x01C)) +#define UICR_OTP (UICR_BASE + 0x100) + +/* CTRLAP */ +#ifdef TARGET_nrf5340_app + #define CTRLAP_BASE (0x50006000) +#else + #define CTRLAP_BASE (0x41006000) +#endif +#define CTRLAP_APPROTECT_LOCK (*(volatile uint32_t *)(CTRLAP_BASE 0x540)) +#define CTRLAP_APPROTECT_DISABLE (*(volatile uint32_t *)(CTRLAP_BASE 0x544)) +#define CTRLAP_SECUREAPPROTECT_LOCK (*(volatile uint32_t *)(CTRLAP_BASE 0x548)) +#define CTRLAP_SECUREAPPROTECT_DISABLE (*(volatile uint32_t *)(CTRLAP_BASE 0x54C)) /* Reset */ #ifdef TARGET_nrf5340_app diff --git a/test-app/Makefile b/test-app/Makefile index 4e167b4c41..cbe3fb89d0 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -235,7 +235,8 @@ ifeq ($(TARGET),stm32u5) endif ifeq ($(TARGET),nrf5340_net) - APP_OBJS:=app_$(TARGET).o ../test-app/libwolfboot.o + CFLAGS+=-mcpu=cortex-m33+nodsp+nofp + LDFLAGS+=-mcpu=cortex-m33+nodsp+nofp LSCRIPT_TEMPLATE=ARM-nrf5340_net.ld endif diff --git a/tools/scripts/nrf5340/app.gdbinit b/tools/scripts/nrf5340/app.gdbinit new file mode 100644 index 0000000000..e10521259f --- /dev/null +++ b/tools/scripts/nrf5340/app.gdbinit @@ -0,0 +1,7 @@ +file wolfboot_app.elf +tar rem:3333 +add-symbol-file image_app.elf +set pagination off +foc c + + diff --git a/tools/scripts/nrf5340/build_flash.sh b/tools/scripts/nrf5340/build_flash.sh index 26bc98574f..b5731bed53 100755 --- a/tools/scripts/nrf5340/build_flash.sh +++ b/tools/scripts/nrf5340/build_flash.sh @@ -15,8 +15,9 @@ # Build dela update version 3 and flash to external (also reprograms internal flash) # ./tools/scripts/nrf5340/build_flash.sh --delta -#import config for IMAGE_HEADER_SIZE and WOLFBOOT_SECTOR_SIZE -. config/examples/nrf5340.config +#import IMAGE_HEADER_SIZE and WOLFBOOT_SECTOR_SIZE +IMAGE_HEADER_SIZE="$(awk -F '?=|:=|=' '$1 == "IMAGE_HEADER_SIZE" { print $2 }' config/examples/nrf5340.config)" +WOLFBOOT_SECTOR_SIZE="$(awk -F '?=|:=|=' '$1 == "WOLFBOOT_SECTOR_SIZE" { print $2 }' config/examples/nrf5340.config)" # Defaults MAKE_ARGS=" DEBUG_SYMBOLS=1" @@ -47,22 +48,26 @@ fi while test $# -gt 0; do case "$1" in - -h|--help|-?) + -h|--help|-\?) echo "nRF5340 build / flash script" echo " " echo "default: build, erase and program" echo " " echo "options:" - echo "-h, --help show brief help" - echo "-c, --clean cleanup build artifacts" - echo "-b, --build build release with symbols" - echo "-d, --debug build debug" - echo "-v, --verbose build verbose" - echo "--version use custom version" - echo "-e, --erase do erase of internal/external flash" - echo "-p, --program program images built" - echo "-u, --update build update, sign and program external flash" - echo "-t, --delta build update, sign delta and program external flash" + echo "-h, --help show brief help" + echo "-c, --clean cleanup build artifacts" + echo "-b, --build build release with symbols" + echo "-d, --debug build debug" + echo "-v, --verbose build verbose" + echo "--version use custom version" + echo "-e, --erase do erase of internal/external flash" + echo "-ei, --erase-int do erase of internal flash" + echo "-ee, --erase-ext do erase of external flash" + echo "-p, --program program images built" + echo "-pi, --program-int program internal image (boot)" + echo "-pe, --program-ext program external image (update)" + echo "-u, --update build update, sign and program external flash" + echo "-t, --delta build update, sign delta and program external flash" exit 0 ;; -c|--clean) @@ -93,12 +98,32 @@ while test $# -gt 0; do echo "Do erase" shift ;; + -ei|--erase-int) + DO_ERASE_INT=1 + echo "Do erase internal" + shift + ;; + -ee|--erase-ext) + DO_ERASE_EXT=1 + echo "Do erase external" + shift + ;; -p|--program) DO_PROGRAM_INT=1 DO_PROGRAM_EXT=1 echo "Do program" shift ;; + -pi|--program-int) + DO_PROGRAM_INT=1 + echo "Do program internal" + shift + ;; + -pe|--program-ext) + DO_PROGRAM_EXT=1 + echo "Do program external" + shift + ;; --version) UPDATE_VERSION="$2" echo "Use version ${UPDATE_VERSION}" @@ -148,6 +173,8 @@ if [[ $DO_BUILD == 1 ]]; then make clean make $MAKE_ARGS cp test-app/image.bin tools/scripts/nrf5340/image_net.bin + cp wolfboot.elf tools/scripts/nrf5340/wolfboot_net.elf + cp test-app/image.elf tools/scripts/nrf5340/image_net.elf if [ ! -f tools/scripts/nrf5340/factory_net.bin ]; then cp test-app/image_v1_signed.bin tools/scripts/nrf5340/image_net_v1_signed.bin cp factory.bin tools/scripts/nrf5340/factory_net.bin @@ -158,6 +185,8 @@ if [[ $DO_BUILD == 1 ]]; then make clean make $MAKE_ARGS cp test-app/image.bin tools/scripts/nrf5340/image_app.bin + cp wolfboot.elf tools/scripts/nrf5340/wolfboot_app.elf + cp test-app/image.elf tools/scripts/nrf5340/image_app.elf if [ ! -f tools/scripts/nrf5340/factory_app.bin ]; then cp test-app/image_v1_signed.bin tools/scripts/nrf5340/image_app_v1_signed.bin cp factory.bin tools/scripts/nrf5340/factory_app.bin diff --git a/tools/scripts/nrf5340/net.gdbinit b/tools/scripts/nrf5340/net.gdbinit new file mode 100644 index 0000000000..80d0962444 --- /dev/null +++ b/tools/scripts/nrf5340/net.gdbinit @@ -0,0 +1,7 @@ +file wolfboot_net.elf +tar rem:3334 +add-symbol-file image_net.elf +set pagination off +foc c + + From a3866b88868717a4a16b70efdf321fec7ed1e642 Mon Sep 17 00:00:00 2001 From: Mattia Moffa Date: Wed, 19 Nov 2025 16:53:58 +0100 Subject: [PATCH 4/5] Fix new stm32h5-tz-tpm.config --- config/examples/stm32h5-tz-tpm.config | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/config/examples/stm32h5-tz-tpm.config b/config/examples/stm32h5-tz-tpm.config index fbf69e49cf..800a941ca2 100644 --- a/config/examples/stm32h5-tz-tpm.config +++ b/config/examples/stm32h5-tz-tpm.config @@ -20,6 +20,10 @@ RAM_CODE?=1 DUALBANK_SWAP?=0 WOLFBOOT_PARTITION_SIZE?=0xA0000 WOLFBOOT_SECTOR_SIZE?=0x2000 +WOLFBOOT_KEYVAULT_ADDRESS?=0x0C040000 +WOLFBOOT_KEYVAULT_SIZE?=0x1C000 +WOLFBOOT_NSC_ADDRESS?=0x0C05C000 +WOLFBOOT_NSC_SIZE?=0x4000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08060000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0C100000 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0C1A0000 @@ -29,4 +33,4 @@ WOLFCRYPT_TZ=1 WOLFCRYPT_TZ_PKCS11=1 IMAGE_HEADER_SIZE?=1024 ARMORED=1 -WOLFTPM=1 \ No newline at end of file +WOLFTPM=1 From bc9cfd3c1bd9f2825d6e60c512362de71993bc35 Mon Sep 17 00:00:00 2001 From: Mattia Moffa Date: Thu, 20 Nov 2025 17:40:08 +0100 Subject: [PATCH 5/5] Shorten line --- hal/stm32_tz.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hal/stm32_tz.c b/hal/stm32_tz.c index acada7bab9..3aefb68a2c 100644 --- a/hal/stm32_tz.c +++ b/hal/stm32_tz.c @@ -337,7 +337,9 @@ void hal_tz_sau_init(void) WOLFBOOT_NSC_ADDRESS + WOLFBOOT_NSC_SIZE - 1, 1); /* Non-secure: application flash area */ - sau_init_region(1, WOLFBOOT_PARTITION_BOOT_ADDRESS, WOLFBOOT_PARTITION_BOOT_ADDRESS + 2 * WOLFBOOT_PARTITION_SIZE - 1, 0); + sau_init_region(1, WOLFBOOT_PARTITION_BOOT_ADDRESS, + WOLFBOOT_PARTITION_BOOT_ADDRESS + 2 * WOLFBOOT_PARTITION_SIZE - 1, + 0); /* Non-secure RAM region in SRAM1/SRAM2 */ sau_init_region(2, 0x20020000, 0x2003FFFF, 0);