mirror of https://github.com/wolfSSL/wolfBoot.git
MCXN non-TrustZone + TrustZone port
parent
472cab64ae
commit
438c250288
|
|
@ -390,6 +390,7 @@ if(NOT DEFINED ARM_TARGETS)
|
|||
lpc54606j512
|
||||
mcxa
|
||||
mcxw
|
||||
mcxn
|
||||
nrf52
|
||||
nrf52840
|
||||
nrf5340
|
||||
|
|
|
|||
39
arch.mk
39
arch.mk
|
|
@ -339,7 +339,7 @@ else
|
|||
ifeq ($(WOLFCRYPT_TZ),1)
|
||||
CORTEXM_ARM_EXTRA_OBJS=
|
||||
CORTEXM_ARM_EXTRA_CFLAGS=
|
||||
SECURE_OBJS+=./src/wc_callable.o
|
||||
SECURE_OBJS+=./src/wc_callable.o $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/random.o
|
||||
CFLAGS+=-DWOLFCRYPT_SECURE_MODE
|
||||
SECURE_LDFLAGS+=-Wl,--cmse-implib -Wl,--out-implib=./src/wc_secure_calls.o
|
||||
endif
|
||||
|
|
@ -732,6 +732,43 @@ ifeq ($(TARGET),mcxw)
|
|||
$(MCUXPRESSO_DRIVERS)/drivers/fsl_romapi.o
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),mcxn)
|
||||
CORTEX_M33=1
|
||||
ifneq ($(TZEN),1)
|
||||
LSCRIPT_IN=hal/$(TARGET)-ns.ld
|
||||
endif
|
||||
CFLAGS+=\
|
||||
-I$(MCUXPRESSO_DRIVERS) \
|
||||
-I$(MCUXPRESSO_DRIVERS)/drivers \
|
||||
-I$(MCUXPRESSO_DRIVERS)/drivers/romapi/flash \
|
||||
-I$(MCUXPRESSO_DRIVERS)/../periph \
|
||||
-I$(MCUXPRESSO) \
|
||||
-I$(MCUXPRESSO)/drivers \
|
||||
-I$(MCUXPRESSO)/drivers/gpio \
|
||||
-I$(MCUXPRESSO)/drivers/port \
|
||||
-I$(MCUXPRESSO)/drivers/common \
|
||||
-I$(MCUXPRESSO)/drivers/lpflexcomm \
|
||||
-I$(MCUXPRESSO)/drivers/lpuart \
|
||||
-I$(MCUXPRESSO_PROJECT_TEMPLATE) \
|
||||
-I$(MCUXPRESSO_CMSIS)/Include \
|
||||
-I$(MCUXPRESSO_CMSIS)/Core/Include
|
||||
CFLAGS+=-DCPU_$(MCUXPRESSO_CPU) -DDEBUG_CONSOLE_ASSERT_DISABLE=1
|
||||
CFLAGS+=-Wno-old-style-declaration
|
||||
CFLAGS+=-mcpu=cortex-m33 -DCORTEX_M33 -U__ARM_FEATURE_DSP
|
||||
LDFLAGS+=-mcpu=cortex-m33
|
||||
OBJS+=\
|
||||
$(MCUXPRESSO_DRIVERS)/drivers/fsl_clock.o \
|
||||
$(MCUXPRESSO_PROJECT_TEMPLATE)/clock_config.o \
|
||||
$(MCUXPRESSO_DRIVERS)/drivers/romapi/flash/src/fsl_flash.o
|
||||
|
||||
ifeq ($(DEBUG_UART),1)
|
||||
OBJS+=\
|
||||
$(MCUXPRESSO)/drivers/lpflexcomm/fsl_lpflexcomm.o \
|
||||
$(MCUXPRESSO)/drivers/lpuart/fsl_lpuart.o \
|
||||
$(MCUXPRESSO_DRIVERS)/drivers/fsl_reset.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),nrf5340)
|
||||
ifneq ($(TZEN), 1)
|
||||
LSCRIPT_IN=hal/$(TARGET)-ns.ld
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
ARCH?=ARM
|
||||
TZEN?=1
|
||||
TARGET?=mcxn
|
||||
SIGN?=ECC384
|
||||
HASH?=SHA384
|
||||
MCUXSDK?=1
|
||||
MCUXPRESSO?=$(PWD)/../NXP/mcuxsdk/mcuxsdk
|
||||
MCUXPRESSO_CMSIS?=$(PWD)/../NXP/CMSIS_5/CMSIS
|
||||
MCUXPRESSO_CPU?=MCXN947VDF_cm33_core0
|
||||
MCUXPRESSO_DRIVERS?=$(MCUXPRESSO)/devices/MCX/MCXN/MCXN947
|
||||
MCUXPRESSO_PROJECT_TEMPLATE?=$(MCUXPRESSO)/examples/_boards/frdmmcxn947/project_template
|
||||
DEBUG?=0
|
||||
DEBUG_UART?=1
|
||||
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
|
||||
WOLFCRYPT_TZ?=1
|
||||
|
||||
# 8KB sectors
|
||||
WOLFBOOT_SECTOR_SIZE?=0x2000
|
||||
|
||||
# Default configuration
|
||||
# 64KB boot, 80KB keyvault, 8KB NSC, 60KB partitions, 8KB swap
|
||||
WOLFBOOT_KEYVAULT_ADDRESS?=0x10000
|
||||
WOLFBOOT_KEYVAULT_SIZE?=0x14000
|
||||
WOLFBOOT_NSC_ADDRESS?=0x24000
|
||||
WOLFBOOT_NSC_SIZE?=0x2000
|
||||
WOLFBOOT_PARTITION_SIZE?=0xF000
|
||||
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x26000
|
||||
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x35000
|
||||
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x44000
|
||||
|
||||
# Alternate larger configuration for debugging or ARMASM
|
||||
# 128KB boot, 80KB keyvault, 8KB NSC, 60KB partitions, 8KB swap
|
||||
#WOLFBOOT_KEYVAULT_ADDRESS?=0x20000
|
||||
#WOLFBOOT_KEYVAULT_SIZE?=0x14000
|
||||
#WOLFBOOT_NSC_ADDRESS?=0x34000
|
||||
#WOLFBOOT_NSC_SIZE?=0x2000
|
||||
#WOLFBOOT_PARTITION_SIZE?=0xF000
|
||||
#WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x36000
|
||||
#WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x45000
|
||||
#WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x54000
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
ARCH?=ARM
|
||||
TZEN?=0
|
||||
TARGET?=mcxn
|
||||
SIGN?=ECC384
|
||||
HASH?=SHA384
|
||||
MCUXSDK?=1
|
||||
MCUXPRESSO?=$(PWD)/../NXP/mcuxsdk/mcuxsdk
|
||||
MCUXPRESSO_CMSIS?=$(PWD)/../NXP/CMSIS_5/CMSIS
|
||||
MCUXPRESSO_CPU?=MCXN947VDF_cm33_core0
|
||||
MCUXPRESSO_DRIVERS?=$(MCUXPRESSO)/devices/MCX/MCXN/MCXN947
|
||||
MCUXPRESSO_PROJECT_TEMPLATE?=$(MCUXPRESSO)/examples/_boards/frdmmcxn947/project_template
|
||||
DEBUG?=0
|
||||
DEBUG_UART?=1
|
||||
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
|
||||
# 40KB boot, 44KB partitions, 8KB swap
|
||||
WOLFBOOT_PARTITION_SIZE?=0xB000
|
||||
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0xA000
|
||||
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x15000
|
||||
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x20000
|
||||
|
||||
# Alternate larger configuration for debugging or ARMASM
|
||||
# 64KB boot, 64KB partitions, 8KB swap
|
||||
#WOLFBOOT_PARTITION_SIZE?=0x10000
|
||||
#WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x12000
|
||||
#WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x22000
|
||||
#WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x32000
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
@ -0,0 +1,331 @@
|
|||
/* mcxn.c
|
||||
*
|
||||
* Copyright (C) 2025 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <target.h>
|
||||
#include "fsl_common.h"
|
||||
#include "image.h"
|
||||
|
||||
#include "clock_config.h"
|
||||
#include "fsl_clock.h"
|
||||
#include "fsl_flash.h"
|
||||
#include "fsl_gpio.h"
|
||||
#include "fsl_lpflexcomm.h"
|
||||
#include "fsl_lpuart.h"
|
||||
#include "fsl_port.h"
|
||||
#include "fsl_reset.h"
|
||||
#include "loader.h"
|
||||
#include "PERI_AHBSC.h"
|
||||
|
||||
#ifdef TZEN
|
||||
#include "hal/armv8m_tz.h"
|
||||
#endif
|
||||
|
||||
static flash_config_t pflash;
|
||||
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 (boot partition) */
|
||||
sau_init_region(1, WOLFBOOT_PARTITION_BOOT_ADDRESS,
|
||||
WOLFBOOT_PARTITION_BOOT_ADDRESS + WOLFBOOT_PARTITION_SIZE - 1,
|
||||
0);
|
||||
|
||||
/* Non-secure RAM */
|
||||
sau_init_region(2, 0x20020000, 0x20025FFF, 0);
|
||||
|
||||
/* Peripherals */
|
||||
sau_init_region(3, 0x40000000, 0x4005FFFF, 0);
|
||||
sau_init_region(4, 0x40080000, 0x400DFFFF, 0);
|
||||
sau_init_region(5, 0x40100000, 0x4013FFFF, 0);
|
||||
|
||||
/* Enable SAU */
|
||||
SAU_CTRL = SAU_INIT_CTRL_ENABLE;
|
||||
|
||||
/* Enable securefault handler */
|
||||
SCB_SHCSR |= SCB_SHCSR_SECUREFAULT_EN;
|
||||
}
|
||||
|
||||
static void periph_unsecure(void)
|
||||
{
|
||||
CLOCK_EnableClock(kCLOCK_Gpio0);
|
||||
CLOCK_EnableClock(kCLOCK_Gpio1);
|
||||
CLOCK_EnableClock(kCLOCK_Port0);
|
||||
CLOCK_EnableClock(kCLOCK_Port1);
|
||||
|
||||
GPIO_EnablePinControlNonSecure(GPIO0, (1UL << 10) | (1UL << 27));
|
||||
GPIO_EnablePinControlNonSecure(GPIO1, (1UL << 2) | (1UL << 8) | (1UL << 9));
|
||||
}
|
||||
#endif
|
||||
|
||||
void hal_init(void)
|
||||
{
|
||||
#ifdef __WOLFBOOT
|
||||
/* Single-byte RAM writes unpredictably fail when ECC is enabled */
|
||||
SYSCON->ECC_ENABLE_CTRL = 0;
|
||||
BOARD_InitBootClocks();
|
||||
#ifdef DEBUG_UART
|
||||
uart_init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__WOLFBOOT) || !defined(TZEN)
|
||||
memset(&pflash, 0, sizeof(pflash));
|
||||
FLASH_Init(&pflash);
|
||||
FLASH_GetProperty(&pflash, kFLASH_PropertyPflashSectorSize,
|
||||
&pflash_sector_size);
|
||||
#endif
|
||||
|
||||
#if defined(TZEN) && !defined(NONSECURE_APP)
|
||||
hal_sau_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __WOLFBOOT
|
||||
/* Assert hook needed by SDK assert() macro. */
|
||||
void __assert_func(const char *a, int b, const char *c, const char *d)
|
||||
{
|
||||
(void)a;
|
||||
(void)b;
|
||||
(void)c;
|
||||
(void)d;
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
void hal_prepare_boot(void)
|
||||
{
|
||||
#ifdef TZEN
|
||||
periph_unsecure();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
|
||||
{
|
||||
const uint32_t word_size = 4U;
|
||||
int written = 0;
|
||||
|
||||
while (len > 0) {
|
||||
if ((address & (word_size - 1U)) || (len < (int)word_size)) {
|
||||
uint32_t aligned = address & ~(word_size - 1U);
|
||||
uint32_t word;
|
||||
uint32_t offset = address - aligned;
|
||||
uint32_t copy = word_size - offset;
|
||||
|
||||
if (copy > (uint32_t)len) {
|
||||
copy = (uint32_t)len;
|
||||
}
|
||||
|
||||
memcpy(&word, (void *)aligned, word_size);
|
||||
memcpy(((uint8_t *)&word) + offset, data + written, copy);
|
||||
if (FLASH_Program(&pflash, aligned, (uint8_t *)&word, word_size) !=
|
||||
kStatus_FLASH_Success) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
address += copy;
|
||||
len -= (int)copy;
|
||||
written += (int)copy;
|
||||
}
|
||||
else {
|
||||
uint32_t chunk = (uint32_t)len & ~(word_size - 1U);
|
||||
|
||||
if (FLASH_Program(&pflash, address, (uint8_t *)data + written,
|
||||
chunk) != kStatus_FLASH_Success) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
address += chunk;
|
||||
len -= (int)chunk;
|
||||
written += (int)chunk;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RAMFUNCTION hal_flash_unlock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void RAMFUNCTION hal_flash_lock(void)
|
||||
{
|
||||
}
|
||||
|
||||
int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
|
||||
{
|
||||
uint32_t sector_size = pflash_sector_size;
|
||||
|
||||
if (sector_size == 0U) {
|
||||
sector_size = WOLFBOOT_SECTOR_SIZE;
|
||||
}
|
||||
|
||||
if ((address % sector_size) != 0U) {
|
||||
address -= address % sector_size;
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
if (FLASH_Erase(&pflash, address, sector_size,
|
||||
kFLASH_ApiEraseKey) != kStatus_FLASH_Success) {
|
||||
return -1;
|
||||
}
|
||||
if (FLASH_VerifyErase(&pflash, address, sector_size) !=
|
||||
kStatus_FLASH_Success) {
|
||||
return -1;
|
||||
}
|
||||
address += sector_size;
|
||||
len -= (int)sector_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WOLFCRYPT_SECURE_MODE
|
||||
/* These functions are stubs for now, because the MCUXpresso SDK doesn't
|
||||
* implement drivers for the MCXN's TRNG. */
|
||||
void hal_trng_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void hal_trng_fini(void)
|
||||
{
|
||||
}
|
||||
|
||||
int hal_trng_get_entropy(unsigned char *out, unsigned int len)
|
||||
{
|
||||
(void)out;
|
||||
(void)len;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void uart_init(void)
|
||||
{
|
||||
lpuart_config_t config;
|
||||
const port_pin_config_t uart_rx = {
|
||||
.pullSelect = kPORT_PullUp,
|
||||
#if defined(FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE) && FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE
|
||||
.pullValueSelect = kPORT_LowPullResistor,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE
|
||||
.slewRate = kPORT_FastSlewRate,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER
|
||||
.passiveFilterEnable = kPORT_PassiveFilterDisable,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN
|
||||
.openDrainEnable = kPORT_OpenDrainDisable,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH
|
||||
.driveStrength = kPORT_LowDriveStrength,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1
|
||||
.driveStrength1 = kPORT_NormalDriveStrength,
|
||||
#endif
|
||||
.mux = kPORT_MuxAlt2,
|
||||
#if defined(FSL_FEATURE_PORT_HAS_INPUT_BUFFER) && FSL_FEATURE_PORT_HAS_INPUT_BUFFER
|
||||
.inputBuffer = kPORT_InputBufferEnable,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_INVERT_INPUT) && FSL_FEATURE_PORT_HAS_INVERT_INPUT
|
||||
.invertInput = kPORT_InputNormal,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK
|
||||
.lockRegister = kPORT_UnlockRegister
|
||||
#endif
|
||||
};
|
||||
const port_pin_config_t uart_tx = {
|
||||
.pullSelect = kPORT_PullDisable,
|
||||
#if defined(FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE) && FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE
|
||||
.pullValueSelect = kPORT_LowPullResistor,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE
|
||||
.slewRate = kPORT_FastSlewRate,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER
|
||||
.passiveFilterEnable = kPORT_PassiveFilterDisable,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN
|
||||
.openDrainEnable = kPORT_OpenDrainDisable,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH
|
||||
.driveStrength = kPORT_LowDriveStrength,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1
|
||||
.driveStrength1 = kPORT_NormalDriveStrength,
|
||||
#endif
|
||||
.mux = kPORT_MuxAlt2,
|
||||
#if defined(FSL_FEATURE_PORT_HAS_INPUT_BUFFER) && FSL_FEATURE_PORT_HAS_INPUT_BUFFER
|
||||
.inputBuffer = kPORT_InputBufferEnable,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_INVERT_INPUT) && FSL_FEATURE_PORT_HAS_INVERT_INPUT
|
||||
.invertInput = kPORT_InputNormal,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK
|
||||
.lockRegister = kPORT_UnlockRegister
|
||||
#endif
|
||||
};
|
||||
|
||||
CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1U);
|
||||
CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4);
|
||||
CLOCK_EnableClock(kCLOCK_LPFlexComm4);
|
||||
RESET_ClearPeripheralReset(kFC4_RST_SHIFT_RSTn);
|
||||
CLOCK_EnableClock(kCLOCK_Port1);
|
||||
|
||||
PORT_SetPinConfig(PORT1, 8U, &uart_rx);
|
||||
PORT_SetPinConfig(PORT1, 9U, &uart_tx);
|
||||
|
||||
(void)LP_FLEXCOMM_Init(4U, LP_FLEXCOMM_PERIPH_LPUART);
|
||||
LPUART_GetDefaultConfig(&config);
|
||||
config.baudRate_Bps = 115200U;
|
||||
config.enableTx = true;
|
||||
config.enableRx = true;
|
||||
(void)LPUART_Init(LPUART4, &config, 12000000U);
|
||||
}
|
||||
|
||||
void uart_write(const char *buf, unsigned int sz)
|
||||
{
|
||||
const char *line;
|
||||
unsigned int line_sz;
|
||||
|
||||
while (sz > 0) {
|
||||
line = memchr(buf, '\n', sz);
|
||||
if (line == NULL) {
|
||||
(void)LPUART_WriteBlocking(LPUART4, (const uint8_t *)buf, sz);
|
||||
break;
|
||||
}
|
||||
line_sz = (unsigned int)(line - buf);
|
||||
if (line_sz > sz - 1U) {
|
||||
line_sz = sz - 1U;
|
||||
}
|
||||
(void)LPUART_WriteBlocking(LPUART4, (const uint8_t *)buf, line_sz);
|
||||
(void)LPUART_WriteBlocking(LPUART4, (const uint8_t *)"\r\n", 2U);
|
||||
buf = line + 1;
|
||||
sz -= line_sz + 1U;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = @WOLFBOOT_KEYVAULT_ADDRESS@ - @ARCH_FLASH_OFFSET@
|
||||
RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 0x10000 /* 64K */
|
||||
RAM_HEAP (rwx) : ORIGIN = 0x30010000, LENGTH = 0xC000 /* 48K */
|
||||
RAM_KV (rwx) : ORIGIN = 0x3001C000, 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 = 0x20020000, 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));
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K
|
||||
}
|
||||
|
||||
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));
|
||||
|
|
@ -372,6 +372,26 @@ ifeq ($(TARGET),mcxw)
|
|||
LDFLAGS+=--specs=nosys.specs
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),mcxn)
|
||||
ifeq ($(TZEN),1)
|
||||
LSCRIPT_TEMPLATE=ARM-mcxn-ns.ld
|
||||
CFLAGS:=$(filter-out -mcmse, $(CFLAGS))
|
||||
else
|
||||
LSCRIPT_TEMPLATE=ARM-mcxn.ld
|
||||
endif
|
||||
APP_OBJS+=\
|
||||
$(MCUXPRESSO_PROJECT_TEMPLATE)/clock_config.o \
|
||||
$(MCUXPRESSO)/drivers/gpio/fsl_gpio.o \
|
||||
$(MCUXPRESSO)/drivers/lpflexcomm/fsl_lpflexcomm.o \
|
||||
$(MCUXPRESSO)/drivers/lpuart/fsl_lpuart.o \
|
||||
$(MCUXPRESSO_DRIVERS)/drivers/fsl_reset.o \
|
||||
$(MCUXPRESSO_DRIVERS)/drivers/fsl_clock.o \
|
||||
$(MCUXPRESSO_DRIVERS)/drivers/romapi/flash/src/fsl_flash.o
|
||||
ifeq (,$(findstring nosys.specs,$(LDFLAGS)))
|
||||
LDFLAGS+=--specs=nosys.specs
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),imx_rt)
|
||||
LDFLAGS+=\
|
||||
-mcpu=cortex-m7 -Wall --specs=nosys.specs -fno-common -ffunction-sections -fdata-sections \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,122 @@
|
|||
/* app_mcxn.c
|
||||
*
|
||||
* Minimal test application scaffold for NXP MCXN targets.
|
||||
*
|
||||
* Copyright (C) 2025 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "fsl_clock.h"
|
||||
#include "fsl_gpio.h"
|
||||
#include "fsl_port.h"
|
||||
|
||||
#include "target.h"
|
||||
#include "wolfboot/wolfboot.h"
|
||||
#include "printf.h"
|
||||
|
||||
extern void hal_init(void);
|
||||
|
||||
static void gpio_init_output(GPIO_Type *gpio, PORT_Type *port,
|
||||
clock_ip_name_t gpio_clock,
|
||||
clock_ip_name_t port_clock, uint32_t pin,
|
||||
uint8_t initial_level)
|
||||
{
|
||||
const port_pin_config_t pin_config = {
|
||||
.pullSelect = kPORT_PullDisable,
|
||||
#if defined(FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE) && FSL_FEATURE_PORT_PCR_HAS_PULL_VALUE
|
||||
.pullValueSelect = kPORT_LowPullResistor,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE
|
||||
.slewRate = kPORT_FastSlewRate,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER
|
||||
.passiveFilterEnable = kPORT_PassiveFilterDisable,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN
|
||||
.openDrainEnable = kPORT_OpenDrainDisable,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH
|
||||
.driveStrength = kPORT_LowDriveStrength,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH1
|
||||
.driveStrength1 = kPORT_LowDriveStrength,
|
||||
#endif
|
||||
.mux = kPORT_MuxAlt0,
|
||||
#if defined(FSL_FEATURE_PORT_HAS_INPUT_BUFFER) && FSL_FEATURE_PORT_HAS_INPUT_BUFFER
|
||||
.inputBuffer = kPORT_InputBufferEnable,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_INVERT_INPUT) && FSL_FEATURE_PORT_HAS_INVERT_INPUT
|
||||
.invertInput = kPORT_InputNormal,
|
||||
#endif
|
||||
#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK
|
||||
.lockRegister = kPORT_UnlockRegister
|
||||
#endif
|
||||
};
|
||||
const gpio_pin_config_t gpio_config = {
|
||||
.pinDirection = kGPIO_DigitalOutput,
|
||||
.outputLogic = initial_level,
|
||||
};
|
||||
|
||||
CLOCK_EnableClock(gpio_clock);
|
||||
CLOCK_EnableClock(port_clock);
|
||||
GPIO_PinInit(gpio, pin, &gpio_config);
|
||||
PORT_SetPinConfig(port, pin, &pin_config);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
uint32_t boot_ver;
|
||||
|
||||
hal_init();
|
||||
|
||||
#ifdef WOLFCRYPT_SECURE_MODE
|
||||
boot_ver = wolfBoot_nsc_current_firmware_version();
|
||||
#else
|
||||
boot_ver = wolfBoot_current_firmware_version();
|
||||
#endif
|
||||
|
||||
wolfBoot_printf("Hello from firmware version %d\n", boot_ver);
|
||||
|
||||
if (boot_ver == 1) {
|
||||
/* Red off */
|
||||
gpio_init_output(GPIO0, PORT0, kCLOCK_Gpio0, kCLOCK_Port0, 10U, 1U);
|
||||
/* Green off */
|
||||
gpio_init_output(GPIO0, PORT0, kCLOCK_Gpio0, kCLOCK_Port0, 27U, 1U);
|
||||
/* Blue on */
|
||||
gpio_init_output(GPIO1, PORT1, kCLOCK_Gpio1, kCLOCK_Port1, 2U, 0U);
|
||||
}
|
||||
else {
|
||||
/* Red off */
|
||||
gpio_init_output(GPIO0, PORT0, kCLOCK_Gpio0, kCLOCK_Port0, 10U, 1U);
|
||||
/* Green on */
|
||||
gpio_init_output(GPIO0, PORT0, kCLOCK_Gpio0, kCLOCK_Port0, 27U, 0U);
|
||||
/* Blue off */
|
||||
gpio_init_output(GPIO1, PORT1, kCLOCK_Gpio1, kCLOCK_Port1, 2U, 1U);
|
||||
|
||||
#ifdef WOLFCRYPT_SECURE_MODE
|
||||
wolfBoot_nsc_success();
|
||||
#else
|
||||
wolfBoot_success();
|
||||
#endif
|
||||
}
|
||||
|
||||
while (1) {
|
||||
__asm__ volatile ("wfi");
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue