mirror of https://github.com/wolfSSL/wolfBoot.git
MCXW TrustZone support
parent
1bc325d940
commit
23ba33140e
|
|
@ -201,6 +201,12 @@ jobs:
|
|||
arch: arm
|
||||
config-file: ./config/examples/mcxw.config
|
||||
|
||||
nxp_mcxw_tz_test:
|
||||
uses: ./.github/workflows/test-build-mcux-sdk.yml
|
||||
with:
|
||||
arch: arm
|
||||
config-file: ./config/examples/mcxw-tz.config
|
||||
|
||||
raspi3_test:
|
||||
uses: ./.github/workflows/test-build.yml
|
||||
with:
|
||||
|
|
|
|||
3
arch.mk
3
arch.mk
|
|
@ -661,6 +661,9 @@ endif
|
|||
|
||||
ifeq ($(TARGET),mcxw)
|
||||
CORTEX_M33=1
|
||||
ifneq ($(TZEN),1)
|
||||
LSCRIPT_IN=hal/$(TARGET)-ns.ld
|
||||
endif
|
||||
CFLAGS+=\
|
||||
-I$(MCUXPRESSO_DRIVERS) \
|
||||
-I$(MCUXPRESSO_DRIVERS)/drivers \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
ARCH?=ARM
|
||||
TZEN?=1
|
||||
TARGET?=mcxw
|
||||
SIGN?=ECC256
|
||||
HASH?=SHA256
|
||||
MCUXSDK?=1
|
||||
MCUXPRESSO?=$(PWD)/../NXP/mcux-sdk
|
||||
MCUXPRESSO_CMSIS?=$(PWD)/../NXP/CMSIS_5/CMSIS
|
||||
MCUXPRESSO_CPU?=MCXW716CMFTA
|
||||
MCUXPRESSO_DRIVERS?=$(MCUXPRESSO)/devices/MCXW716C
|
||||
DEBUG?=0
|
||||
VTOR?=1
|
||||
CORTEX_M0?=0
|
||||
CORTEX_M33?=1
|
||||
NO_ASM?=0
|
||||
NO_MPU=1
|
||||
EXT_FLASH?=0
|
||||
SPI_FLASH?=0
|
||||
ALLOW_DOWNGRADE?=0
|
||||
NVM_FLASH_WRITEONCE?=1
|
||||
NO_ARM_ASM=1
|
||||
WOLFBOOT_VERSION?=0
|
||||
V?=0
|
||||
SPMATH?=1
|
||||
RAM_CODE?=1
|
||||
DUALBANK_SWAP?=0
|
||||
PKA?=1
|
||||
|
||||
# 8KB sectors
|
||||
WOLFBOOT_SECTOR_SIZE?=0x2000
|
||||
|
||||
# Default configuration
|
||||
# 32KB boot, 80KB keyvault, 16KB NSC, 60KB partitions, 8KB swap
|
||||
WOLFBOOT_KEYVAULT_ADDRESS?=0x8000
|
||||
WOLFBOOT_KEYVAULT_SIZE?=0x14000
|
||||
WOLFBOOT_NSC_ADDRESS?=0x1C000
|
||||
WOLFBOOT_NSC_SIZE?=0x4000
|
||||
WOLFBOOT_PARTITION_SIZE?=0xF000
|
||||
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x20000
|
||||
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x2F000
|
||||
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x3E000
|
||||
|
||||
# Alternate larger configuration for debugging or ARMASM
|
||||
# 40KB boot, 80KB keyvault, 8KB NSC, 60KB partitions, 8KB swap
|
||||
#WOLFBOOT_KEYVAULT_ADDRESS?=0xA000
|
||||
#WOLFBOOT_KEYVAULT_SIZE?=0x14000
|
||||
#WOLFBOOT_NSC_ADDRESS?=0x1E000
|
||||
#WOLFBOOT_NSC_SIZE?=0x2000
|
||||
#WOLFBOOT_PARTITION_SIZE?=0xF000
|
||||
#WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x20000
|
||||
#WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x2F000
|
||||
#WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x3E000
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 24K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
.text :
|
||||
{
|
||||
_start_text = .;
|
||||
KEEP(*(.isr_vector))
|
||||
. = 0x200;
|
||||
*(.keystore*)
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
*(.init*)
|
||||
*(.fini*)
|
||||
. = ALIGN(4);
|
||||
_end_text = .;
|
||||
} > FLASH
|
||||
|
||||
.edidx :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.ARM.exidx*)
|
||||
} > FLASH
|
||||
|
||||
_stored_data = .;
|
||||
|
||||
.data : AT (_stored_data)
|
||||
{
|
||||
_start_data = .;
|
||||
KEEP(*(.data*))
|
||||
. = ALIGN(4);
|
||||
_end_data = .;
|
||||
} > RAM
|
||||
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
_start_bss = .;
|
||||
__bss_start__ = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_end_bss = .;
|
||||
__bss_end__ = .;
|
||||
_end = .;
|
||||
} > RAM
|
||||
. = ALIGN(4);
|
||||
}
|
||||
|
||||
END_STACK = ORIGIN(RAM) + LENGTH(RAM);
|
||||
133
hal/mcxw.c
133
hal/mcxw.c
|
|
@ -37,6 +37,8 @@
|
|||
#include "fsl_flash_api.h"
|
||||
#include "fsl_ccm32k.h"
|
||||
|
||||
#include "hal/armv8m_tz.h"
|
||||
|
||||
#define FLASH FMU0
|
||||
|
||||
/*!< Core clock frequency: 48000000Hz */
|
||||
|
|
@ -46,6 +48,41 @@ static uint32_t pflash_sector_size = WOLFBOOT_SECTOR_SIZE;
|
|||
|
||||
uint32_t SystemCoreClock;
|
||||
|
||||
#ifdef TZEN
|
||||
static void hal_sau_init(void)
|
||||
{
|
||||
/* Non-secure callable area */
|
||||
sau_init_region(0, WOLFBOOT_NSC_ADDRESS,
|
||||
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);
|
||||
|
||||
/* ROM bootloader API */
|
||||
sau_init_region(2, 0x14800000, 0x14817FFF, 0);
|
||||
|
||||
/* Non-secure RAM */
|
||||
sau_init_region(3, 0x20010000, 0x20015FFF, 0);
|
||||
|
||||
/* Peripherals */
|
||||
sau_init_region(4, 0x40000000, 0x4007FFFF, 0);
|
||||
sau_init_region(5, 0x48000000, 0x48FFFFFF, 0);
|
||||
|
||||
/* Enable SAU */
|
||||
SAU_CTRL = SAU_INIT_CTRL_ENABLE;
|
||||
|
||||
/* Enable securefault handler */
|
||||
SCB_SHCSR |= SCB_SHCSR_SECUREFAULT_EN;
|
||||
}
|
||||
|
||||
static void periph_unsecure(void)
|
||||
{
|
||||
GPIOA->PCNS = 0xFFFFFFFF;
|
||||
GPIOA->ICNS = 0xFFFFFFFF;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __WOLFBOOT
|
||||
|
||||
|
|
@ -63,7 +100,9 @@ void __assert_func(const char *a, int b, const char *c, const char *d)
|
|||
|
||||
void hal_prepare_boot(void)
|
||||
{
|
||||
|
||||
#ifdef TZEN
|
||||
periph_unsecure();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -80,11 +119,39 @@ void hal_init(void)
|
|||
FLASH_Init(&pflash);
|
||||
FLASH_GetProperty(&pflash, kFLASH_PropertyPflash0SectorSize,
|
||||
&pflash_sector_size);
|
||||
|
||||
#if defined(TZEN) && !defined(NONSECURE_APP)
|
||||
hal_sau_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void write_flash_qword(uint32_t *dst, const uint32_t *src)
|
||||
{
|
||||
/* Wait for non-busy */
|
||||
while (!(FMU0->FSTAT & 0x00000080)) {}
|
||||
/* Clear errors */
|
||||
FMU0->FSTAT = 0x74;
|
||||
/* Set command "program phrase" */
|
||||
FMU0->FCCOB[0] = 0x24;
|
||||
/* Start command */
|
||||
FMU0->FSTAT = 0x80;
|
||||
/* Wait for write enabled */
|
||||
while (!(FMU0->FSTAT & 0x01000000)) {}
|
||||
/* Write the 4 words */
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
dst[3] = src[3];
|
||||
/* Wait for operation ready to execute */
|
||||
while (!(FMU0->FSTAT & 0x80000000)) {}
|
||||
/* Start operation */
|
||||
FMU0->FSTAT = 0x80000000;
|
||||
/* Wait for completion */
|
||||
while (!(FMU0->FSTAT & 0x00000080)) {}
|
||||
}
|
||||
|
||||
int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
|
||||
{
|
||||
int ret;
|
||||
int w = 0;
|
||||
const uint32_t flash_word_size = 16;
|
||||
const uint32_t empty_qword[4] = {
|
||||
|
|
@ -103,33 +170,24 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
|
|||
((uint8_t *)aligned_qword)[i] = data[w++];
|
||||
}
|
||||
if (memcmp(aligned_qword, empty_qword, flash_word_size) != 0) {
|
||||
ret = FLASH_Program(&pflash, FLASH, address_align, aligned_qword,
|
||||
flash_word_size);
|
||||
if (ret != kStatus_Success)
|
||||
return -1;
|
||||
write_flash_qword((uint32_t *)address_align, aligned_qword);
|
||||
}
|
||||
address += i;
|
||||
len -= i;
|
||||
}
|
||||
else {
|
||||
uint32_t i;
|
||||
uint32_t len_align = len - (len & 0x0F);
|
||||
if (((uint32_t)data + w) & 0x0F) {
|
||||
uint32_t __attribute__((aligned(16))) aligned_data[4];
|
||||
memcpy(aligned_data, (void*)((uint32_t)data + w), len_align);
|
||||
ret = FLASH_Program(&pflash, FLASH, address, (uint32_t*)data + w,
|
||||
len_align);
|
||||
|
||||
for (i = 0; i < len_align; i += 16) {
|
||||
write_flash_qword((uint32_t *)(address + i),
|
||||
(const uint32_t *)(data + w + i));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = FLASH_Program(&pflash, FLASH, address, (uint32_t*)data + w,
|
||||
len_align);
|
||||
}
|
||||
if (ret != kStatus_Success)
|
||||
return -1;
|
||||
len -= len_align;
|
||||
address += len_align;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -141,23 +199,38 @@ void RAMFUNCTION hal_flash_lock(void)
|
|||
{
|
||||
}
|
||||
|
||||
static void erase_flash_sector(uint32_t *dst) {
|
||||
/* Wait for non-busy */
|
||||
while (!(FMU0->FSTAT & 0x00000080)) {}
|
||||
/* Clear errors */
|
||||
FMU0->FSTAT = 0x74;
|
||||
/* Set command "erase sector" */
|
||||
FMU0->FCCOB[0] = 0x42;
|
||||
/* Start command */
|
||||
FMU0->FSTAT = 0x80;
|
||||
/* Wait for write enabled */
|
||||
while (!(FMU0->FSTAT & 0x01000000)) {}
|
||||
/* Write 4 words to specify sector to erase */
|
||||
dst[0] = 0;
|
||||
dst[1] = 0;
|
||||
dst[2] = 0;
|
||||
dst[3] = 0;
|
||||
/* Wait for operation ready to execute */
|
||||
while (!(FMU0->FSTAT & 0x80000000)) {}
|
||||
/* Start operation */
|
||||
FMU0->FSTAT = 0x80000000;
|
||||
/* Wait for completion */
|
||||
while (!(FMU0->FSTAT & 0x00000080)) {}
|
||||
}
|
||||
|
||||
int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
|
||||
{
|
||||
status_t result;
|
||||
if (address % pflash_sector_size)
|
||||
address -= address % pflash_sector_size;
|
||||
while (len > 0) {
|
||||
result = FLASH_Erase(&pflash, FLASH, address, pflash_sector_size,
|
||||
kFLASH_ApiEraseKey);
|
||||
if (kStatus_FLASH_Success != result)
|
||||
return -1;
|
||||
|
||||
/* Verify sector if it's been erased. */
|
||||
result = FLASH_VerifyEraseSector(&pflash, FLASH, address,
|
||||
pflash_sector_size);
|
||||
if (kStatus_FLASH_Success != result)
|
||||
return -1;
|
||||
len -= pflash_sector_size;
|
||||
erase_flash_sector((uint32_t *)address);
|
||||
address += WOLFBOOT_SECTOR_SIZE;
|
||||
len -= WOLFBOOT_SECTOR_SIZE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
129
hal/mcxw.ld
129
hal/mcxw.ld
|
|
@ -1,54 +1,75 @@
|
|||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 24K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
.text :
|
||||
{
|
||||
_start_text = .;
|
||||
KEEP(*(.isr_vector))
|
||||
. = 0x200;
|
||||
*(.keystore*)
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
*(.init*)
|
||||
*(.fini*)
|
||||
. = ALIGN(4);
|
||||
_end_text = .;
|
||||
} > FLASH
|
||||
|
||||
.edidx :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.ARM.exidx*)
|
||||
} > FLASH
|
||||
|
||||
_stored_data = .;
|
||||
|
||||
.data : AT (_stored_data)
|
||||
{
|
||||
_start_data = .;
|
||||
KEEP(*(.data*))
|
||||
. = ALIGN(4);
|
||||
_end_data = .;
|
||||
} > RAM
|
||||
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
_start_bss = .;
|
||||
__bss_start__ = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_end_bss = .;
|
||||
__bss_end__ = .;
|
||||
_end = .;
|
||||
} > RAM
|
||||
. = ALIGN(4);
|
||||
}
|
||||
|
||||
END_STACK = ORIGIN(RAM) + LENGTH(RAM);
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = @WOLFBOOT_KEYVAULT_ADDRESS@ - @ARCH_FLASH_OFFSET@
|
||||
RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 0x6000 /* 24K */
|
||||
RAM_HEAP (rwx) : ORIGIN = 0x30006000, LENGTH = 0x6000 /* 24K */
|
||||
RAM_KV (rwx) : ORIGIN = 0x3000C000, LENGTH = 0x2000 /* 8K */
|
||||
FLASH_KEYVAULT (rw) : ORIGIN = @WOLFBOOT_KEYVAULT_ADDRESS@, LENGTH = @WOLFBOOT_KEYVAULT_SIZE@
|
||||
FLASH_NSC (rx) : ORIGIN = @WOLFBOOT_NSC_ADDRESS@, LENGTH = @WOLFBOOT_NSC_SIZE@
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
.text :
|
||||
{
|
||||
_start_text = .;
|
||||
KEEP(*(.isr_vector))
|
||||
. = 0x200;
|
||||
*(.keystore*)
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
*(.init*)
|
||||
*(.fini*)
|
||||
. = ALIGN(4);
|
||||
_end_text = .;
|
||||
} > FLASH
|
||||
|
||||
.edidx :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.ARM.exidx*)
|
||||
} > FLASH
|
||||
|
||||
.gnu.sgstubs :
|
||||
{
|
||||
. += 0x400;
|
||||
. = ALIGN(4);
|
||||
*(.gnu.sgstubs*) /* Secure Gateway Stubs */
|
||||
. = ALIGN(4);
|
||||
} > FLASH_NSC
|
||||
|
||||
_stored_data = .;
|
||||
|
||||
.data : AT (_stored_data)
|
||||
{
|
||||
_start_data = .;
|
||||
KEEP(*(.data*))
|
||||
. = ALIGN(4);
|
||||
_end_data = .;
|
||||
} > RAM
|
||||
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
_start_bss = .;
|
||||
__bss_start__ = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_end_bss = .;
|
||||
__bss_end__ = .;
|
||||
_end = .;
|
||||
} > RAM
|
||||
. = ALIGN(4);
|
||||
}
|
||||
|
||||
END_STACK = ORIGIN(RAM) + LENGTH(RAM);
|
||||
|
||||
_keyvault_origin = ORIGIN(RAM_KV);
|
||||
_keyvault_size = LENGTH(RAM_KV);
|
||||
|
||||
_flash_keyvault = ORIGIN(FLASH_KEYVAULT);
|
||||
_flash_keyvault_size = LENGTH(FLASH_KEYVAULT);
|
||||
|
||||
_start_heap = ORIGIN(RAM_HEAP);
|
||||
_heap_size = LENGTH(RAM_HEAP);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@
|
||||
RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 24K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
_start_text = .;
|
||||
KEEP(*(.isr_vector))
|
||||
*(.init)
|
||||
*(.fini)
|
||||
*(.text*)
|
||||
KEEP(*(.rodata*))
|
||||
. = ALIGN(4);
|
||||
_end_text = .;
|
||||
} > FLASH
|
||||
|
||||
.ARM :
|
||||
{
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} > FLASH
|
||||
|
||||
_stored_data = .;
|
||||
|
||||
.data : AT (_stored_data)
|
||||
{
|
||||
_start_data = .;
|
||||
KEEP(*(.data*))
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.ramcode))
|
||||
. = ALIGN(4);
|
||||
_end_data = .;
|
||||
} > RAM
|
||||
|
||||
.bss :
|
||||
{
|
||||
_start_bss = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_end_bss = .;
|
||||
_end = .;
|
||||
} > RAM
|
||||
}
|
||||
|
||||
_wolfboot_partition_boot_address = @WOLFBOOT_PARTITION_BOOT_ADDRESS@;
|
||||
_wolfboot_partition_size = @WOLFBOOT_PARTITION_SIZE@;
|
||||
_wolfboot_partition_update_address = @WOLFBOOT_PARTITION_UPDATE_ADDRESS@;
|
||||
_wolfboot_partition_swap_address = @WOLFBOOT_PARTITION_SWAP_ADDRESS@;
|
||||
|
||||
PROVIDE(_start_heap = _end);
|
||||
PROVIDE(end = _end);
|
||||
PROVIDE(_end_stack = ORIGIN(RAM) + LENGTH(RAM));
|
||||
|
|
@ -348,7 +348,12 @@ ifeq ($(TARGET),mcxa)
|
|||
endif
|
||||
|
||||
ifeq ($(TARGET),mcxw)
|
||||
LSCRIPT_TEMPLATE=ARM-mcxw.ld
|
||||
ifeq ($(TZEN),1)
|
||||
LSCRIPT_TEMPLATE=ARM-mcxw-ns.ld
|
||||
CFLAGS:=$(filter-out -mcmse, $(CFLAGS))
|
||||
else
|
||||
LSCRIPT_TEMPLATE=ARM-mcxw.ld
|
||||
endif
|
||||
APP_OBJS+=$(MCUXPRESSO_DRIVERS)/drivers/fsl_clock.o
|
||||
APP_OBJS+=$(MCUXPRESSO)/drivers/gpio/fsl_gpio.o
|
||||
APP_OBJS+=$(MCUXPRESSO)/drivers/spc/fsl_spc.o
|
||||
|
|
|
|||
|
|
@ -75,17 +75,16 @@ void main(void)
|
|||
gpio_portA_init(19);
|
||||
gpio_portA_init(20);
|
||||
|
||||
hal_init();
|
||||
if (bootVer == 1) {
|
||||
wolfBoot_update_trigger();
|
||||
/* Blue LED ON, GPIOA port A pin 20 */
|
||||
GPIO_PinWrite(GPIOA, 20, 0);
|
||||
wolfBoot_update_trigger();
|
||||
}
|
||||
else {
|
||||
/* Green LED ON, GPIOA port A pin 19 */
|
||||
GPIO_PinWrite(GPIOA, 19, 0);
|
||||
/* mark boot successful */
|
||||
wolfBoot_success();
|
||||
/* Green LED ON, GPIOA port A pin 19 */
|
||||
GPIO_PinWrite(GPIOA, 19, 0);
|
||||
}
|
||||
|
||||
/* busy wait */
|
||||
|
|
|
|||
Loading…
Reference in New Issue