Skip to content

Commit 95b91b8

Browse files
authored
Merge pull request #641 from mattia-moffa/20251125-nrf5340-tz
nRF5340 TrustZone
2 parents b9fd9e0 + df49fbf commit 95b91b8

File tree

14 files changed

+430
-34
lines changed

14 files changed

+430
-34
lines changed

.github/workflows/test-configs.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ jobs:
136136
arch: arm
137137
config-file: ./config/examples/nrf5340.config
138138

139+
nrf5340_app_tz_test:
140+
uses: ./.github/workflows/test-build.yml
141+
with:
142+
arch: arm
143+
config-file: ./config/examples/nrf5340-tz.config
144+
139145
nrf5340_net_test:
140146
uses: ./.github/workflows/test-build.yml
141147
with:

arch.mk

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,12 @@ ifeq ($(TARGET),mcxw)
690690
$(MCUXPRESSO_DRIVERS)/drivers/fsl_romapi.o
691691
endif
692692

693+
ifeq ($(TARGET),nrf5340)
694+
ifneq ($(TZEN), 1)
695+
LSCRIPT_IN=hal/$(TARGET)-ns.ld
696+
endif
697+
endif
698+
693699
ifeq ($(TARGET),nrf5340_net)
694700
# Net core doesn't support DSP and FP
695701
CFLAGS+=-mcpu=cortex-m33+nodsp+nofp

config/examples/nrf5340-tz.config

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
ARCH?=ARM
2+
TZEN?=1
3+
TARGET?=nrf5340
4+
SIGN?=ECC384
5+
HASH?=SHA384
6+
WOLFBOOT_VERSION?=1
7+
VTOR?=1
8+
CORTEX_M0?=0
9+
CORTEX_M33?=1
10+
NO_ASM?=0
11+
NO_MPU=1
12+
ALLOW_DOWNGRADE?=0
13+
NVM_FLASH_WRITEONCE?=0
14+
DELTA_UPDATES?=1
15+
16+
SPMATH?=1
17+
RAM_CODE?=1
18+
19+
DUALBANK_SWAP?=0
20+
FLAGS_HOME=0
21+
DISABLE_BACKUP=0
22+
EXT_FLASH?=1
23+
SPI_FLASH?=0
24+
QSPI_FLASH?=1
25+
26+
# Flash is 4KB pages (app)
27+
WOLFBOOT_SECTOR_SIZE?=0x1000
28+
29+
# Flash keyvault: 112K
30+
WOLFBOOT_KEYVAULT_ADDRESS?=0x20000
31+
WOLFBOOT_KEYVAULT_SIZE?=0x1C000
32+
33+
# Flash NSC: 16K
34+
WOLFBOOT_NSC_ADDRESS?=0x3C000
35+
WOLFBOOT_NSC_SIZE?=0x04000
36+
37+
# Application offset (reserve 256K for wolfBoot + keyvault + NSC)
38+
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x40000
39+
40+
# Application Partition Size (768KB)
41+
WOLFBOOT_PARTITION_SIZE?=0xC0000
42+
43+
# External Flash offset for application update (1MB)
44+
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0
45+
46+
# External Flash offset for network update at 0x100000 (size=256KB)
47+
48+
# External Flash offset for swap (4KB)
49+
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x140000
50+
51+
V?=0
52+
DEBUG?=0
53+
DEBUG_UART?=1
54+
USE_GCC=1
55+
OPTIMIZATION_LEVEL=2
56+
57+
# Optionally wait for network core to boot before starting application core
58+
CFLAGS_EXTRA+=-DNRF_SYNC_CORES
59+
60+
# Use larger block size for swapping sectors (performance improvement)
61+
CFLAGS_EXTRA+=-DFLASHBUFFER_SIZE=0x1000
62+
63+
# Enable optional power control pin (active low) P1.00
64+
#CFLAGS_EXTRA+=-DQSPI_PWR_CTRL_PORT=1 -DQSPI_PWR_CTRL_PIN=0
65+
66+
# Use UART0 on P0.22
67+
#CFLAGS_EXTRA+=-DUART_PORT=0 -DUART_PIN=22
68+
69+
#CFLAGS_EXTRA+=-DDEBUG_FLASH
70+
#CFLAGS_EXTRA+=-DDEBUG_QSPI=1
71+
72+
# Hard fault debugging
73+
#CFLAGS_EXTRA+=-DDEBUG_HARDFAULT

