diff --git a/.github/workflows/test-configs.yml b/.github/workflows/test-configs.yml index d3d822e8a..ebfed4016 100644 --- a/.github/workflows/test-configs.yml +++ b/.github/workflows/test-configs.yml @@ -159,12 +159,17 @@ jobs: arch: ppc config-file: ./config/examples/nxp-t2080.config -# MCXA test disabled until MCXA is available in mcux -# nxp_mcxa_test: -# uses: ./.github/workflows/test-build-mcux-sdk.yml -# with: -# arch: arm -# config-file: ./config/examples/mcxa.config + nxp_mcxa_test: + uses: ./.github/workflows/test-build-mcux-sdk.yml + with: + arch: arm + config-file: ./config/examples/mcxa.config + + nxp_mcxw_test: + uses: ./.github/workflows/test-build-mcux-sdk.yml + with: + arch: arm + config-file: ./config/examples/mcxw.config raspi3_test: uses: ./.github/workflows/test-build.yml diff --git a/arch.mk b/arch.mk index 3d3e24ef9..d3abb7013 100644 --- a/arch.mk +++ b/arch.mk @@ -613,10 +613,17 @@ ifeq ($(TARGET),mcxa) CFLAGS+=\ -I$(MCUXPRESSO_DRIVERS) \ -I$(MCUXPRESSO_DRIVERS)/drivers \ + -I$(MCUXPRESSO_DRIVERS)/drivers/common \ -I$(MCUXPRESSO)/drivers \ -I$(MCUXPRESSO)/drivers/common \ -I$(MCUXPRESSO_CMSIS)/Include \ - -I$(MCUXPRESSO_CMSIS)/Core/Include + -I$(MCUXPRESSO_CMSIS)/Core/Include \ + -I$(MCUXPRESSO)/drivers/flash \ + -I$(MCUXPRESSO)/drivers/mcx_spc \ + -I$(MCUXPRESSO)/drivers/sysmpu \ + -I$(MCUXPRESSO)/drivers/ltc \ + -I$(MCUXPRESSO)/drivers/port \ + -I$(MCUXPRESSO)/drivers/gpio CFLAGS+=-DCPU_$(MCUXPRESSO_CPU) -DDEBUG_CONSOLE_ASSERT_DISABLE=1 CFLAGS+=-DWOLFSSL_SP_NO_UMAAL CFLAGS+=-Wno-old-style-declaration @@ -624,18 +631,39 @@ ifeq ($(TARGET),mcxa) LDFLAGS+=-mcpu=cortex-m33 OBJS+=\ $(MCUXPRESSO_DRIVERS)/drivers/fsl_clock.o \ - $(MCUXPRESSO_DRIVERS)/drivers/fsl_spc.o + $(MCUXPRESSO)/drivers/mcx_spc/fsl_spc.o \ + $(MCUXPRESSO_DRIVERS)/project_template/clock_config.o +endif - ifeq ($(MCUXSDK),1) - CFLAGS+=\ +ifeq ($(TARGET),mcxw) + CORTEX_M33=1 + CFLAGS+=\ + -I$(MCUXPRESSO_DRIVERS) \ + -I$(MCUXPRESSO_DRIVERS)/drivers \ + -I$(MCUXPRESSO_DRIVERS)/periph2 \ + -I$(MCUXPRESSO)/drivers \ + -I$(MCUXPRESSO)/drivers/flash_k4 \ + -I$(MCUXPRESSO)/drivers/ccm32k \ + -I$(MCUXPRESSO)/drivers/common \ + -I$(MCUXPRESSO_CMSIS)/Include \ + -I$(MCUXPRESSO_CMSIS)/Core/Include \ -I$(MCUXPRESSO)/drivers/flash \ + -I$(MCUXPRESSO)/drivers/spc \ -I$(MCUXPRESSO)/drivers/sysmpu \ -I$(MCUXPRESSO)/drivers/ltc \ -I$(MCUXPRESSO)/drivers/port \ -I$(MCUXPRESSO)/drivers/gpio - - else - endif + CFLAGS+=-DCPU_$(MCUXPRESSO_CPU) -DDEBUG_CONSOLE_ASSERT_DISABLE=1 + CFLAGS+=-DWOLFSSL_SP_NO_UMAAL + 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)/drivers/spc/fsl_spc.o \ + $(MCUXPRESSO_DRIVERS)/project_template/clock_config.o \ + $(MCUXPRESSO)/drivers/ccm32k/fsl_ccm32k.o \ + $(MCUXPRESSO_DRIVERS)/drivers/fsl_romapi.o endif ifeq ($(TARGET),imx_rt) diff --git a/config/examples/mcxa.config b/config/examples/mcxa.config index 8599965b2..6a3c20f21 100644 --- a/config/examples/mcxa.config +++ b/config/examples/mcxa.config @@ -2,9 +2,9 @@ ARCH?=ARM TARGET?=mcxa SIGN?=ECC256 HASH?=SHA256 -MCUXSDK?=0 -MCUXPRESSO?=$(PWD)/../NXP/MCXA153 -MCUXPRESSO_CMSIS?=$(MCUXPRESSO)/CMSIS +MCUXSDK?=1 +MCUXPRESSO?=$(PWD)/../NXP/mcux-sdk +MCUXPRESSO_CMSIS?=$(PWD)/../NXP/CMSIS_5/CMSIS MCUXPRESSO_CPU?=MCXA153VLH MCUXPRESSO_DRIVERS?=$(MCUXPRESSO)/devices/MCXA153 DEBUG?=0 diff --git a/config/examples/mcxw.config b/config/examples/mcxw.config new file mode 100644 index 000000000..35d10e4ee --- /dev/null +++ b/config/examples/mcxw.config @@ -0,0 +1,42 @@ +ARCH?=ARM +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 +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, 44KB partitions, 8KB swap +WOLFBOOT_PARTITION_SIZE?=0xB000 +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x8000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x13000 +WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x1E000 + +# Alternate larger configuration for debugging or ARMASM +# 40KB boot, 40KB partitions, 8KB swap +#WOLFBOOT_PARTITION_SIZE?=0xA000 +#WOLFBOOT_PARTITION_BOOT_ADDRESS?=0xA000 +#WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x14000 +#WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x1E000 diff --git a/docs/Targets.md b/docs/Targets.md index fdc1242c7..415f2d1ea 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -19,6 +19,7 @@ This README describes configuration of supported targets. * [NXP LPC54xxx](#nxp-lpc54xxx) * [NXP LS1028A](#nxp-ls1028a) * [NXP MCXA153](#nxp-mcxa153) +* [NXP MCXW716C](#nxp-mcxw716c) * [NXP P1021 PPC](#nxp-qoriq-p1021-ppc) * [NXP T1024 PPC](#nxp-qoriq-t1024-ppc) * [NXP T2080 PPC](#nxp-qoriq-t2080-ppc) @@ -2181,7 +2182,15 @@ make ### MCX A: Loading the firmware -The NXP Freedom MCX A board debugger comes loaded with MCU Link, but it can be updated to JLink. See https://docs.nxp.com/bundle/UM12012/page/topics/Updating_MCU_Link_firmware.html +The NXP Freedom MCX W board debugger comes loaded with MCU Link, but it can be updated to JLink. +- Download and install the tool to update MCU Link to support jlink: +[@NXP: LinkServer for microcontrollers](https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/linkserver-for-microcontrollers:LINKERSERVER#downloads) + +- put the rom bootloader in 'dfu' mode by adding a jumper JP8 (ISP_EN) + +- run `scripts/program_JLINK` to update the onboard debugger + +- when the update is complete, remove the jumper in JP8 Use JLinkExe tool to upload the initial firmware: `JLinkExe -if swd -Device MCXA153` @@ -2241,6 +2250,96 @@ mon reset c ``` +## NXP MCXW716 + +NXP MCXW716 is a Cortex-M33 microcontroller running at 96MHz. +The support has been tested using FRDM-MCXW716 with the onboard MCU-Link configured in JLink mode. + +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)` +placed under "../NXP". Adjust the MCUXPRESSO and MCUXPRESSO_CMSIS variables in your .config file according to your paths. + +### MCX W: Configuring and compiling + +Copy the example configuration file and build with make: + +```sh +cp config/examples/mcxw.config .config` +make +``` + +### MCX W: Loading the firmware + +The NXP Freedom MCX W board debugger comes loaded with MCU Link, but it can be updated to JLink. +- Download and install the tool to update MCU Link to support jlink: +[@NXP: LinkServer for microcontrollers](https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/linkserver-for-microcontrollers:LINKERSERVER#downloads) + +- put the rom bootloader in 'dfu' mode by adding a jumper in JP5 (ISP_EN) + +- run `scripts/program_JLINK` to update the onboard debugger + +- when the update is complete, remove the jumper in JP5 + +Use JLinkExe tool to upload the initial firmware: `JLinkExe -if swd -Device MCXW716` + +At the Jlink prompt, type: + +``` +loadbin factory.bin 0 +Downloading file [factory.bin]... +J-Link: Flash download: Bank 0 @ 0x00000000: Skipped. Contents already match +O.K. +``` + +Reset or power cycle board. + +The blue led (PA20) will show to indicate version 1 of the firmware has been staged. + + +### MCX W: Testing firmware update + +1) Sign the test-app with version 2: + +```sh +./tools/keytools/sign --ecc256 test-app/image.bin wolfboot_signing_private_key.der 2 +``` + +2) Create a bin footer with wolfBoot trailer "BOOT" and "p" (ASCII for 0x70 == IMG_STATE_UPDATING): + +```sh +echo -n "pBOOT" > trigger_magic.bin +``` + +3) Assembly new factory update.bin: + +```sh +./tools/bin-assemble/bin-assemble \ + update.bin \ + 0x0 test-app/image_v2_signed.bin \ + 0xAFFB trigger_magic.bin +``` + +4) Flash update.bin to 0x13000 (`loadbin update.bin 0x13000`). + +Once wolfBoot has performed validation of the partition and staged a firmware with version > 1, the D15 Green LED on PA19 will show. + +Note: For alternate larger scheme flash `update.bin` to `0x14000` and place trigger_magic.bin at `0x9FFB`. + +### MCX W: Debugging + +Debugging with JLink: + +Note: We include a `.gdbinit` in the wolfBoot root that loads the wolfboot and test-app elf files. + +In one terminal: `JLinkGDBServer -if swd -Device MCXW716 -port 3333` + +In another terminal use `gdb`: + +``` +b main +mon reset +c +``` + ## TI Hercules TMS570LC435 @@ -3224,7 +3323,7 @@ make After running the above commands, you should find a file named `final_image.bin` in the root folder of the repository. The image can be flashed directly into the board. By default wolfBoot tries to read a wolfBoot image from the SATA drive. -The drive should be partitioned with a GPT table, wolfBoot tries to load an image saved in the 5th or the 6th partition. +The drive should be partitioned with a GPT table, wolfBoot tries to load an image saved in the 5th or the 6th partition. You can find more details in `src/update_disk.c`. wolfBoot doesn't try to read from a filesystem and the images need to be written directly into the partition. This is an example boot log: ``` diff --git a/hal/mcxa.c b/hal/mcxa.c index c4338f861..1fdb22001 100644 --- a/hal/mcxa.c +++ b/hal/mcxa.c @@ -38,6 +38,10 @@ static flash_config_t pflash; static int flash_init = 0; +uint32_t SystemCoreClock; + +extern void BOARD_BootClockFRO96M(void); + #ifdef __WOLFBOOT /* Assert hook needed by Kinetis SDK */ void __assert_func(const char *a, int b, const char *c, const char *d) @@ -46,57 +50,6 @@ void __assert_func(const char *a, int b, const char *c, const char *d) ; } -/* The following clock setting function is autogenerated by the MCUXpresso IDE */ -void BOARD_BootClockFRO96M(void) -{ - uint32_t coreFreq; - spc_active_mode_core_ldo_option_t ldoOption; - spc_sram_voltage_config_t sramOption; - - /* Get the CPU Core frequency */ - coreFreq = CLOCK_GetCoreSysClkFreq(); - - /* The flow of increasing voltage and frequency */ - if (coreFreq <= BOARD_BOOTCLOCKFRO96M_CORE_CLOCK) { - /* Set the LDO_CORE VDD regulator level */ - ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; - ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; - (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); - /* Configure Flash to support different voltage level and frequency */ - FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x2U)); - /* Specifies the operating voltage for the SRAM's read/write timing margin */ - sramOption.operateVoltage = kSPC_sramOperateAt1P1V; - sramOption.requestVoltageUpdate = true; - (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); - } - - CLOCK_SetupFROHFClocking(96000000U); /*!< Enable FRO HF(96MHz) output */ - - CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ - - CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ - - /* The flow of decreasing voltage and frequency */ - if (coreFreq > BOARD_BOOTCLOCKFRO96M_CORE_CLOCK) { - /* Configure Flash to support different voltage level and frequency */ - FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x2U)); - /* Specifies the operating voltage for the SRAM's read/write timing margin */ - sramOption.operateVoltage = kSPC_sramOperateAt1P1V; - sramOption.requestVoltageUpdate = true; - (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); - /* Set the LDO_CORE VDD regulator level */ - ldoOption.CoreLDOVoltage = kSPC_CoreLDO_NormalVoltage; - ldoOption.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength; - (void)SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOption); - } - - /*!< Set up clock selectors - Attach clocks to the peripheries */ - - /*!< Set up dividers */ - CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ - CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ -} - void hal_init(void) { /* Clock setting */ diff --git a/hal/mcxw.c b/hal/mcxw.c new file mode 100644 index 000000000..1627ac37c --- /dev/null +++ b/hal/mcxw.c @@ -0,0 +1,164 @@ +/* mcxw.c + * + * Stubs for custom HAL implementation. Defines the + * functions used by wolfboot for a specific target. + * + * 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 +#include +#include "image.h" +/* FSL includes */ +#include "fsl_common.h" + +/* Clock + RAM voltage settings */ +#include "fsl_clock.h" + +/* Flash driver */ +#include "fsl_device_registers.h" +#include "fsl_lpspi_flash.h" +#include "fsl_flash_api.h" +#include "fsl_ccm32k.h" + +#define FLASH FMU0 + +/*!< Core clock frequency: 48000000Hz */ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U +static flash_config_t pflash; +static uint32_t pflash_sector_size = WOLFBOOT_SECTOR_SIZE; + +uint32_t SystemCoreClock; + + +#ifdef __WOLFBOOT + +extern void BOARD_BootClockRUN(void); + + + +/* Assert hook needed by Kinetis SDK */ +void __assert_func(const char *a, int b, const char *c, const char *d) +{ + while(1) + ; +} + + +void hal_prepare_boot(void) +{ + +} + +#endif + +void hal_init(void) +{ +#ifdef __WOLFBOOT + /* Clock setting */ + BOARD_BootClockRUN(); +#endif + /* Clear the FLASH configuration structure */ + memset(&pflash, 0, sizeof(pflash)); + /* FLASH driver init */ + FLASH_Init(&pflash); + FLASH_GetProperty(&pflash, kFLASH_PropertyPflash0SectorSize, + &pflash_sector_size); +} + +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] = { + 0xFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF + }; + + while (len > 0) { + if ((len < (int)flash_word_size) || (address & (flash_word_size - 1))) { + uint32_t aligned_qword[4]; + uint32_t address_align = address - (address & (flash_word_size - 1)); + uint32_t start_off = address - address_align; + uint32_t i; + + memcpy(aligned_qword, (void*)address_align, flash_word_size); + for (i = start_off; ((i < flash_word_size) && (i < len + start_off)); i++) { + ((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; + } + address += i; + len -= i; + } + else { + 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); + } + 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; +} + +void RAMFUNCTION hal_flash_unlock(void) +{ +} + +void RAMFUNCTION hal_flash_lock(void) +{ +} + +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; + } + return 0; +} + diff --git a/hal/mcxw.ld b/hal/mcxw.ld new file mode 100644 index 000000000..0de30f323 --- /dev/null +++ b/hal/mcxw.ld @@ -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); diff --git a/test-app/ARM-mcxw.ld b/test-app/ARM-mcxw.ld new file mode 100644 index 000000000..ef58a695b --- /dev/null +++ b/test-app/ARM-mcxw.ld @@ -0,0 +1,57 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ + RAM (rwx) : ORIGIN = 0x20000000, 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_stack = ORIGIN(RAM) + LENGTH(RAM)); diff --git a/test-app/Makefile b/test-app/Makefile index 7ea7ae7d2..f25c91b46 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -296,10 +296,21 @@ endif ifeq ($(TARGET),mcxa) LSCRIPT_TEMPLATE=ARM-mcxa.ld + APP_OBJS+=$(MCUXPRESSO_DRIVERS)/project_template/clock_config.o APP_OBJS+=$(MCUXPRESSO_DRIVERS)/drivers/fsl_clock.o APP_OBJS+=$(MCUXPRESSO_DRIVERS)/drivers/fsl_reset.o - APP_OBJS+=$(MCUXPRESSO_DRIVERS)/drivers/fsl_gpio.o - APP_OBJS+=$(MCUXPRESSO_DRIVERS)/drivers/fsl_spc.o + APP_OBJS+=$(MCUXPRESSO)/drivers/gpio/fsl_gpio.o + APP_OBJS+=$(MCUXPRESSO)/drivers/mcx_spc/fsl_spc.o +endif + +ifeq ($(TARGET),mcxw) + LSCRIPT_TEMPLATE=ARM-mcxw.ld + APP_OBJS+=$(MCUXPRESSO_DRIVERS)/drivers/fsl_clock.o + APP_OBJS+=$(MCUXPRESSO)/drivers/gpio/fsl_gpio.o + APP_OBJS+=$(MCUXPRESSO)/drivers/spc/fsl_spc.o + APP_OBJS+=$(MCUXPRESSO_DRIVERS)/project_template/clock_config.o + APP_OBJS+=$(MCUXPRESSO)/drivers/ccm32k/fsl_ccm32k.o + APP_OBJS+=$(MCUXPRESSO_DRIVERS)/drivers/fsl_romapi.o endif ifeq ($(TARGET),imx_rt) diff --git a/test-app/app_mcxw.c b/test-app/app_mcxw.c new file mode 100644 index 000000000..903d91cb2 --- /dev/null +++ b/test-app/app_mcxw.c @@ -0,0 +1,95 @@ +/* app_mcxa.c + * + * Test bare-metal boot-led-on application + * + * Copyright (C) 2024 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 +#include +#include +#include "fsl_common.h" +#include "fsl_port.h" +#include "fsl_gpio.h" +#include "fsl_clock.h" + +#include "wolfboot/wolfboot.h" +#include "target.h" + +extern void hal_init(void); + +/* init gpio for port 3 */ +void gpio_portA_init(int pin) +{ + const port_pin_config_t GPIO_OUT_LED = { + (uint16_t)kPORT_PullDisable, + (uint16_t)kPORT_LowPullResistor, + (uint16_t)kPORT_FastSlewRate, + (uint16_t)kPORT_PassiveFilterDisable, + (uint16_t)kPORT_OpenDrainDisable, + (uint16_t)kPORT_LowDriveStrength, + (uint16_t)kPORT_NormalDriveStrength, + (uint16_t)kPORT_MuxAsGpio, + (uint16_t)kPORT_UnlockRegister + }; + + const gpio_pin_config_t GPIO_OUT_LED_config = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = 0U + }; + + + /* Initialize GPIO functionality on pin */ + GPIO_PinInit(GPIOA, pin, &GPIO_OUT_LED_config); + PORT_SetPinConfig(PORTA, pin, &GPIO_OUT_LED); + GPIO_PinWrite(GPIOA, pin, 1); +} + +void main(void) +{ + int i = 0; + uint8_t* bootPart = (uint8_t*)WOLFBOOT_PARTITION_BOOT_ADDRESS; + uint32_t bootVer = wolfBoot_get_blob_version(bootPart); + /* Enable GPIO port clocks */ + CLOCK_EnableClock(kCLOCK_GpioA); + CLOCK_EnableClock(kCLOCK_PortA); + CLOCK_EnableClock(kCLOCK_PortC); + gpio_portA_init(18); + gpio_portA_init(19); + gpio_portA_init(20); + + hal_init(); + if (bootVer == 1) { + /* 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(); + } + + /* busy wait */ + while (1) { + __WFI(); + } +}