Skip to content

Commit 97230f5

Browse files
authored
Merge pull request #646 from mattia-moffa/20251125-nxp-mcxw71-tz
MCXW TrustZone support
2 parents 1bc325d + 23ba331 commit 97230f5

File tree

9 files changed

+360
-89
lines changed

9 files changed

+360
-89
lines changed

.github/workflows/test-configs.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,12 @@ jobs:
201201
arch: arm
202202
config-file: ./config/examples/mcxw.config
203203

204+
nxp_mcxw_tz_test:
205+
uses: ./.github/workflows/test-build-mcux-sdk.yml
206+
with:
207+
arch: arm
208+
config-file: ./config/examples/mcxw-tz.config
209+
204210
raspi3_test:
205211
uses: ./.github/workflows/test-build.yml
206212
with:

arch.mk

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,9 @@ endif
661661

662662
ifeq ($(TARGET),mcxw)
663663
CORTEX_M33=1
664+
ifneq ($(TZEN),1)
665+
LSCRIPT_IN=hal/$(TARGET)-ns.ld
666+
endif
664667
CFLAGS+=\
665668
-I$(MCUXPRESSO_DRIVERS) \
666669
-I$(MCUXPRESSO_DRIVERS)/drivers \

config/examples/mcxw-tz.config

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
ARCH?=ARM
2+
TZEN?=1
3+
TARGET?=mcxw
4+
SIGN?=ECC256
5+
HASH?=SHA256
6+
MCUXSDK?=1
7+
MCUXPRESSO?=$(PWD)/../NXP/mcux-sdk
8+
MCUXPRESSO_CMSIS?=$(PWD)/../NXP/CMSIS_5/CMSIS
9+
MCUXPRESSO_CPU?=MCXW716CMFTA
10+
MCUXPRESSO_DRIVERS?=$(MCUXPRESSO)/devices/MCXW716C
11+
DEBUG?=0
12+
VTOR?=1
13+
CORTEX_M0?=0
14+
CORTEX_M33?=1
15+
NO_ASM?=0
16+
NO_MPU=1
17+
EXT_FLASH?=0
18+
SPI_FLASH?=0
19+
ALLOW_DOWNGRADE?=0
20+
NVM_FLASH_WRITEONCE?=1
21+
NO_ARM_ASM=1
22+
WOLFBOOT_VERSION?=0
23+
V?=0
24+
SPMATH?=1
25+
RAM_CODE?=1
26+
DUALBANK_SWAP?=0
27+
PKA?=1
28+
29+
# 8KB sectors
30+
WOLFBOOT_SECTOR_SIZE?=0x2000
31+
32+
# Default configuration
33+
# 32KB boot, 80KB keyvault, 16KB NSC, 60KB partitions, 8KB swap
34+
WOLFBOOT_KEYVAULT_ADDRESS?=0x8000
35+
WOLFBOOT_KEYVAULT_SIZE?=0x14000
36+
WOLFBOOT_NSC_ADDRESS?=0x1C000
37+
WOLFBOOT_NSC_SIZE?=0x4000
38+
WOLFBOOT_PARTITION_SIZE?=0xF000
39+
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x20000
40+
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x2F000
41+
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x3E000
42+
43+
# Alternate larger configuration for debugging or ARMASM
44+
# 40KB boot, 80KB keyvault, 8KB NSC, 60KB partitions, 8KB swap
45+
#WOLFBOOT_KEYVAULT_ADDRESS?=0xA000
46+
#WOLFBOOT_KEYVAULT_SIZE?=0x14000
47+
#WOLFBOOT_NSC_ADDRESS?=0x1E000
48+
#WOLFBOOT_NSC_SIZE?=0x2000
49+
#WOLFBOOT_PARTITION_SIZE?=0xF000
50+
#WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x20000
51+
#WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x2F000
52+
#WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x3E000

hal/mcxw-ns.ld

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

hal/mcxw.c

Lines changed: 103 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
#include "fsl_flash_api.h"
3838
#include "fsl_ccm32k.h"
3939

40+
#include "hal/armv8m_tz.h"
41+
4042
#define FLASH FMU0
4143

4244
/*!< Core clock frequency: 48000000Hz */
@@ -46,6 +48,41 @@ static uint32_t pflash_sector_size = WOLFBOOT_SECTOR_SIZE;
4648

4749
uint32_t SystemCoreClock;
4850

51+
#ifdef TZEN
52+
static void hal_sau_init(void)
53+
{
54+
/* Non-secure callable area */
55+
sau_init_region(0, WOLFBOOT_NSC_ADDRESS,
56+
WOLFBOOT_NSC_ADDRESS + WOLFBOOT_NSC_SIZE - 1, 1);
57+
58+
/* Non-secure: application flash area */
59+
sau_init_region(1, WOLFBOOT_PARTITION_BOOT_ADDRESS,
60+
WOLFBOOT_PARTITION_BOOT_ADDRESS + 2 * WOLFBOOT_PARTITION_SIZE - 1,
61+
0);
62+
63+
/* ROM bootloader API */
64+
sau_init_region(2, 0x14800000, 0x14817FFF, 0);
65+
66+
/* Non-secure RAM */
67+
sau_init_region(3, 0x20010000, 0x20015FFF, 0);
68+
69+
/* Peripherals */
70+
sau_init_region(4, 0x40000000, 0x4007FFFF, 0);
71+
sau_init_region(5, 0x48000000, 0x48FFFFFF, 0);
72+
73+
/* Enable SAU */
74+
SAU_CTRL = SAU_INIT_CTRL_ENABLE;
75+
76+
/* Enable securefault handler */
77+
SCB_SHCSR |= SCB_SHCSR_SECUREFAULT_EN;
78+
}
79+
80+
static void periph_unsecure(void)
81+
{
82+
GPIOA->PCNS = 0xFFFFFFFF;
83+
GPIOA->ICNS = 0xFFFFFFFF;
84+
}
85+
#endif
4986