docs/Targets.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2425,7 +2425,7 @@ c
24252425
NXP MCXW716 is a Cortex-M33 microcontroller running at 96MHz.
24262426
The support has been tested using FRDM-MCXW716 with the onboard MCU-Link configured in JLink mode.
24272427

2428-
This requires the MCXW SDK from the NXP MCUXpresso SDK Builder. We tested using [mcux-sdk](https://github.com/nxp-mcuxpresso/mcux-sdk) and [CMSIS_5](https://github.com/nxp-mcuxpresso/CMSIS_5)`
2428+
This requires the MCXW SDK from the NXP MCUXpresso SDK Builder. We tested using [mcux-sdk](https://github.com/nxp-mcuxpresso/mcux-sdk) and [CMSIS_5](https://github.com/nxp-mcuxpresso/CMSIS_5)
24292429
placed under "../NXP". Adjust the MCUXPRESSO and MCUXPRESSO_CMSIS variables in your .config file according to your paths.
24302430

24312431
### MCX W: Configuring and compiling
@@ -2549,6 +2549,13 @@ Tested with the Nordic nRF5340-DK. This device has two cores:
25492549
1) Application core: Cortex-M33 at 128MHz, w/TrustZone, 1MB flash, 512KB RAM
25502550
2) Network core: Cortex-M33 at 64MHz, 256KB Flash and 64KB RAM
25512551
2552+
Three different configurations are available at `config/examples`:
2553+
- `nrf5340.config`: for the app core; does not make use of TrustZone, i.e. it
2554+
always runs in secure mode.
2555+
- `nrf5340-tz.config`: for the app core; makes use of TrustZone, i.e. boots the
2556+
application as non-secure code.
2557+
- `nrf5340_net.config`: for the net core.
2558+
25522559
The DK board has two virtual COM ports. Application core and Network core will each output to different VCOM ports.
25532560
The cores communicate firmware updates using shared memory hosted on application core.
25542561

hal/nrf5340-ns.ld

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
MEMORY
2+
{
3+
FLASH (rx) : ORIGIN = @ARCH_FLASH_OFFSET@, LENGTH = @BOOTLOADER_PARTITION_SIZE@
4+
FLASH_NET (rx) : ORIGIN = 0x01000000, LENGTH = 256K
5+
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
6+
}
7+
8+
SECTIONS
9+
{
10+
.text :
11+
{
12+
_start_text = .;
13+
KEEP(*(.isr_vector))
14+
*(.boot*)
15+
*(.text*)
16+
*(.rodata*)
17+
*(.init*)
18+
*(.fini*)
19+
. = ALIGN(4);
20+
_end_text = .;
21+
} > FLASH
22+
23+
.edidx :
24+
{
25+
. = ALIGN(4);
26+
*(.ARM.exidx*)
27+
} > FLASH
28+
29+
_stored_data = .;
30+
31+
.data : AT (_stored_data)
32+
{
33+
_start_data = .;
34+
KEEP(*(.data*))
35+
. = ALIGN(4);
36+
_end_data = .;
37+
} > RAM
38+
39+
.bss (NOLOAD) :
40+
{
41+
_start_bss = .;
42+
__bss_start__ = .;
43+
*(.bss*)
44+
*(COMMON)
45+
. = ALIGN(4);
46+
_end_bss = .;
47+
__bss_end__ = .;
48+
_end = .;
49+
} > RAM
50+
. = ALIGN(4);
51+
}
52+
53+
END_STACK = ORIGIN(RAM) + LENGTH(RAM);

hal/nrf5340.c

Lines changed: 94 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include "printf.h"
3030
#include "nrf5340.h"
3131
#include "spi_flash.h"
32+
#include "hal/armv8m_tz.h"
33+
#include "target.h"
3234

3335
/* TODO:
3436
* Key Storage: See 7.1.18.4.2 Key storage:
@@ -133,6 +135,50 @@ static SharedMem_t* shm = (SharedMem_t*)&shm_shadow;
133135
#endif
134136
#endif
135137

138+
#ifdef TZEN
139+
static void hal_spu_init(void) {
140+
uint8_t nsc_size_index;
141+
uint8_t region;
142+
uint8_t start_region;
143+
uint8_t end_region;
144+
145+
/* Make sure SAU is disabled, configure everything through SPU */
146+
SAU_CTRL = SAU_INIT_CTRL_ALLNS;
147+
148+
/* Flash: Non-Secure Callable */
149+
nsc_size_index = (WOLFBOOT_NSC_SIZE > 2048) ? 8 :
150+
(WOLFBOOT_NSC_SIZE > 1024) ? 7 :
151+
(WOLFBOOT_NSC_SIZE > 512) ? 6 :
152+
(WOLFBOOT_NSC_SIZE > 256) ? 5 :
153+
(WOLFBOOT_NSC_SIZE > 128) ? 4 :
154+
(WOLFBOOT_NSC_SIZE > 64) ? 3 :
155+
(WOLFBOOT_NSC_SIZE > 32) ? 2 :
156+
(WOLFBOOT_NSC_SIZE > 0) ? 1 : 0;
157+
158+
SPU_FLASHNSC_REGION(0) = ((WOLFBOOT_NSC_ADDRESS / SPU_FLASH_BLOCK_SIZE) &
159+
SPU_FLASHNSC_REGION_MASK) | SPU_FLASHNSC_REGION_LOCK;
160+
SPU_FLASHNSC_SIZE(0) = nsc_size_index | SPU_FLASHNSC_SIZE_LOCK;
161+
162+
/* Flash: non-secure application area */
163+
start_region = WOLFBOOT_PARTITION_BOOT_ADDRESS / SPU_FLASH_BLOCK_SIZE;
164+
end_region = (WOLFBOOT_PARTITION_BOOT_ADDRESS + WOLFBOOT_PARTITION_SIZE) / SPU_FLASH_BLOCK_SIZE;
165+
166+
for (region = start_region; region < end_region; region++) {
167+
SPU_FLASHREGION_PERM(region) = (SPU_FLASHREGION_PERM(region) &
168+
~SPU_FLASHREGION_PERM_SECATTR) | SPU_FLASHREGION_PERM_LOCK;
169+
}
170+
171+
/* RAM: non-secure application area */
172+
start_region = 0x20000 / SPU_RAM_BLOCK_SIZE;
173+
end_region = 0x24000 / SPU_RAM_BLOCK_SIZE;
174+
175+
for (region = start_region; region < end_region; region++) {
176+
SPU_RAMREGION_PERM(region) = (SPU_RAMREGION_PERM(region) &
177+
~SPU_RAMREGION_PERM_SECATTR) | SPU_RAMREGION_PERM_LOCK;
178+
}
179+
}
180+
#endif
181+
136182
void uart_init(void)
137183
{
138184
/* nRF5340-DK: (P0.20 or P1.01)
@@ -220,8 +266,9 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
220266
((((uint32_t)data) + i) & 0x03) == 0)) {
221267
src = (uint32_t *)data;
222268
dst = (uint32_t *)address;
223-
/* set both secure and non-secure registers */
269+
#if TZ_SECURE() || defined(TARGET_nrf5340_net)
224270
NVMC_CONFIG = NVMC_CONFIG_WEN;
271+
#endif
225272
NVMC_CONFIGNS = NVMC_CONFIG_WEN;
226273
while (NVMC_READY == 0);
227274
dst[i >> 2] = src[i >> 2];
@@ -234,8 +281,9 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
234281
dst = (uint32_t *)(address - off);
235282
val = dst[i >> 2];
236283
vbytes[off] = data[i];
237-
/* set both secure and non-secure registers */
284+
#if TZ_SECURE() || defined(TARGET_nrf5340_net)
238285
NVMC_CONFIG = NVMC_CONFIG_WEN;
286+
#endif
239287
NVMC_CONFIGNS = NVMC_CONFIG_WEN;
240288
while (NVMC_READY == 0);
241289
dst[i >> 2] = val;
@@ -257,7 +305,9 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
257305
address &= ~(FLASH_PAGE_SIZE-1);
258306
for (p = address; p <= end; p += FLASH_PAGE_SIZE) {
259307
/* set both secure and non-secure registers */
308+
#if TZ_SECURE() || defined(TARGET_nrf5340_net)
260309
NVMC_CONFIG = NVMC_CONFIG_EEN;
310+
#endif
261311
NVMC_CONFIGNS = NVMC_CONFIG_EEN;
262312
while (NVMC_READY == 0);
263313
*(volatile uint32_t *)p = 0xFFFFFFFF;
@@ -716,6 +766,10 @@ void hal_init(void)
716766

717767
hal_net_check_version();
718768
#endif
769+
770+
#ifdef TZEN
771+
hal_spu_init();
772+
#endif
719773
}
720774

721775
#ifdef __WOLFBOOT
@@ -733,8 +787,8 @@ int hal_flash_protect(uint32_t start, uint32_t len)
733787
if (start + len > FLASH_SIZE)
734788
len = FLASH_SIZE - start;
735789

736-
region = (start / SPU_BLOCK_SIZE);
737-
n = (len / SPU_BLOCK_SIZE);
790+
region = (start / SPU_FLASH_BLOCK_SIZE);
791+
n = (len / SPU_FLASH_BLOCK_SIZE);
738792

739793
for (i = 0; i < n; i++) {
740794
/* do not allow write to this region and lock till next reset */
@@ -749,6 +803,28 @@ int hal_flash_protect(uint32_t start, uint32_t len)
749803
return 0;
750804
}
751805

806+
#ifdef TZEN
807+
static void periph_unsecure() {
808+
/* Unsecure both GPIO ports */
809+
SPU_PERIPHID_PERM(GPIO_PERIPHID) &= ~SPU_PERIPHID_PERM_SECATTR;
810+
SPU_GPIOPORT_PERM(0) = 0;
811+
SPU_GPIOPORT_PERM(1) = 0;
812+
813+
/* Assign LED2 GPIO pin to net core; cannot be done by app because MCUSEL
814+
* is only accessible from secure code */
815+
GPIO_PIN_CNF(0, 29) = (GPIO_CNF_OUT | GPIO_CNF_MCUSEL(1));
816+
817+
/* Unsecure UARTE0 */
818+
SPU_PERIPHID_PERM(SERIAL0_PERIPHID) &= ~SPU_PERIPHID_PERM_SECATTR;
819+
820+
/* Unsecure NVMC */
821+
SPU_PERIPHID_PERM(KMU_NVMC_PERIPHID) &= ~SPU_PERIPHID_PERM_SECATTR;
822+
823+
/* Unsecure RTC0 */
824+
SPU_PERIPHID_PERM(RTC0_PERIPHID) &= ~SPU_PERIPHID_PERM_SECATTR;
825+
}
826+
#endif
827+
752828
void hal_prepare_boot(void)
753829
{
754830
/* Write protect bootloader region of flash */
@@ -771,16 +847,28 @@ void hal_prepare_boot(void)
771847
#endif
772848

773849
#if defined(TARGET_nrf5340_app) && defined(NRF_SYNC_CORES)
774-
/* if core synchronization enabled,
775-
* then wait for update_done or do_boot (5 seconds, 30 for update) */
850+
/* If core synchronization enabled,
851+
* then wait for update_done or do_boot (5 seconds, 30 for update).
852+
* Longer wait in DEBUG mode because the net core boots much
853+
* slower. */
776854
wolfBoot_printf("Waiting for network core...\n");
855+
#ifndef DEBUG
777856
(void)hal_shm_status_wait(&shm->core.net,
778857
(SHARED_STATUS_UPDATE_DONE | SHARED_STATUS_DO_BOOT),
779858
doUpdateNet ? 30*1000 : 5*1000);
859+
#else
860+
(void)hal_shm_status_wait(&shm->core.net,
861+
(SHARED_STATUS_UPDATE_DONE | SHARED_STATUS_DO_BOOT),
862+
doUpdateNet ? 45*1000 : 20*1000);
863+
#endif
780864
#endif
781865
}
782866

783867
hal_shm_cleanup();
868+
869+
#ifdef TZEN
870+
periph_unsecure();
871+
#endif
784872
}
785873
#endif /* __WOLFBOOT */
786874

0 commit comments

Comments
 (0)