5087
#ifdef __WOLFBOOT
5188

@@ -63,7 +100,9 @@ void __assert_func(const char *a, int b, const char *c, const char *d)
63100

64101
void hal_prepare_boot(void)
65102
{
66-
103+
#ifdef TZEN
104+
periph_unsecure();
105+
#endif
67106
}
68107

69108
#endif
@@ -80,11 +119,39 @@ void hal_init(void)
80119
FLASH_Init(&pflash);
81120
FLASH_GetProperty(&pflash, kFLASH_PropertyPflash0SectorSize,
82121
&pflash_sector_size);
122+
123+
#if defined(TZEN) && !defined(NONSECURE_APP)
124+
hal_sau_init();
125+
#endif
126+
}
127+
128+
static void write_flash_qword(uint32_t *dst, const uint32_t *src)
129+
{
130+
/* Wait for non-busy */
131+
while (!(FMU0->FSTAT & 0x00000080)) {}
132+
/* Clear errors */
133+
FMU0->FSTAT = 0x74;
134+
/* Set command "program phrase" */
135+
FMU0->FCCOB[0] = 0x24;
136+
/* Start command */
137+
FMU0->FSTAT = 0x80;
138+
/* Wait for write enabled */
139+
while (!(FMU0->FSTAT & 0x01000000)) {}
140+
/* Write the 4 words */
141+
dst[0] = src[0];
142+
dst[1] = src[1];
143+
dst[2] = src[2];
144+
dst[3] = src[3];
145+
/* Wait for operation ready to execute */
146+
while (!(FMU0->FSTAT & 0x80000000)) {}
147+
/* Start operation */
148+
FMU0->FSTAT = 0x80000000;
149+
/* Wait for completion */
150+
while (!(FMU0->FSTAT & 0x00000080)) {}
83151
}
84152

85153
int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
86154
{
87-
int ret;
88155
int w = 0;
89156
const uint32_t flash_word_size = 16;
90157
const uint32_t empty_qword[4] = {
@@ -103,33 +170,24 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
103170
((uint8_t *)aligned_qword)[i] = data[w++];
104171
}
105172
if (memcmp(aligned_qword, empty_qword, flash_word_size) != 0) {
106-
ret = FLASH_Program(&pflash, FLASH, address_align, aligned_qword,
107-
flash_word_size);
108-
if (ret != kStatus_Success)
109-
return -1;
173+
write_flash_qword((uint32_t *)address_align, aligned_qword);
110174
}
111175
address += i;
112176
len -= i;
113177
}
114178
else {
179+
uint32_t i;
115180
uint32_t len_align = len - (len & 0x0F);
116-
if (((uint32_t)data + w) & 0x0F) {
117-
uint32_t __attribute__((aligned(16))) aligned_data[4];
118-
memcpy(aligned_data, (void*)((uint32_t)data + w), len_align);
119-
ret = FLASH_Program(&pflash, FLASH, address, (uint32_t*)data + w,
120-
len_align);
121-
}
122-
else
123-
{
124-
ret = FLASH_Program(&pflash, FLASH, address, (uint32_t*)data + w,
125-
len_align);
181+
182+
for (i = 0; i < len_align; i += 16) {
183+
write_flash_qword((uint32_t *)(address + i),
184+
(const uint32_t *)(data + w + i));
126185
}
127-
if (ret != kStatus_Success)
128-
return -1;
129186
len -= len_align;
130187
address += len_align;
131188
}
132189
}
190+
133191
return 0;
134192
}
135193

@@ -141,23 +199,38 @@ void RAMFUNCTION hal_flash_lock(void)
141199
{
142200
}
143201

202+
static void erase_flash_sector(uint32_t *dst) {
203+
/* Wait for non-busy */
204+
while (!(FMU0->FSTAT & 0x00000080)) {}
205+
/* Clear errors */
206+
FMU0->FSTAT = 0x74;
207+
/* Set command "erase sector" */
208+
FMU0->FCCOB[0] = 0x42;
209+
/* Start command */
210+
FMU0->FSTAT = 0x80;
211+
/* Wait for write enabled */
212+
while (!(FMU0->FSTAT & 0x01000000)) {}
213+
/* Write 4 words to specify sector to erase */
214+
dst[0] = 0;
215+
dst[1] = 0;
216+
dst[2] = 0;
217+
dst[3] = 0;
218+
/* Wait for operation ready to execute */
219+
while (!(FMU0->FSTAT & 0x80000000)) {}
220+
/* Start operation */
221+
FMU0->FSTAT = 0x80000000;
222+
/* Wait for completion */
223+
while (!(FMU0->FSTAT & 0x00000080)) {}
224+
}
225+
144226
int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
145227
{
146-
status_t result;
147228
if (address % pflash_sector_size)
148229
address -= address % pflash_sector_size;
149230
while (len > 0) {
150-
result = FLASH_Erase(&pflash, FLASH, address, pflash_sector_size,
151-
kFLASH_ApiEraseKey);
152-
if (kStatus_FLASH_Success != result)
153-
return -1;
154-
155-
/* Verify sector if it's been erased. */
156-
result = FLASH_VerifyEraseSector(&pflash, FLASH, address,
157-
pflash_sector_size);
158-
if (kStatus_FLASH_Success != result)
159-
return -1;
160-
len -= pflash_sector_size;
231+
erase_flash_sector((uint32_t *)address);
232+
address += WOLFBOOT_SECTOR_SIZE;
233+
len -= WOLFBOOT_SECTOR_SIZE;
161234
}
162235
return 0;
163236
}

0 commit comments

Comments
 (0)