From 13bf713b90175fc984448e8e4bc98df83bbc6372 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 14 Nov 2025 14:35:32 -0800 Subject: [PATCH 1/3] Added Vorago VA416x0 wolfBoot support Added check on image header size and sector size. Expanded the ML-DSA testing. --- .github/workflows/test-configs.yml | 7 + .github/workflows/test-renode-nrf52.yml | 15 +- .github/workflows/test-sunnyday-simulator.yml | 14 +- arch.mk | 20 + config/examples/sim-ml-dsa-ecc-hybrid.config | 3 +- config/examples/sim-ml-dsa.config | 2 +- config/examples/sim-ml-dsa3.config | 52 ++ config/examples/sim-ml-dsa5.config | 53 ++ config/examples/vorago_va416x0.config | 79 +++ docs/PQ.md | 9 +- docs/Targets.md | 272 +++++++++ hal/hal.c | 6 +- hal/imx_rt.c | 5 +- hal/kinetis.c | 3 +- hal/mcxa.c | 6 +- hal/nrf5340.c | 11 + hal/va416x0.c | 540 ++++++++++++++++++ hal/va416x0.h | 111 ++++ hal/va416x0.ld | 166 ++++++ include/image.h | 9 +- include/vorago/board.h | 30 + include/vorago/hal_config.h | 30 + src/boot_arm.c | 34 +- src/image.c | 11 +- src/libwolfboot.c | 29 +- src/update_flash.c | 3 +- test-app/ARM-mcxa.ld | 1 + test-app/ARM-mcxw.ld | 1 + test-app/ARM-va416x0.ld | 166 ++++++ test-app/Makefile | 22 +- test-app/app_va416x0.c | 171 ++++++ test-app/startup_arm.c | 15 +- tools/scripts/va416x0/build_test.sh | 74 +++ tools/scripts/va416x0/flash_va416xx.jlink | 11 + .../va416x0/flash_va416xx_update.jlink | 11 + 35 files changed, 1916 insertions(+), 76 deletions(-) create mode 100644 config/examples/sim-ml-dsa3.config create mode 100644 config/examples/sim-ml-dsa5.config create mode 100644 config/examples/vorago_va416x0.config create mode 100644 hal/va416x0.c create mode 100644 hal/va416x0.h create mode 100644 hal/va416x0.ld create mode 100644 include/vorago/board.h create mode 100644 include/vorago/hal_config.h create mode 100644 test-app/ARM-va416x0.ld create mode 100644 test-app/app_va416x0.c create mode 100755 tools/scripts/va416x0/build_test.sh create mode 100644 tools/scripts/va416x0/flash_va416xx.jlink create mode 100644 tools/scripts/va416x0/flash_va416xx_update.jlink diff --git a/.github/workflows/test-configs.yml b/.github/workflows/test-configs.yml index 25a2c21dd2..a915232bf3 100644 --- a/.github/workflows/test-configs.yml +++ b/.github/workflows/test-configs.yml @@ -463,6 +463,13 @@ jobs: # TODO: ti-tms570lc435.config requires CCS_ROOT + # Cannot run on CI without the SDK (see VORAGO_SDK_DIR) + # vorago_va416x0_test: + # uses: ./.github/workflows/test-build.yml + # with: + # arch: arm + # config-file: ./config/examples/vorago_va416x0.config + x86_64_efi_test: uses: ./.github/workflows/test-build.yml with: diff --git a/.github/workflows/test-renode-nrf52.yml b/.github/workflows/test-renode-nrf52.yml index ad3de895e8..bd44c168e3 100644 --- a/.github/workflows/test-renode-nrf52.yml +++ b/.github/workflows/test-renode-nrf52.yml @@ -61,16 +61,23 @@ jobs: # LMS TEST - name: Renode Tests LMS-8-5-5 - run: ./tools/renode/docker-test.sh "SIGN=LMS LMS_LEVELS=2 LMS_HEIGHT=5 LMS_WINTERNITZ=8 WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=2644 IMAGE_HEADER_SIZE=5288" + run: ./tools/renode/docker-test.sh "SIGN=LMS LMS_LEVELS=2 LMS_HEIGHT=5 LMS_WINTERNITZ=8 WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=2644 IMAGE_HEADER_SIZE=5288 WOLFBOOT_SECTOR_SIZE=0x2000" # XMSS TEST - name: Renode Tests XMSS-SHA2_10_256 - run: ./tools/renode/docker-test.sh "SIGN=XMSS XMSS_PARAMS='XMSS-SHA2_10_256' WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=2500 IMAGE_HEADER_SIZE=5000" + run: ./tools/renode/docker-test.sh "SIGN=XMSS XMSS_PARAMS='XMSS-SHA2_10_256' WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=2500 IMAGE_HEADER_SIZE=5000 WOLFBOOT_SECTOR_SIZE=0x2000" -# ML-DSA TEST +# ML-DSA Level 2 TEST - name: Renode Tests ML-DSA-44 - run: ./tools/renode/docker-test.sh "SIGN=ML_DSA ML_DSA_LEVEL=2 WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=2420 IMAGE_HEADER_SIZE=4840" + run: ./tools/renode/docker-test.sh "SIGN=ML_DSA ML_DSA_LEVEL=2 WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=2420 IMAGE_HEADER_SIZE=4840 WOLFBOOT_SECTOR_SIZE=0x2000" +# ML-DSA Level 3 TEST + - name: Renode Tests ML-DSA-65 + run: ./tools/renode/docker-test.sh "SIGN=ML_DSA ML_DSA_LEVEL=3 WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=3309 IMAGE_HEADER_SIZE=8192 WOLFBOOT_SECTOR_SIZE=0x2000" + +# ML-DSA Level 5 TEST + - name: Renode Tests ML-DSA-87 + run: ./tools/renode/docker-test.sh "SIGN=ML_DSA ML_DSA_LEVEL=5 WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=4627 IMAGE_HEADER_SIZE=12288 WOLFBOOT_SECTOR_SIZE=0x3000" - name: Upload Output Dir uses: actions/upload-artifact@v4 diff --git a/.github/workflows/test-sunnyday-simulator.yml b/.github/workflows/test-sunnyday-simulator.yml index 04091e6e7e..b537b51e14 100644 --- a/.github/workflows/test-sunnyday-simulator.yml +++ b/.github/workflows/test-sunnyday-simulator.yml @@ -104,12 +104,12 @@ jobs: - name: Run dualbank swap simulation run: | tools/scripts/sim-dualbank-swap-update.sh - + - name: Cleanup before WOLFBOOT_SMALL_STACK test run: | make keysclean mv .config.orig .config - + - name: Build wolfboot.elf (ECC256, WOLFBOOT_SMALL_STACK) run: | make clean && make test-sim-internal-flash-with-update SIGN=ECC256 WOLFBOOT_SMALL_STACK=1 SPMATH=1 @@ -617,10 +617,18 @@ jobs: run: | tools/scripts/sim-pq-sunnyday-update.sh config/examples/sim-xmss.config - - name: Run sunny day ML-DSA update test + - name: Run sunny day ML-DSA level 2 update test run: | tools/scripts/sim-pq-sunnyday-update.sh config/examples/sim-ml-dsa.config + - name: Run sunny day ML-DSA level 3 update test + run: | + tools/scripts/sim-pq-sunnyday-update.sh config/examples/sim-ml-dsa3.config + + - name: Run sunny day ML-DSA level 5 update test + run: | + tools/scripts/sim-pq-sunnyday-update.sh config/examples/sim-ml-dsa5.config + # 64 Bit simulator, Hybrid auth ML_DSA + ECDSA # - name: make clean diff --git a/arch.mk b/arch.mk index ad9195af42..3dfca22d87 100644 --- a/arch.mk +++ b/arch.mk @@ -266,6 +266,26 @@ ifeq ($(ARCH),ARM) CFLAGS+=-DWOLFBOOT_USE_STDLIBC endif + ifeq ($(TARGET),va416x0) + CFLAGS+=-I$(WOLFBOOT_ROOT)/include/vorago/ \ + -I$(VORAGO_SDK_DIR)/common/drivers/hdr/ \ + -I$(VORAGO_SDK_DIR)/common/mcu/hdr/ \ + -I$(VORAGO_SDK_DIR)/common/utils/hdr/ + SDK_OBJS=$(VORAGO_SDK_DIR)/common/drivers/src/va416xx_hal.o \ + $(VORAGO_SDK_DIR)/common/drivers/src/va416xx_hal_spi.o \ + $(VORAGO_SDK_DIR)/common/drivers/src/va416xx_hal_clkgen.o \ + $(VORAGO_SDK_DIR)/common/drivers/src/va416xx_hal_ioconfig.o \ + $(VORAGO_SDK_DIR)/common/drivers/src/va416xx_hal_irqrouter.o \ + $(VORAGO_SDK_DIR)/common/drivers/src/va416xx_hal_uart.o \ + $(VORAGO_SDK_DIR)/common/drivers/src/va416xx_hal_timer.o \ + $(VORAGO_SDK_DIR)/common/mcu/src/system_va416xx.o + ifeq ($(USE_HAL_SPI_FRAM),1) + SDK_OBJS+=$(VORAGO_SDK_DIR)/common/utils/src/spi_fram.o + CFLAGS+=-DUSE_HAL_SPI_FRAM + endif + OBJS+=$(SDK_OBJS) + endif + ## Cortex CPU ifeq ($(CORTEX_A5),1) diff --git a/config/examples/sim-ml-dsa-ecc-hybrid.config b/config/examples/sim-ml-dsa-ecc-hybrid.config index dd6f64b695..7d1cd0c82a 100644 --- a/config/examples/sim-ml-dsa-ecc-hybrid.config +++ b/config/examples/sim-ml-dsa-ecc-hybrid.config @@ -13,7 +13,8 @@ SIGN_SECONDARY=ECC384 # sizes should be multiple of system page size WOLFBOOT_PARTITION_SIZE=0x40000 -WOLFBOOT_SECTOR_SIZE=0x1000 +# sector size must be larger than IMAGE_HEADER_SIZE +WOLFBOOT_SECTOR_SIZE=0x2000 WOLFBOOT_PARTITION_BOOT_ADDRESS=0x80000 # if on external flash, it should be multiple of system page size WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x100000 diff --git a/config/examples/sim-ml-dsa.config b/config/examples/sim-ml-dsa.config index c6e1e3147e..0c71fb1978 100644 --- a/config/examples/sim-ml-dsa.config +++ b/config/examples/sim-ml-dsa.config @@ -49,7 +49,7 @@ IMAGE_HEADER_SIZE=8192 # ML_DSA_LEVEL=5 # IMAGE_SIGNATURE_SIZE=4627 # IMAGE_HEADER_SIZE=12288 -# This example needsd larger sector size. +# NOTE: This example needs larger sector size. # WOLFBOOT_SECTOR_SIZE=0x3000 # diff --git a/config/examples/sim-ml-dsa3.config b/config/examples/sim-ml-dsa3.config new file mode 100644 index 0000000000..c9fd4080f6 --- /dev/null +++ b/config/examples/sim-ml-dsa3.config @@ -0,0 +1,52 @@ +# ML-DSA signature example, based on sim.config example. +# +# The acceptable parameter values are those in FIPS 204: +# +# ML_DSA_LEVEL = {2, 3, 5} +# +# This corresponds to these security levels (from FIPS 204, Table 1.): +# +# Claimed Security Strength +# ML-DSA-44 Category 2 +# ML-DSA-65 Category 3 +# ML-DSA-87 Category 5 +# +# The signature, pub key, and priv key lengths are all a function +# of this parameter. Refer to this table (from FIPS 204, Table 2.) +# to configure your IMAGE_SIGNATURE_SIZE: +# +# Table 2. Sizes (in bytes) of keys and signatures of ML-DSA +# +# Private Key Public Key Signature Size +# ML-DSA-44 2560 1312 2420 +# ML-DSA-65 4032 1952 3309 +# ML-DSA-87 4896 2592 4627 +# + +ARCH=sim +TARGET=sim +SIGN=ML_DSA +HASH=SHA256 +WOLFBOOT_SMALL_STACK=0 +SPI_FLASH=0 +DEBUG=0 +DELTA_UPDATES=0 + +# +# ML-DSA config examples: +# +# Category 3: +ML_DSA_LEVEL=3 +IMAGE_SIGNATURE_SIZE=3309 +IMAGE_HEADER_SIZE=8192 + +# sizes should be multiple of system page size +WOLFBOOT_PARTITION_SIZE=0x40000 +WOLFBOOT_SECTOR_SIZE=0x2000 +WOLFBOOT_PARTITION_BOOT_ADDRESS=0x20000 +# if on external flash, it should be multiple of system page size +WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x60000 +WOLFBOOT_PARTITION_SWAP_ADDRESS=0xA0000 + +# required for keytools +WOLFBOOT_FIXED_PARTITIONS=1 diff --git a/config/examples/sim-ml-dsa5.config b/config/examples/sim-ml-dsa5.config new file mode 100644 index 0000000000..4464d4c419 --- /dev/null +++ b/config/examples/sim-ml-dsa5.config @@ -0,0 +1,53 @@ +# ML-DSA signature example, based on sim.config example. +# +# The acceptable parameter values are those in FIPS 204: +# +# ML_DSA_LEVEL = {2, 3, 5} +# +# This corresponds to these security levels (from FIPS 204, Table 1.): +# +# Claimed Security Strength +# ML-DSA-44 Category 2 +# ML-DSA-65 Category 3 +# ML-DSA-87 Category 5 +# +# The signature, pub key, and priv key lengths are all a function +# of this parameter. Refer to this table (from FIPS 204, Table 2.) +# to configure your IMAGE_SIGNATURE_SIZE: +# +# Table 2. Sizes (in bytes) of keys and signatures of ML-DSA +# +# Private Key Public Key Signature Size +# ML-DSA-44 2560 1312 2420 +# ML-DSA-65 4032 1952 3309 +# ML-DSA-87 4896 2592 4627 +# + +ARCH=sim +TARGET=sim +SIGN=ML_DSA +HASH=SHA256 +WOLFBOOT_SMALL_STACK=0 +SPI_FLASH=0 +DEBUG=0 +DELTA_UPDATES=0 + +# +# ML-DSA config examples: +# +# Category 5: +ML_DSA_LEVEL=5 +IMAGE_SIGNATURE_SIZE=4627 +IMAGE_HEADER_SIZE=12288 + +# sizes should be multiple of system page size +WOLFBOOT_PARTITION_SIZE=0x40000 +# This example needs larger sector size. +WOLFBOOT_SECTOR_SIZE=0x3000 +WOLFBOOT_PARTITION_BOOT_ADDRESS=0x20000 +# if on external flash, it should be multiple of system page size +WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x60000 +WOLFBOOT_PARTITION_SWAP_ADDRESS=0xA0000 + +# required for keytools +WOLFBOOT_FIXED_PARTITIONS=1 diff --git a/config/examples/vorago_va416x0.config b/config/examples/vorago_va416x0.config new file mode 100644 index 0000000000..4b94dbfa46 --- /dev/null +++ b/config/examples/vorago_va416x0.config @@ -0,0 +1,79 @@ +ARCH?=ARM +CORTEX_M4?=1 +TARGET?=va416x0 + +# ECDSA P384 and SHA384 +SIGN?=ECC384 +HASH?=SHA384 +IMAGE_HEADER_SIZE=512 + +# ML-DSA Level 5 (87) +#SIGN=ML_DSA +#HASH=SHA256 +#ML_DSA_LEVEL=5 +#IMAGE_SIGNATURE_SIZE=4627 +#IMAGE_HEADER_SIZE=12288 + +WOLFBOOT_VERSION?=1 +ARMORED?=1 +DEBUG?=0 +DEBUG_SYMBOLS?=1 +DEBUG_UART?=1 +VTOR?=1 +EXT_FLASH?=1 +SPI_FLASH?=0 +NO_XIP?=1 +NVM_FLASH_WRITEONCE?=0 +UART_FLASH?=0 +V?=0 +NO_MPU?=1 +RAM_CODE?=0 +SPMATH?=1 +DUALBANK_SWAP?=0 +PKA?=0 +ENCRYPT=0 +WOLFTPM?=0 +OPTIMIZATION_LEVEL=1 + +# Optionally allow downgrade to older valid version in update partition +ALLOW_DOWNGRADE?=0 + +# Use assembly version of ECDSA and SHA +NO_ASM?=0 +NO_ARM_ASM?=0 + +# Optional: Use smaller SHA512 +#CFLAGS_EXTRA+=-DUSE_SLOW_SHA512 + +# 38KB boot, 108KB partitions, 2KB swap +WOLFBOOT_SECTOR_SIZE?=0x800 +WOLFBOOT_PARTITION_SIZE?=0x1B000 +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x9800 +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x24800 +WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x3F800 + +# ML-DSA 5: 36KB boot, 104KB partitions, 12KB swap +#WOLFBOOT_SECTOR_SIZE?=0x3000 +#WOLFBOOT_PARTITION_SIZE?=0x1A000 +#WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x9000 +#WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x23000 +#WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x3D000 + +# Debug: 64KB boot, 95KB partitions, 2KB swap +#WOLFBOOT_SECTOR_SIZE?=0x800 +#WOLFBOOT_PARTITION_SIZE?=0x18000 +#WOLFBOOT_PARTITION_BOOT_ADDRESS?=0xFC00 +#WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x27C00 +#WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x3FC00 + +# Vorago SDK common drivers directory +VORAGO_SDK_DIR?=$(PWD)/../VA416xx_SDK/ + +# Use Vorago FRAM driver +USE_HAL_SPI_FRAM=1 + +#CFLAGS_EXTRA+=-DWOLFBOOT_EDAC_RAM_SCRUB=1000 +#CFLAGS_EXTRA+=-DWOLFBOOT_EDAC_ROM_SCRUB=125 + +# Optionally restore clock to heart-beat oscillator after boot +#CFLAGS_EXTRA+=-DWOLFBOOT_RESTORE_CLOCK \ No newline at end of file diff --git a/docs/PQ.md b/docs/PQ.md index 9eb0caa268..2da2ddc6c5 100644 --- a/docs/PQ.md +++ b/docs/PQ.md @@ -26,6 +26,8 @@ In terms of relative tradeoffs: See these config files for simulated target examples: - `config/examples/sim-ml-dsa.config` +- `config/examples/sim-ml-dsa3.config` +- `config/examples/sim-ml-dsa5.config` - `config/examples/sim-lms.config` - `config/examples/sim-xmss.config` @@ -60,15 +62,16 @@ all depend on the parameter set: ### ML-DSA Config -A new ML-DSA sim example has been added here: +See ML-DSA sim examples here: ``` config/examples/sim-ml-dsa.config +config/examples/sim-ml-dsa3.config +config/examples/sim-ml-dsa5.config ``` The security category level is configured with `ML_DSA_LEVEL=`, where -num = 2, 3, 5. Here is an example from the `sim-ml-dsa.config` for category -2: +num = 2, 3, 5. Here is an example for level 2: ``` # ML-DSA config examples: diff --git a/docs/Targets.md b/docs/Targets.md index a3409e91a3..c7cb0816fd 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -45,6 +45,7 @@ This README describes configuration of supported targets. * [STM32U5](#stm32u5) * [STM32WB55](#stm32wb55) * [TI Hercules TMS570LC435](#ti-hercules-tms570lc435) +* [Vorago VA416x0](#vorago-va416x0) * [Xilinx Zynq UltraScale](#xilinx-zynq-ultrascale) ## STM32F4 @@ -3575,3 +3576,274 @@ Currently, wolfBoot for TC3xx is distributed as part of the wolfHSM TC3xx platfo For access to the TC3xx platform release or for more information on using wolfBoot and wolfHSM on AURIX devices, contact [facts@wolfssl.com](mailto:facts@wolfssl.com). + +## Vorago VA416x0 + +Tested on VA41620 and VA41630 MCU's. + +MCU: Cortex-M4 with Triple-Mode Redundancy (TMR) RAD hardening at up to 100MHz. +FLASH: The VA41630 has 256KB of internal SPI FRAM (for the VA41620 its external). FRAM is Infineon FM25V20A. + +Default flash layout: + +| Partition | Size | Address | Description | +|-------------|-------|---------|-------------| +| Bootloader | 38KB | 0x0 | Bootloader partition | +| Application | 108KB | 0x9800 | Boot partition | +| Update | 108KB | 0x24800 | Update partition | +| Swap | 2KB | 0x3F800 | Swap area | + +SRAM: 64KB on-chip SRAM and 256KB on-chip instruction/program memory + +Boot ROM loads at 20MHz from SPI bus to internal data SRAM. + +By default the bootloader is built showing logs on UART0. To use UART1 set `DEBUG_UART_NUM=1`. To disable the bootloader UART change `DEBUG_UART=0` in the `.config`. + +### Building Vorago VA416x0 + +All build settings come from .config file. For this platform use `TARGET=va416x0`. +See example configuration at `config/examples/vorago_va416x0.config`. +The default build uses DEBUG_UART=1 to generate logging on the UART. + +```sh +cp config/examples/vorago_va416x0.config .config +make VORAGO_SDK_DIR=$PWD../VA416xx_SDK/ + [CC ARM] src/string.o + [CC ARM] src/image.o + [CC ARM] src/libwolfboot.o + [CC ARM] hal/hal.o + [CC ARM] hal/va416x0.o + [CC ARM] src/keystore.o + [CC ARM] src/loader.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/../VA416xx_SDK//common/drivers/src/va416xx_hal.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/../VA416xx_SDK//common/drivers/src/va416xx_hal_spi.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/../VA416xx_SDK//common/drivers/src/va416xx_hal_clkgen.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/../VA416xx_SDK//common/drivers/src/va416xx_hal_ioconfig.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/../VA416xx_SDK//common/drivers/src/va416xx_hal_irqrouter.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/../VA416xx_SDK//common/drivers/src/va416xx_hal_uart.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/../VA416xx_SDK//common/drivers/src/va416xx_hal_timer.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/../VA416xx_SDK//common/mcu/src/system_va416xx.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/../VA416xx_SDK//common/utils/src/spi_fram.o + [CC ARM] src/boot_arm.o + [AS ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/port/arm/thumb2-aes-asm.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/port/arm/thumb2-aes-asm_c.o + [AS ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/port/arm/thumb2-sha256-asm.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/port/arm/thumb2-sha256-asm_c.o + [AS ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/port/arm/thumb2-sha512-asm.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/port/arm/thumb2-sha512-asm_c.o + [AS ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/port/arm/thumb2-sha3-asm.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/port/arm/thumb2-sha3-asm_c.o + [AS ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/port/arm/thumb2-chacha-asm.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/port/arm/thumb2-chacha-asm_c.o + [CC ARM] src/update_flash.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/sha256.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/hash.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/memory.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/wc_port.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/wolfmath.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/logging.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/asn.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/ecc.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/sp_int.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/sp_cortexm.o + [CC ARM] /home/davidgarske/GitHub/wolfboot/lib/wolfssl/wolfcrypt/src/sha512.o + [LD] wolfboot.elf + [BIN] wolfboot.bin + [SIZE] + text data bss dec hex filename + 34636 4 26976 61616 f0b0 wolfboot.elf +``` + +### Flashing Vorago VA416x0 + +Flash using Segger JLink: `JLinkExe -CommanderScript tools/scripts/va416x0/flash_va416xx.jlink` + +Example JLink flash script `tools/scripts/va416x0/flash_va416xx.jlink`: + +``` +device VA416XX +si 1 +speed 2000 +r +h +write4 0x40010010 0x1 +exec SetCompareMode = 0 +loadbin factory.bin 0x0 +write4 0x40010010 0x0 +loadfile ../VA416xx_SDK/loader.elf +exit +``` + +The `loader.elf` programs the external SPI FRAM with the IRAM image. It is created with `make loader` from the SDK. + +See `tools/scripts/va416x0/build_test.sh clean` for flashing examples. + +Example boot ouput on UART 0 (MCU TX): + +``` +wolfBoot HAL Init +Boot partition: 0x9800 (sz 5060, ver 0x1, type 0x601) +Partition 1 header magic 0x00000000 invalid at 0x24800 +Boot partition: 0x9800 (sz 5060, ver 0x1, type 0x601) +Booting version: 0x1 +======================== +VA416x0 wolfBoot demo Application +Copyright 2025 wolfSSL Inc +GPL v3 +Version : 0x1 +======================== + +System information +==================================== +Firmware version : 0x1 +Current firmware state: NEW +No image in update partition. + +Bootloader OTP keystore information +==================================== +Number of public keys: 1 + + Public Key #0: size 96, type 6, mask FFFFFFFF + ==================================== + 5F D6 0D 55 DE 8B 17 99 C0 57 4A A9 D1 EF 2A C8 + 6C 36 4A D7 BA 21 5A CB 13 45 AE 45 A0 35 C9 B3 + 6B 0D 4F FF 69 47 29 17 10 1D 6D 4F 44 83 3E EF + 9B BE B7 BB 11 75 01 81 45 14 19 7E B2 BD C0 A6 + 11 0C FA F6 B5 F9 59 BA B9 A5 8E 34 4A CD C5 83 + 7E 43 EF 61 6E C4 15 88 3C FE D6 76 47 D9 82 A4 +``` + +### Debugging Vorago VA416x0 + +Start the GDB server: `JLinkGDBServer -device VA416XX -if SWD -speed 2000 -port 3333` + +Run: `arm-none-eabi-gdb`. This will source the `.gdbinit` to load symbols for `wolfboot.elf` and `test-app/image.elf`. It will also attempt to connect to the GDB server on default port 3333. + +### Testing updates on VA416x0 + +See `tools/scripts/va416x0/build_test.sh update`: + +```sh +# Sign a new test app with version 2 +IMAGE_HEADER_SIZE=512 ./tools/keytools/sign --ecc384 --sha384 test-app/image.bin wolfboot_signing_private_key.der 2 + +# Create a bin footer with wolfBoot trailer "BOOT" and "p" (ASCII for 0x70 == IMG_STATE_UPDATING) +echo -n "pBOOT" > trigger_magic.bin + +# Assembly new factory update.bin +./tools/bin-assemble/bin-assemble \ + update.bin \ + 0x0 wolfboot.bin \ + 0x9800 test-app/image_v1_signed.bin \ + 0x24800 test-app/image_v2_signed.bin \ + 0x3F7FB trigger_magic.bin + +# Use JLink to load +device VA416XX +si 1 +speed 2000 +r +h +write4 0x40010010 0x1 +exec SetCompareMode = 0 +loadbin update.bin 0x0 +write4 0x40010010 0x0 +loadfile ../VA416xx_SDK/loader.elf +exit +``` + +Example update output: + +``` +wolfBoot HAL Init +Boot partition: 0x9800 (sz 5060, ver 0x1, type 0x601) +Update partition: 0x24800 (sz 5060, ver 0x2, type 0x601) +Starting Update (fallback allowed 0) +Update partition: 0x24800 (sz 5060, ver 0x2, type 0x601) +Boot partition: 0x9800 (sz 5060, ver 0x1, type 0x601) +Versions: Current 0x1, Update 0x2 +Copy sector 0 (part 1->2) +Copy sector 0 (part 0->1) +Copy sector 0 (part 2->0) +Boot partition: 0x9800 (sz 5060, ver 0x2, type 0x601) +Update partition: 0x24800 (sz 5060, ver 0x1, type 0x601) +Copy sector 1 (part 1->2) +Copy sector 1 (part 0->1) +Copy sector 1 (part 2->0) +Copy sector 2 (part 1->2) +Copy sector 2 (part 0->1) +Copy sector 2 (part 2->0) +Erasing remainder of partition (50 sectors)... +Boot partition: 0x9800 (sz 5060, ver 0x2, type 0x601) +Update partition: 0x24800 (sz 5060, ver 0x1, type 0x601) +Copy sector 52 (part 0->2) +Copied boot sector to swap +Boot partition: 0x9800 (sz 5060, ver 0x2, type 0x601) +Booting version: 0x1 +======================== +VA416x0 wolfBoot demo Application +Copyright 2025 wolfSSL Inc +GPL v3 +Version : 0x2 +======================== + +System information +==================================== +Firmware version : 0x2 +Current firmware state: TESTING +Backup firmware version : 0x1 +Update state: NEW +Update image older than current. + +Bootloader OTP keystore information +==================================== +Number of public keys: 1 + + Public Key #0: size 96, type 6, mask FFFFFFFF + ==================================== + 5F D6 0D 55 DE 8B 17 99 C0 57 4A A9 D1 EF 2A C8 + 6C 36 4A D7 BA 21 5A CB 13 45 AE 45 A0 35 C9 B3 + 6B 0D 4F FF 69 47 29 17 10 1D 6D 4F 44 83 3E EF + 9B BE B7 BB 11 75 01 81 45 14 19 7E B2 BD C0 A6 + 11 0C FA F6 B5 F9 59 BA B9 A5 8E 34 4A CD C5 83 + 7E 43 EF 61 6E C4 15 88 3C FE D6 76 47 D9 82 A4 + +Booting new firmware, marking successful boot +``` + +Boot logs after hard reset: + +``` +wolfBoot HAL Init +Boot partition: 0x9800 (sz 5060, ver 0x2, type 0x601) +Update partition: 0x24800 (sz 5060, ver 0x1, type 0x601) +Boot partition: 0x9800 (sz 5060, ver 0x2, type 0x601) +Booting version: 0x2 +======================== +VA416x0 wolfBoot demo Application +Copyright 2025 wolfSSL Inc +GPL v3 +Version : 0x2 +======================== + +System information +==================================== +Firmware version : 0x2 +Current firmware state: CONFIRMED +Backup firmware version : 0x1 +Update state: NEW +Update image older than current. + +Bootloader OTP keystore information +==================================== +Number of public keys: 1 + + Public Key #0: size 96, type 6, mask FFFFFFFF + ==================================== + 5F D6 0D 55 DE 8B 17 99 C0 57 4A A9 D1 EF 2A C8 + 6C 36 4A D7 BA 21 5A CB 13 45 AE 45 A0 35 C9 B3 + 6B 0D 4F FF 69 47 29 17 10 1D 6D 4F 44 83 3E EF + 9B BE B7 BB 11 75 01 81 45 14 19 7E B2 BD C0 A6 + 11 0C FA F6 B5 F9 59 BA B9 A5 8E 34 4A CD C5 83 + 7E 43 EF 61 6E C4 15 88 3C FE D6 76 47 D9 82 A4 +``` diff --git a/hal/hal.c b/hal/hal.c index 3ce6d9d240..c89e42f3d7 100644 --- a/hal/hal.c +++ b/hal/hal.c @@ -85,7 +85,7 @@ int hal_flash_test(void) int hal_flash_test_write_once(void) { uint8_t test_byte, expected_byte; - unsigned int i, b; + unsigned int b; int ret = 0; /* Erase the test sector */ @@ -116,7 +116,7 @@ int hal_flash_test_write_once(void) /* Verify the write by direct comparison */ if (memcmp((void*)TEST_ADDRESS, &expected_byte, sizeof(expected_byte)) != 0) { - wolfBoot_printf("Verification failed at byte %d, bit %d\n", i, b); + wolfBoot_printf("Verification failed at byte %d\n", b); return -1; } } @@ -217,7 +217,7 @@ int hal_flash_test_unaligned_src(void) return 0; } -#endif /* TEST_FLASH_READONLY */ +#endif /* !TEST_FLASH_READONLY */ /* This test can be run only if swapping the flash do not reboot the board */ #if defined(DUALBANK_SWAP) && !defined(TEST_FLASH_READONLY) diff --git a/hal/imx_rt.c b/hal/imx_rt.c index cdadb76544..47a8cd0d8f 100644 --- a/hal/imx_rt.c +++ b/hal/imx_rt.c @@ -67,7 +67,6 @@ /* #define DEBUG_EXT_FLASH */ -#ifdef __WOLFBOOT /** Built-in ROM API for bootloaders **/ @@ -850,7 +849,7 @@ static int hal_flash_init(void); void hal_init(void) { -#ifdef WOLFSSL_IMXRT_DCP +#if defined(__WOLFBOOT) && defined(WOLFSSL_IMXRT_DCP) wc_dcp_init(); #endif ARM_MPU_Disable(); @@ -866,8 +865,6 @@ void hal_prepare_boot(void) { } -#endif /* __WOLFBOOT */ - static int RAMFUNCTION hal_flash_init(void) { status_t ret = 0; diff --git a/hal/kinetis.c b/hal/kinetis.c index 87d3c2229e..e204d27638 100644 --- a/hal/kinetis.c +++ b/hal/kinetis.c @@ -28,7 +28,8 @@ #include "fsl_sysmpu.h" #if defined(CPU_MK82FN256VLL15) && defined(FREESCALE_USE_LTC) -#include +#include "wolfssl/wolfcrypt/settings.h" +#include "wolfssl/wolfcrypt/port/nxp/ksdk_port.h" #endif static flash_config_t pflash; diff --git a/hal/mcxa.c b/hal/mcxa.c index 0e28a46e5b..5ce563a26a 100644 --- a/hal/mcxa.c +++ b/hal/mcxa.c @@ -50,8 +50,11 @@ void __assert_func(const char *a, int b, const char *c, const char *d) ; } +#endif /* __WOLFBOOT */ + void hal_init(void) { +#ifdef __WOLFBOOT /* Clock setting */ BOARD_BootClockFRO96M(); @@ -59,14 +62,13 @@ void hal_init(void) memset(&pflash, 0, sizeof(pflash)); /* FLASH driver init */ FLASH_Init(&pflash); +#endif /* __WOLFBOOT */ } void hal_prepare_boot(void) { } -#endif /* __WOLFBOOT */ - int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len) { int ret; diff --git a/hal/nrf5340.c b/hal/nrf5340.c index 3ea64f6fcc..60e231a6ec 100644 --- a/hal/nrf5340.c +++ b/hal/nrf5340.c @@ -376,6 +376,8 @@ void sleep_us(uint32_t usec) RTC_STOP(USE_RTC) = 1; } +#ifdef __WOLFBOOT + #ifdef TARGET_nrf5340_app void hal_net_core(int hold) /* 1=hold, 0=release */ { @@ -678,28 +680,36 @@ static void hal_net_check_version(void) hal_shm_status_string(shm->core.net.status), shm->core.net.version); } +#endif /* __WOLFBOOT */ void hal_init(void) { +#ifdef __WOLFBOOT #ifdef DEBUG_UART const char* bootStr = "wolfBoot HAL Init (" CORE_STR " core)\n"; +#endif #endif clock_init(); #ifdef DEBUG_UART uart_init(); + #ifdef __WOLFBOOT uart_write(bootStr, strlen(bootStr)); + #endif #endif +#ifdef __WOLFBOOT hal_shm_init(); /* need early init of external flash to support checking network core */ spi_flash_probe(); hal_net_check_version(); +#endif } +#ifdef __WOLFBOOT /* enable write protection for the region of flash specified */ int hal_flash_protect(uint32_t start, uint32_t len) { @@ -763,5 +773,6 @@ void hal_prepare_boot(void) hal_shm_cleanup(); } +#endif /* __WOLFBOOT */ #endif /* TARGET_* */ diff --git a/hal/va416x0.c b/hal/va416x0.c new file mode 100644 index 0000000000..91ac2a698c --- /dev/null +++ b/hal/va416x0.c @@ -0,0 +1,540 @@ +/* va416x0.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 + +#include "image.h" +#include "string.h" + +#include "va416x0.h" + +/* Vorago HAL includes */ +#include "va416xx_hal.h" +#include "va416xx_hal_clkgen.h" +#include "va416xx_hal_irqrouter.h" +#include "va416xx_hal_timer.h" +#include "va416xx_hal_ioconfig.h" +#include "va416xx_hal_spi.h" + +#ifdef USE_HAL_SPI_FRAM +#include "spi_fram.h" +#endif + +#include "printf.h" +#include "loader.h" + +const stc_iocfg_pin_cfg_t bootDefaultConfig[] = +{ + {VOR_PORTB,14,en_iocfg_dir_dncare, {{.fltclk=0,.invinp=0,.iewo=0,.opendrn=0,.invout=0,.plevel=0,.pen=0,.pwoa=0,.funsel=3,.iodis=0}}}, /* UART1 TX */ + {VOR_PORTB,15,en_iocfg_dir_dncare, {{.fltclk=0,.invinp=0,.iewo=0,.opendrn=0,.invout=0,.plevel=0,.pen=0,.pwoa=0,.funsel=3,.iodis=0}}}, /* UART1 RX */ + + {VOR_PORTG, 0,en_iocfg_dir_dncare, {{.fltclk=0,.invinp=0,.iewo=0,.opendrn=0,.invout=0,.plevel=0,.pen=0,.pwoa=0,.funsel=1,.iodis=0}}}, /* UART0 TX */ + {VOR_PORTG, 1,en_iocfg_dir_dncare, {{.fltclk=0,.invinp=0,.iewo=0,.opendrn=0,.invout=0,.plevel=0,.pen=0,.pwoa=0,.funsel=1,.iodis=0}}}, /* UART0 RX */ + {VOR_PORTG, 2,en_iocfg_dir_output, {{.fltclk=0,.invinp=0,.iewo=0,.opendrn=0,.invout=0,.plevel=0,.pen=0,.pwoa=0,.funsel=1,.iodis=0}}}, /* out low */ + + {VOR_PORTG, 5,en_iocfg_dir_output, {{.fltclk=0,.invinp=0,.iewo=0,.opendrn=0,.invout=0,.plevel=0,.pen=0,.pwoa=0,.funsel=0,.iodis=0}}}, /* LED DS2 */ + {VOR_PORTF,15,en_iocfg_dir_output, {{.fltclk=0,.invinp=0,.iewo=0,.opendrn=0,.invout=0,.plevel=0,.pen=0,.pwoa=0,.funsel=0,.iodis=0}}}, /* LED DS4 */ + {0} /* end of array - with optimizations end of array was not being properly detected*/ +}; + + +#ifdef DEBUG_UART + +#if defined(DEBUG_UART_NUM) && DEBUG_UART_NUM == 0 + #define DEBUG_UART_BASE VOR_UART0 +#elif defined(DEBUG_UART_NUM) && DEBUG_UART_NUM == 1 + #define DEBUG_UART_BASE VOR_UART1 +#elif defined(DEBUG_UART_NUM) && DEBUG_UART_NUM == 2 + #define DEBUG_UART_BASE VOR_UART2 +#endif + +#ifndef DEBUG_UART_BASE + /* default to UART0 */ + #define DEBUG_UART_BASE VOR_UART0 +#endif + +#ifndef DEBUG_UART_BAUD + #define DEBUG_UART_BAUD 115200 +#endif + +#define UART_CLK (SystemCoreClock / 4) +#define UART2_CLK (SystemCoreClock / 2) + +#define UART_CALC_CLOCKSCALE(_scc,_baud) ((_scc / (_baud * 16)) << \ + UART_CLKSCALE_INT_Pos) | \ + (((((_scc % (_baud * 16)) * \ + 64 + (_baud * 8)) / \ + (_baud * 16))) << \ + UART_CLKSCALE_FRAC_Pos) + + +static void UartInit(VOR_UART_Type* uart, uint32_t baudrate) +{ + if (VOR_UART0 == uart) { + VOR_SYSCONFIG->PERIPHERAL_CLK_ENABLE |= CLK_ENABLE_UART0; + uart->CLKSCALE = UART_CALC_CLOCKSCALE(UART_CLK, baudrate); + } else if (VOR_UART1 == uart) { + VOR_SYSCONFIG->PERIPHERAL_CLK_ENABLE |= CLK_ENABLE_UART1; + uart->CLKSCALE = UART_CALC_CLOCKSCALE(UART_CLK, baudrate); + } else if (VOR_UART2 == uart) { + VOR_SYSCONFIG->PERIPHERAL_CLK_ENABLE |= CLK_ENABLE_UART2; + uart->CLKSCALE = UART_CALC_CLOCKSCALE(UART2_CLK, baudrate); + } else { + return; + } + + /* Configure word size and RTS behavior. */ + uart->CTRL = (3 << UART_CTRL_WORDSIZE_Pos) | (UART_CTRL_DEFRTS_Msk); + + /* Enable CTS flow control IO, if needed */ +#ifdef configUART_CTS_FLOW_CONTROL + uart->CTRL |= UART_CTRL_AUTOCTS_Msk; +#endif + + /* Enable RTS flow control IO, if needed */ +#ifdef configUART_RTS_FLOW_CONTROL + uart->CTRL |= UART_CTRL_AUTORTS_Msk; +#endif + + /* Enable RX interrupts as soon as a character is received */ + uart->IRQ_ENB = UART_IRQ_ENB_IRQ_RX_Msk; + uart->RXFIFOIRQTRG = 1; + uart->TXFIFOIRQTRG = 8; + + if (VOR_UART0 == uart) { + NVIC_SetPriority(UART0_RX_IRQn, 1); + NVIC_EnableIRQ(UART0_RX_IRQn); + } else if (VOR_UART1 == uart) { + NVIC_SetPriority(UART1_RX_IRQn, 1); + NVIC_EnableIRQ(UART1_RX_IRQn); + } else { + NVIC_SetPriority(UART2_RX_IRQn, 1); + NVIC_EnableIRQ(UART2_RX_IRQn); + } + + /* Enable UART */ + uart->ENABLE = (UART_ENABLE_RXENABLE_Msk | + UART_ENABLE_TXENABLE_Msk); + + /* send a break to let rx state machine reset */ + uart->TXBREAK = 32; +} + +void uart_init(void) +{ + UartInit(DEBUG_UART_BASE, DEBUG_UART_BAUD); +} + +void uart_write(const char* buf, unsigned int sz) +{ + uint32_t pos = 0; + while (sz-- > 0) { + char c = buf[pos++]; + if (c == '\n') { /* handle CRLF */ + while((DEBUG_UART_BASE->TXSTATUS & UART_TXSTATUS_WRRDY_Msk) == 0); + DEBUG_UART_BASE->DATA = '\r'; + } + while((DEBUG_UART_BASE->TXSTATUS & UART_TXSTATUS_WRRDY_Msk) == 0); + DEBUG_UART_BASE->DATA = c; + } +} + +void uart_flush(void) +{ + /* wait for TX FIFO to be empty */ + while (DEBUG_UART_BASE->TXSTATUS & UART_TXSTATUS_WRBUSY_Msk); +} +#endif /* DEBUG_UART */ + + +/* FRAM Driver */ +/* Commands */ +#define FRAM_WREN 0x06 +#define FRAM_WRDI 0x04 +#define FRAM_RDSR 0x05 +#define FRAM_WRSR 0x01 +#define FRAM_READ 0x03 +#define FRAM_WRITE 0x02 +#define FRAM_RDID 0x9F +#define FRAM_SLEEP 0xB9 + +#ifndef USE_HAL_SPI_FRAM +static hal_spi_handle_t spiHandle; + +static void FRAM_WaitIdle(uint8_t spiBank) +{ + if (spiBank >= SPI_NUM_BANKS) { + return; + } + + /* Wait until TxBuf sends all */ + while (!(VOR_SPI->BANK[spiBank].STATUS & SPI_STATUS_TFE_Msk)); + /* Wait here until bytes are fully transmitted */ + while (VOR_SPI->BANK[spiBank].STATUS & SPI_STATUS_BUSY_Msk); + /* Clear Tx & RX fifo */ + VOR_SPI->BANK[spiBank].FIFO_CLR = + (SPI_FIFO_CLR_RXFIFO_Msk | SPI_FIFO_CLR_TXFIFO_Msk); +} + +/* Init SPI FRAM access */ +hal_status_t FRAM_Init(uint8_t spiBank, uint8_t csNum) +{ + hal_status_t status = hal_status_ok; + uint8_t spiData[2]; + + /* Initialize the SPI handle */ + memset(&spiHandle, 0, sizeof(spiHandle)); + spiHandle.locked = false; + spiHandle.state = hal_spi_state_reset; + spiHandle.spi = &VOR_SPI->BANK[spiBank]; + spiHandle.init.blockmode = true; + spiHandle.init.bmstall = true; + spiHandle.init.clkDiv = 2; /* 40MHz */ + spiHandle.init.loopback = false; + spiHandle.init.mdlycap = false; + spiHandle.init.mode = hal_spi_clkmode_0; + spiHandle.init.ms = hal_spi_ms_master; + spiHandle.init.chipSelect = csNum; + spiHandle.init.wordLen = 8; + + status = HAL_Spi_Init(&spiHandle); + if (status == hal_status_ok) { + spiData[0] = FRAM_WREN; /* Set Write Enable Latch(WEL) bit */ + status = HAL_Spi_Transmit(&spiHandle, spiData, 1, 0, true); + HAL_Timer_DelayMs(1); + status = HAL_Spi_Transmit(&spiHandle, spiData, 1, 0, true); + spiData[0] = FRAM_WRSR; /* Write single-byte Status Register message */ + spiData[1] = 0x00; /* Clear the BP1/BP0 protection */ + status = HAL_Spi_Transmit(&spiHandle, spiData, 2, 0, true); + FRAM_WaitIdle(spiBank); + spiHandle.state = hal_spi_state_ready; + } + wolfBoot_printf("FRAM_Init: status %d\n", status); + return status; +} + +hal_status_t FRAM_Write(uint8_t spiBank, uint32_t addr, uint8_t *buf, + uint32_t len) +{ + hal_status_t status = hal_status_ok; + uint8_t spiData[4]; + +#ifdef DEBUG_EXT_FLASH + wolfBoot_printf("fram write: addr 0x%x, dst 0x%x, len %d\n", + addr, buf, len); +#endif + + FRAM_WaitIdle(spiBank); + + spiData[0] = FRAM_WREN; + status = HAL_Spi_Transmit(&spiHandle, spiData, 1, 0, true); + spiData[0] = FRAM_WRITE; /* Write command */ + spiData[1] = (uint8_t)((addr>>16) & 0xFF); /* Address high byte */ + spiData[2] = (uint8_t)((addr>>8) & 0xFF); /* Address mid byte */ + spiData[3] = (uint8_t)( addr & 0xFF); /* Address low byte */ + status = HAL_Spi_Transmit(&spiHandle, spiData, 4, 0, false); + return HAL_Spi_Transmit(&spiHandle, buf, len, 0, true); +} + +hal_status_t FRAM_Read(uint8_t spiBank, uint32_t addr, uint8_t *buf, + uint32_t len) +{ + uint8_t spiData[4]; + +#ifdef DEBUG_EXT_FLASH + wolfBoot_printf("fram read: addr 0x%x, dst 0x%x, len %d\n", + addr, buf, len); +#endif + + FRAM_WaitIdle(spiBank); + + spiData[0] = FRAM_READ; /* Read command */ + spiData[1] = (uint8_t)((addr>>16) & 0xFF); /* Address high byte */ + spiData[2] = (uint8_t)((addr>>8) & 0xFF); /* Address mid byte */ + spiData[3] = (uint8_t)( addr & 0xFF); /* Address low byte */ + return HAL_Spi_TransmitReceive(&spiHandle, spiData, buf, 4, 4, len, 0, true); +} +#endif + +#ifndef FRAM_ERASE_VALUE +#define FRAM_ERASE_VALUE 0xFF +#endif +hal_status_t FRAM_Erase(uint8_t spiBank, uint32_t addr, uint32_t len) +{ + hal_status_t status; + uint8_t spiData[4]; + uint8_t data[32]; + +#ifdef DEBUG_EXT_FLASH + wolfBoot_printf("fram erase: addr 0x%x, len %d\n", addr, len); +#endif + + /* Write 0xFF to the address and length */ + memset(data, FRAM_ERASE_VALUE, sizeof(data)); + + while (len > 0) { + int erase_len = (len > (int)sizeof(data)) ? (int)sizeof(data) : len; + status = FRAM_Write(ROM_SPI_BANK, addr, data, erase_len); + if (status != hal_status_ok) { + return -(int)status; /* convert to negative error code */ + } + addr += erase_len; + len -= erase_len; + } + return 0; +} + + +void RAMFUNCTION hal_flash_unlock(void) +{ + +} + +void RAMFUNCTION hal_flash_lock(void) +{ + +} + +int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len) +{ + /* not supported - no internal flash */ + (void)address; + (void)data; + (void)len; + return 0; +} + +int RAMFUNCTION hal_flash_erase(uint32_t address, int len) +{ + /* not supported - no internal flash */ + (void)address; + (void)len; + return 0; +} + + +#ifdef EXT_FLASH +void ext_flash_lock(void) +{ + /* Enable writes to code memory space */ + VOR_SYSCONFIG->ROM_PROT |= SYSCONFIG_ROM_PROT_WREN_Msk; +} + +void ext_flash_unlock(void) +{ + /* Disable writes to code memory space */ + VOR_SYSCONFIG->ROM_PROT &= ~SYSCONFIG_ROM_PROT_WREN_Msk; +} + +int ext_flash_write(uintptr_t address, const uint8_t *data, int len) +{ + hal_status_t status; +#ifdef DEBUG_EXT_FLASH + wolfBoot_printf("ext write: addr 0x%x, dst 0x%x, len %d\n", + address, data, len); +#endif + status = FRAM_Write(ROM_SPI_BANK, address, (uint8_t*)data, len); + if (status == hal_status_ok) { + /* update the shadow IRAM */ + memcpy((void*)address, data, len); + } + else { + return -(int)status; /* convert to negative error code */ + } + return len; +} + +int ext_flash_read(uintptr_t address, uint8_t *data, int len) +{ + hal_status_t status; +#ifdef DEBUG_EXT_FLASH + wolfBoot_printf("ext read: addr 0x%x, dst 0x%x, len %d\n", + address, data, len); +#endif + status = FRAM_Read(ROM_SPI_BANK, address, data, len); + if (status == hal_status_ok) { + /* update the shadow IRAM */ + memcpy((void*)address, data, len); + } + else { + return -(int)status; /* convert to negative error code */ + } + return len; +} + +int ext_flash_erase(uintptr_t address, int len) +{ + hal_status_t status; +#ifdef DEBUG_EXT_FLASH + wolfBoot_printf("ext erase: addr 0x%x, len %d\n", address, len); +#endif + status = FRAM_Erase(ROM_SPI_BANK, address, len); + if (status == hal_status_ok) { + /* update the shadow IRAM */ + memset((void*)address, 0xFF, len); + } + else { + return -(int)status; /* convert to negative error code */ + } + return 0; +} + +#ifdef TEST_EXT_FLASH + +#ifndef TEST_EXT_ADDRESS + /* Start Address for test 246KB */ + #define TEST_EXT_ADDRESS (246 * 1024) +#endif + +static int test_ext_flash(void) +{ + int ret; + uint32_t i; + uint8_t pageData[WOLFBOOT_SECTOR_SIZE]; + uint32_t wait = 0; + +#ifndef READONLY + /* Erase sector */ + ret = ext_flash_erase(TEST_EXT_ADDRESS, sizeof(pageData)); + wolfBoot_printf("Sector Erase: Ret %d\n", ret); + + /* Write Page */ + for (i=0; i 1 + wolfBoot_printf("check[%3d] %02x\n", i, pageData[i]); + #endif + if (pageData[i] != (i & 0xff)) { + wolfBoot_printf("Check Data @ %d failed\n", i); + return -1; + } + } + + wolfBoot_printf("Flash Test Passed\n"); + return ret; +} +#endif /* TEST_EXT_FLASH */ +#endif /* EXT_FLASH */ + +#ifdef __WOLFBOOT /* build for wolfBoot only */ +/* Configure Error Detection and Correction (EDAC) */ +static void ConfigEdac(uint32_t ramScrub, uint32_t romScrub) +{ + VOR_SYSCONFIG->RAM0_SCRUB = ramScrub; + VOR_SYSCONFIG->RAM1_SCRUB = ramScrub; + VOR_SYSCONFIG->ROM_SCRUB = romScrub; + + IRQROUTER_ENABLE_CLOCK(); + NVIC_EnableIRQ(EDAC_MBE_IRQn); + NVIC_SetPriority(EDAC_MBE_IRQn, 0); + NVIC_EnableIRQ(EDAC_SBE_IRQn); + NVIC_SetPriority(EDAC_SBE_IRQn, 0); + + VOR_SYSCONFIG->IRQ_ENB = 0x3f; /* enable all IRQ */ +} +#endif /* __WOLFBOOT */ + +void hal_init(void) +{ + hal_status_t status; + + /* get clock settings and update SystemCoreClock */ + SystemCoreClockUpdate(); + + +#ifdef __WOLFBOOT /* build for wolfBoot only */ + /* Configure PLL to set CPU clock to 100MHz - 40MHz crystal * 2.5 */ + status = HAL_Clkgen_PLL(CLK_CTRL0_XTAL_N_PLL2P5X); + if (status != hal_status_ok) { + /* continue anyways */ + } + + /* Disable Watchdog - should be already disabled out of reset */ + VOR_WATCH_DOG->WDOGLOCK = 0x1ACCE551; + VOR_WATCH_DOG->WDOGCONTROL = 0x0; + NVIC_ClearPendingIRQ(WATCHDOG_IRQn); + + /* set FPU CP10 and CP11 Full Access */ + SCB->CPACR |= ((0x3 << 20)|(0x3 << 22)); + + /* Init EDAC */ + ConfigEdac(WOLFBOOT_EDAC_RAM_SCRUB, WOLFBOOT_EDAC_ROM_SCRUB); +#endif /* __WOLFBOOT */ + + /* Call SDK HAL initialization function */ + status = HAL_Init(); + if (status != hal_status_ok) { + /* continue anyways */ + } + + /* Configure the pins */ + status = HAL_Iocfg_SetupPins(bootDefaultConfig); + if (status != hal_status_ok) { + /* continue anyways */ + } + +#ifdef DEBUG_UART + uart_init(); + #ifdef __WOLFBOOT + uart_write("wolfBoot HAL Init\n", 18); + #endif +#endif + + /* Init the FRAM SPI device */ + status = FRAM_Init(ROM_SPI_BANK, ROM_SPI_CSN); + if (status != hal_status_ok) { + #ifdef DEBUG + wolfBoot_printf("FRAM_Init failed\n"); + #endif + /* continue anyways */ + } + +#ifdef TEST_EXT_FLASH + test_ext_flash(); +#endif + +} + +void hal_prepare_boot(void) +{ +#ifdef DEBUG_UART + uart_flush(); +#endif + +#ifdef WOLFBOOT_RESTORE_CLOCK + /* Restore clock to heart-beat oscillator */ + (void)HAL_Clkgen_Init(CLK_CFG_HBO); + SystemCoreClockUpdate(); +#endif +} diff --git a/hal/va416x0.h b/hal/va416x0.h new file mode 100644 index 0000000000..e86de44663 --- /dev/null +++ b/hal/va416x0.h @@ -0,0 +1,111 @@ +/* va416x0.h + * + * 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 2 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 + */ + + +#ifndef VA416X0_DEF_INCLUDED +#define VA416X0_DEF_INCLUDED + +#include +#include + + +/* HAL Configuration */ + +/** Hardware version (define for VA416xx RevB) */ +#define __MCU_HW_VER_REVB + +/** Expected VREF voltage */ +#define ADC_VREF (3.3f) /* units: volts */ +#define ADC_VREF_MV (3300ul) /* units: millivolts */ + +/** SysTick setup */ +#define SYSTICK_INTERVAL_MS (1u) /* Interval in milliseconds between SysTick interrupts */ +#define SYSTICK_PRIORITY (7u) + +/* remove I2C interrupts from build if not using */ +#define __HAL_DISABLE_I2C0_MASTER +#define __HAL_DISABLE_I2C1_MASTER +#define __HAL_DISABLE_I2C2_MASTER +#define __HAL_DISABLE_I2C0_SLAVE +#define __HAL_DISABLE_I2C1_SLAVE +#define __HAL_DISABLE_I2C2_SLAVE + +/* remove UART interrupts from build if not using */ +#define __HAL_DISABLE_UART0 +#define __HAL_DISABLE_UART1 +#define __HAL_DISABLE_UART2 + +/** SPI setup */ +#define __HAL_SPI_MODULE_ENABLED + + +/* Board specific configuration */ +#ifndef XTAL +#define XTAL (10000000UL) /* 10 MHz xtal */ +#endif +#ifndef EXTCLK +#define EXTCLK (40000000UL) /* EVK ext clk 40M */ +#endif +#ifndef HBO +#define HBO (18500000UL) /* Internal clock */ +#endif + +/** Default pin IOCONFIG register. type: un_iocfg_reg_t - see va416xx_hal_ioconfig.h */ +/** A pin's IOCONFIG is set to this by HAL_Iocfg_Init() if that pin is not in the cfg array */ +#define DEFAULT_PIN_IOCFG (IOCFG_REG_PULLDN) // internal pulldown enabled for input pin + +/** Default pin direction (input/output) type: en_iocfg_dir_t - see va416xx_hal_ioconfig.h */ +/** A pin's DIR is set to this by HAL_Iocfg_Init() if that pin is not in the cfg array */ +#define DEFAULT_PIN_DIR (en_iocfg_dir__input) // default pin input + + +/* PEB1-VA416XX-EVK */ +/* DS2 - PG5 */ +#define EVK_LED2_PORT PORTG +#define EVK_LED2_BANK VOR_GPIO->BANK[6] +#define EVK_LED2_PIN (5) + +/* DS4 - PF15 */ +#define EVK_LED4_PORT PORTF +#define EVK_LED4_BANK VOR_GPIO->BANK[5] +#define EVK_LED4_PIN (15) + + +/* AUX F-ram */ +#define FRAM_AUX_SPI_BANK (1) +#define FRAM_AUX_SPI_CSN (3) +#define FRAM_SIZE (256 * 1024) /* 256KB */ + +/* ROM SPI info */ +#define ROM_SPI_BANK (3) +#define ROM_SPI_CSN (0) + + +/* EDAC Configuration defaults */ +#ifndef WOLFBOOT_EDAC_RAM_SCRUB + #define WOLFBOOT_EDAC_RAM_SCRUB 1000 +#endif +#ifndef WOLFBOOT_EDAC_ROM_SCRUB + #define WOLFBOOT_EDAC_ROM_SCRUB 125 +#endif + + +#endif /* VA416X0_DEF_INCLUDED */ diff --git a/hal/va416x0.ld b/hal/va416x0.ld new file mode 100644 index 0000000000..ef13006fb5 --- /dev/null +++ b/hal/va416x0.ld @@ -0,0 +1,166 @@ +_Min_Heap_Size = 0x00000200; /* required amount of heap */ +_Min_Stack_Size = 0x00006000; /* required amount of stack */ + +/* Memory areas */ +MEMORY +{ + IRAM (rx) :ORIGIN = 0x00000000, LENGTH = 256K + EBI (xrw) :ORIGIN = 0x10000000, LENGTH = 16M + RAM0 (xrw) :ORIGIN = 0x1FFF8000, LENGTH = 32K + RAM1 (xrw) :ORIGIN = 0x20000000, LENGTH = 32K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into IRAM */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >IRAM + + /* The program code and other data goes into IRAM */ + .text : + { + . = ALIGN(4); + _start_text = .; + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >IRAM + + /* Constant data goes into IRAM */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >IRAM + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >IRAM + + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >IRAM + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >IRAM + + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >IRAM + + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >IRAM + + /* jlink rtt section, goes into fixed location in RAM0 */ + .jlink_rtt (NOLOAD) : + { + . = ALIGN(4); + . = ABSOLUTE(0x1fff8000); + *(.ARM.__at_0x1fff8000) + } >RAM0 + + /* used by the startup to initialize data */ + _stored_data = LOADADDR(.data); + + /* Initialized data sections goes into RAM0, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _start_data = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _end_data = .; /* define a global symbol at data end */ + } >RAM0 AT> IRAM + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _start_bss = .; /* define a global symbol at bss start */ + __bss_start__ = _start_bss; + *(.bss) + *(.bss*) + /* *(COMMON) */ + + . = ALIGN(4); + _end_bss = .; /* define a global symbol at bss end */ + __bss_end__ = _end_bss; + } >RAM0 + + /* DMA control block, goes into fixed location in RAM1 */ + .dma_blk (NOLOAD) : + { + . = ALIGN(128); + /**(.ARM.__at_0x20000000) */ + *(dma_blk) + } >RAM1 + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + PROVIDE ( _start_heap = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + PROVIDE ( END_STACK = . ); + PROVIDE ( _end_stack = . ); + } >RAM0 + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/include/image.h b/include/image.h index e84d4a82b9..36433160b8 100644 --- a/include/image.h +++ b/include/image.h @@ -176,6 +176,12 @@ int wolfBot_get_dts_size(void *dts_addr); #define wolfBoot_verify_signature_primary wolfBoot_verify_signature_tpm #endif +/* Validate sector size is larger than image header size */ +#if defined(WOLFBOOT_SECTOR_SIZE) && defined(IMAGE_HEADER_SIZE) && \ + (WOLFBOOT_SECTOR_SIZE < IMAGE_HEADER_SIZE) +#error WOLFBOOT_SECTOR_SIZE must be larger than IMAGE_HEADER_SIZE +#endif + #if (defined(WOLFBOOT_ARMORED) && defined(__WOLFBOOT)) #if !defined(ARCH_ARM) || (!defined(__GNUC__) && \ @@ -208,6 +214,7 @@ struct wolfBoot_image { uint32_t not_signature_ok; uint32_t canary_FEED89AB; uint32_t sha_ok; + uint32_t not_ext; /* image is no longer external */ }; @@ -821,7 +828,7 @@ static void UNUSEDFUNCTION wolfBoot_image_clear_signature_ok( if ((mask & (1UL << id)) != (1UL << id)) \ wolfBoot_panic() -#define VERIFY_VERSION_ALLOWED(fb_ok) do{} while(0) +#define VERIFY_VERSION_ALLOWED(fb_ok) do{} while(0) /* okay */ #endif diff --git a/include/vorago/board.h b/include/vorago/board.h new file mode 100644 index 0000000000..58a5f9518c --- /dev/null +++ b/include/vorago/board.h @@ -0,0 +1,30 @@ +/* + * + * 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 + */ + +/* File required to build Vorago HAL for wolfBoot. + * See hal/va416x0.h for more details. + */ +#ifndef __BOARD_H +#define __BOARD_H + +#include "hal/va416x0.h" + +#endif /* __BOARD_H */ diff --git a/include/vorago/hal_config.h b/include/vorago/hal_config.h new file mode 100644 index 0000000000..71f0e9e4f7 --- /dev/null +++ b/include/vorago/hal_config.h @@ -0,0 +1,30 @@ +/* + * + * 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 + */ + +/* File required to build Vorago HAL for wolfBoot. + *See hal/va416x0.h for more details. */ + +#ifndef __HAL_CFG_H +#define __HAL_CFG_H + +#include "hal/va416x0.h" + +#endif /* __HAL_CFG_H */ diff --git a/src/boot_arm.c b/src/boot_arm.c index 7413d278a7..5006d599c2 100644 --- a/src/boot_arm.c +++ b/src/boot_arm.c @@ -36,6 +36,9 @@ extern unsigned int _end_bss; extern uint32_t *END_STACK; extern void main(void); +#ifdef TARGET_va416x0 +extern void SysTick_Handler(void); +#endif #ifndef WOLFBOOT_NO_MPU @@ -508,22 +511,27 @@ asm volatile ( __attribute__ ((section(".isr_vector"))) void (* const IV[])(void) = { - (void (*)(void))(&END_STACK), - isr_reset, // Reset - isr_NMI, // NMI - isr_fault, // HardFault - isr_fault, // MemFault - isr_fault, // BusFault - isr_fault, // UsageFault - isr_securefault, // SecureFault on M23/33, reserved otherwise (0) + (void (*)(void))(&END_STACK), + isr_reset, // Reset + isr_NMI, // NMI + isr_fault, // HardFault + isr_fault, // MemFault + isr_fault, // BusFault + isr_fault, // UsageFault + isr_securefault, // SecureFault on M23/33, reserved otherwise (0) + 0, // reserved 0, // reserved 0, // reserved + isr_empty, // SVC + isr_empty, // DebugMonitor 0, // reserved - isr_empty, // SVC - isr_empty, // DebugMonitor - 0, // reserved - isr_empty, // PendSV - isr_empty, // SysTick + isr_empty, // PendSV + +#ifdef TARGET_va416x0 + SysTick_Handler, // SysTick +#else + isr_empty, // SysTick +#endif /* Fill with extra unused handlers */ #if defined(TARGET_stm32l5) || defined(TARGET_stm32u5) || \ diff --git a/src/image.c b/src/image.c index cb0572dc5f..66ee114659 100644 --- a/src/image.c +++ b/src/image.c @@ -1250,8 +1250,8 @@ int wolfBoot_open_image_address(struct wolfBoot_image *img, uint8_t *image) { uint32_t *magic = (uint32_t *)(image); if (*magic != WOLFBOOT_MAGIC) { - wolfBoot_printf("Boot header magic 0x%08x invalid at %p\n", - (unsigned int)*magic, image); + wolfBoot_printf("Partition %d header magic 0x%08x invalid at %p\n", + img->part, (unsigned int)*magic, img->hdr); return -1; } img->fw_size = wolfBoot_image_size(image); @@ -2141,9 +2141,9 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img) */ wolfBoot_verify_signature_primary(key_slot, img, stored_signature); (void)stored_signature_size; - if (img->signature_ok == 1) + #ifdef SIGN_HYBRID - { + if (img->signature_ok == 1) { uint8_t *stored_secondary_signature; uint16_t stored_secondary_signature_size; /* Invalidate the signature_ok flag */ @@ -2168,9 +2168,10 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img) wolfBoot_printf("Done.\n"); } } - if (img->signature_ok == 1) #endif + if (img->signature_ok == 1) { return 0; + } return -2; } #endif diff --git a/src/libwolfboot.c b/src/libwolfboot.c index a94434bca6..4ad30d096c 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -904,7 +904,7 @@ uint16_t wolfBoot_find_header(uint8_t *haystack, uint16_t type, uint8_t **ptr) } #ifdef EXT_FLASH -static uint8_t hdr_cpy[IMAGE_HEADER_SIZE]; +static uint8_t hdr_cpy[IMAGE_HEADER_SIZE] XALIGNED(4); static uint32_t hdr_cpy_done = 0; #endif @@ -969,30 +969,8 @@ int wolfBoot_get_delta_info(uint8_t part, int inverse, uint32_t **img_offset, uint32_t **img_size, uint8_t **base_hash, uint16_t *base_hash_size) { uint32_t *magic = NULL; - uint8_t *image = (uint8_t *)0x00000000; - if (part == PART_UPDATE) { - if (PARTN_IS_EXT(PART_UPDATE)) { - #ifdef EXT_FLASH - ext_flash_check_read((uintptr_t)WOLFBOOT_PARTITION_UPDATE_ADDRESS, - hdr_cpy, IMAGE_HEADER_SIZE); - hdr_cpy_done = 1; - image = hdr_cpy; - #endif - } else { - image = (uint8_t *)WOLFBOOT_PARTITION_UPDATE_ADDRESS; - } - } else if (part == PART_BOOT) { - if (PARTN_IS_EXT(PART_BOOT)) { - #ifdef EXT_FLASH - ext_flash_check_read((uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS, - hdr_cpy, IMAGE_HEADER_SIZE); - hdr_cpy_done = 1; - image = hdr_cpy; - #endif - } else { - image = (uint8_t *)WOLFBOOT_PARTITION_BOOT_ADDRESS; - } - } + uint8_t *image = wolfBoot_get_image_from_part(part); + /* Don't check image against NULL to allow using address 0x00000000 */ magic = (uint32_t *)image; if (*magic != WOLFBOOT_MAGIC) @@ -2088,7 +2066,6 @@ int wolfBoot_nsc_write_update(uint32_t address, const uint8_t *buf, uint32_t len return -1; if (address + len > WOLFBOOT_PARTITION_SIZE) return -1; - hal_flash_unlock(); ret = hal_flash_write(address + WOLFBOOT_PARTITION_UPDATE_ADDRESS, buf, len); hal_flash_lock(); diff --git a/src/update_flash.c b/src/update_flash.c index 54805f561c..1a396cdd0c 100644 --- a/src/update_flash.c +++ b/src/update_flash.c @@ -686,7 +686,8 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed) #endif uint32_t cur_ver, upd_ver; - wolfBoot_printf("Staring Update (fallback allowed %d)\n", fallback_allowed); + wolfBoot_printf("Starting Update (fallback allowed %d)\n", + fallback_allowed); /* No Safety check on open: we might be in the middle of a broken update */ { diff --git a/test-app/ARM-mcxa.ld b/test-app/ARM-mcxa.ld index ef58a695b8..e16659e1c8 100644 --- a/test-app/ARM-mcxa.ld +++ b/test-app/ARM-mcxa.ld @@ -54,4 +54,5 @@ _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)); diff --git a/test-app/ARM-mcxw.ld b/test-app/ARM-mcxw.ld index ef58a695b8..e16659e1c8 100644 --- a/test-app/ARM-mcxw.ld +++ b/test-app/ARM-mcxw.ld @@ -54,4 +54,5 @@ _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)); diff --git a/test-app/ARM-va416x0.ld b/test-app/ARM-va416x0.ld new file mode 100644 index 0000000000..1b3a2eeb31 --- /dev/null +++ b/test-app/ARM-va416x0.ld @@ -0,0 +1,166 @@ +_Min_Heap_Size = 0x00002000; /* required amount of heap */ +_Min_Stack_Size = 0x00002000; /* required amount of stack */ + +/* Memory areas */ +MEMORY +{ + IRAM (rx) :ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ + EBI (xrw) :ORIGIN = 0x10000000, LENGTH = 16M + RAM0 (xrw) :ORIGIN = 0x1FFF8000, LENGTH = 32K + RAM1 (xrw) :ORIGIN = 0x20000000, LENGTH = 32K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into IRAM */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >IRAM + + /* The program code and other data goes into IRAM */ + .text : + { + . = ALIGN(4); + _start_text = .; + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >IRAM + + /* Constant data goes into IRAM */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >IRAM + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >IRAM + + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >IRAM + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >IRAM + + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >IRAM + + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >IRAM + + /* jlink rtt section, goes into fixed location in RAM0 */ + .jlink_rtt (NOLOAD) : + { + . = ALIGN(4); + . = ABSOLUTE(0x1fff8000); + *(.ARM.__at_0x1fff8000) + } >RAM0 + + /* used by the startup to initialize data */ + _stored_data = LOADADDR(.data); + + /* Initialized data sections goes into RAM0, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _start_data = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _end_data = .; /* define a global symbol at data end */ + } >RAM0 AT> IRAM + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _start_bss = .; /* define a global symbol at bss start */ + __bss_start__ = _start_bss; + *(.bss) + *(.bss*) + /* *(COMMON) */ + + . = ALIGN(4); + _end_bss = .; /* define a global symbol at bss end */ + __bss_end__ = _end_bss; + } >RAM0 + + /* DMA control block, goes into fixed location in RAM1 */ + .dma_blk (NOLOAD) : + { + . = ALIGN(128); + /**(.ARM.__at_0x20000000) */ + *(dma_blk) + } >RAM1 + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + PROVIDE ( _start_heap = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + PROVIDE ( END_STACK = . ); + PROVIDE ( _end_stack = . ); + } >RAM0 + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/test-app/Makefile b/test-app/Makefile index 3b232f7b2f..33c14c1150 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -16,6 +16,10 @@ DEBUG?=1 DELTA_DATA_SIZE?=2000 USE_GCC?=1 USE_GCC_HEADLESS?=1 +BOOTLOADER_PARTITION_SIZE?=$$(( $(WOLFBOOT_PARTITION_BOOT_ADDRESS) - $(ARCH_FLASH_OFFSET))) + +# For test-applications we should only use user_settings.h +CFLAGS+=-DWOLFSSL_USER_SETTINGS -DWOLFTPM_USER_SETTINGS ifeq ($(SIGN),RSA2048) IMAGE_HEADER_SIZE:=512 @@ -86,7 +90,7 @@ ifeq ($(TZEN),1) ifeq ($(WOLFCRYPT_TZ),1) APP_OBJS+=../src/wc_secure_calls.o ifeq ($(WOLFCRYPT_TZ_PKCS11),1) - CFLAGS+=-DWOLFSSL_USER_SETTINGS -DWOLFBOOT_PKCS11_APP -DSECURE_PKCS11 + CFLAGS+=-DWOLFBOOT_PKCS11_APP -DSECURE_PKCS11 CFLAGS+=-I"$(WOLFBOOT_LIB_WOLFPKCS11)" APP_OBJS+=./wcs/pkcs11_test_ecc.o APP_OBJS+=./wcs/pkcs11_stub.o @@ -232,6 +236,12 @@ ifeq ($(TARGET),ti_hercules) OBJCOPY_FLAGS= endif +ifeq ($(TARGET),va416x0) + APP_OBJS+=$(SDK_OBJS) + LSCRIPT_TEMPLATE=ARM-va416x0.ld + APP_OBJS+=../src/keystore.o +endif + ifeq ($(TARGET),sim) # LD on MacOS does not support "-Map=" LDMAPSUPPORTED=$(shell $(CC) -Wl,-Map=image.map 2>&1 | grep 'unknown option') @@ -315,6 +325,7 @@ ifeq ($(TARGET),mcxa) APP_OBJS+=$(MCUXPRESSO_DRIVERS)/drivers/fsl_reset.o APP_OBJS+=$(MCUXPRESSO)/drivers/gpio/fsl_gpio.o APP_OBJS+=$(MCUXPRESSO)/drivers/mcx_spc/fsl_spc.o + LDFLAGS+=--specs=nosys.specs endif ifeq ($(TARGET),mcxw) @@ -325,6 +336,7 @@ ifeq ($(TARGET),mcxw) 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 + LDFLAGS+=--specs=nosys.specs endif ifeq ($(TARGET),imx_rt) @@ -497,13 +509,13 @@ ifeq ($(TARGET),aurix_tc3xx) endif ifeq ($(WOLFHSM_CLIENT),1) - CFLAGS += -DWOLFSSL_USER_SETTINGS -DSTRING_USER -I"$(WOLFBOOT_LIB_WOLFSSL)" + CFLAGS += -DSTRING_USER -I"$(WOLFBOOT_LIB_WOLFSSL)" APP_OBJS += $(WOLFHSM_OBJS) APP_OBJS += $(sort $(patsubst $(WOLFBOOT_LIB_WOLFSSL)/%, $(WOLFBOOT_LIB_WOLFSSL)/%, $(WOLFCRYPT_OBJS))) endif ifeq ($(WOLFHSM_SERVER),1) - CFLAGS += -DWOLFSSL_USER_SETTINGS -DSTRING_USER -I"$(WOLFBOOT_LIB_WOLFSSL)" + CFLAGS += -DSTRING_USER -I"$(WOLFBOOT_LIB_WOLFSSL)" APP_OBJS += $(WOLFHSM_OBJS) APP_OBJS += $(sort $(patsubst $(WOLFBOOT_LIB_WOLFSSL)/%, $(WOLFBOOT_LIB_WOLFSSL)/%, $(WOLFCRYPT_OBJS))) endif @@ -552,6 +564,9 @@ delta-extra-data: image.bin @echo "\t[CC-$(ARCH)] $@" $(Q)$(CC) $(CFLAGS) -c $(OUTPUT_FLAG) $@ ../src/libwolfboot.c +../hal/$(TARGET).o: ../hal/$(TARGET).c FORCE + $(Q)$(CC) $(CFLAGS) -c -o $(@) ../hal/$(TARGET).c + ../hal/$(TARGET)_ns.o: ../hal/$(TARGET).c FORCE $(Q)$(CC) $(CFLAGS) -c -o $(@) ../hal/$(TARGET).c -DNONSECURE_APP @@ -600,6 +615,7 @@ endif + FORCE: .PHONY: FORCE clean diff --git a/test-app/app_va416x0.c b/test-app/app_va416x0.c new file mode 100644 index 0000000000..99c31fd11d --- /dev/null +++ b/test-app/app_va416x0.c @@ -0,0 +1,171 @@ +/* app_va416x0.c + * + * Test bare-metal application. + * + * 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 +#include + +#include "system.h" +#include "hal.h" +#include "wolfboot/wolfboot.h" +#include "target.h" +#include "printf.h" +#include "keystore.h" + +#include "../hal/va416x0.h" + +/* Vorago HAL includes */ +#include "va416xx_hal.h" +#include "va416xx_hal_clkgen.h" +#include "va416xx_hal_irqrouter.h" +#include "va416xx_hal_timer.h" +#include "va416xx_hal_ioconfig.h" + +static uint8_t boot_part_state = IMG_STATE_NEW; +static uint8_t update_part_state = IMG_STATE_NEW; + +const char part_state_names[6][16] = { + "NEW", + "UPDATING", + "FFLAGS", + "TESTING", + "CONFIRMED", + "[Invalid state]" +}; + +static const char *part_state_name(uint8_t state) +{ + switch(state) { + case IMG_STATE_NEW: + return part_state_names[0]; + case IMG_STATE_UPDATING: + return part_state_names[1]; + case IMG_STATE_FINAL_FLAGS: + return part_state_names[2]; + case IMG_STATE_TESTING: + return part_state_names[3]; + case IMG_STATE_SUCCESS: + return part_state_names[4]; + default: + return part_state_names[5]; + } +} + +static int print_info(void) +{ + int i, j; + uint32_t cur_fw_version, update_fw_version; + uint32_t n_keys; + uint16_t hdrSz; + + cur_fw_version = wolfBoot_current_firmware_version(); + update_fw_version = wolfBoot_update_firmware_version(); + + wolfBoot_get_partition_state(PART_BOOT, &boot_part_state); + wolfBoot_get_partition_state(PART_UPDATE, &update_part_state); + + wolfBoot_printf("\r\n"); + wolfBoot_printf("System information\r\n"); + wolfBoot_printf("====================================\r\n"); + wolfBoot_printf("Firmware version : 0x%lx\r\n", wolfBoot_current_firmware_version()); + wolfBoot_printf("Current firmware state: %s\r\n", part_state_name(boot_part_state)); + if (update_fw_version != 0) { + if (update_part_state == IMG_STATE_UPDATING) + wolfBoot_printf("Candidate firmware version : 0x%lx\r\n", update_fw_version); + else + wolfBoot_printf("Backup firmware version : 0x%lx\r\n", update_fw_version); + wolfBoot_printf("Update state: %s\r\n", part_state_name(update_part_state)); + if (update_fw_version > cur_fw_version) { + wolfBoot_printf("'reboot' to initiate update.\r\n"); + } else { + wolfBoot_printf("Update image older than current.\r\n"); + } + } else { + wolfBoot_printf("No image in update partition.\r\n"); + } + + wolfBoot_printf("\r\n"); + wolfBoot_printf("Bootloader OTP keystore information\r\n"); + wolfBoot_printf("====================================\r\n"); + n_keys = keystore_num_pubkeys(); + wolfBoot_printf("Number of public keys: %lu\r\n", n_keys); + for (i = 0; i < n_keys; i++) { + uint32_t size = keystore_get_size(i); + uint32_t type = keystore_get_key_type(i); + uint32_t mask = keystore_get_mask(i); + uint8_t *keybuf = keystore_get_buffer(i); + + wolfBoot_printf("\r\n"); + wolfBoot_printf(" Public Key #%d: size %lu, type %lx, mask %08lx\r\n", i, + size, type, mask); + wolfBoot_printf(" ====================================\r\n "); + for (j = 0; j < size; j++) { + wolfBoot_printf("%02X ", keybuf[j]); + if (j % 16 == 15) { + wolfBoot_printf("\r\n "); + } + } + wolfBoot_printf("\r\n"); + } + return 0; +} + +void main(void) +{ + uint32_t app_version; + + hal_init(); + + /* Turn on boot LED */ + EVK_LED2_BANK.SETOUT |= 1< 1) { + /* Turn on update LED */ + EVK_LED4_BANK.SETOUT |= 1< [version_number]" + echo " clean: Build and flash a clean factory image (version defaults to 1)" + echo " update: Build and flash an update image (version defaults to 2)" + echo " version_number: Version number for the signed image (optional, defaults to 1 for clean, 2 for update)" + exit 1 +fi + +MODE=$1 +[ "$MODE" != "clean" ] && [ "$MODE" != "update" ] && { echo "Error: Mode must be 'clean' or 'update'"; exit 1; } + +# Set version: default to 1 for clean, default to 2 for update +VERSION=$([ "$MODE" = "clean" ] && echo "${2:-1}" || echo "${2:-2}") + +# Function to get value from .config file +get_config_value() { + grep "^${1}" .config | sed -E "s/^${1}[?]?=//" | head -n1 +} + +# Extract values from .config +BOOT_ADDRESS=$(get_config_value "WOLFBOOT_PARTITION_BOOT_ADDRESS") +UPDATE_ADDRESS=$(get_config_value "WOLFBOOT_PARTITION_UPDATE_ADDRESS") +IMAGE_HEADER_SIZE=$(get_config_value "IMAGE_HEADER_SIZE") +SIGN=$(get_config_value "SIGN") +HASH=$(get_config_value "HASH") +SIGN_ARG="--${SIGN,,}" +HASH_ARG="--${HASH,,}" + +# Common build steps +make clean && make wolfboot.bin && make test-app/image.bin + +# Function to sign image +sign_image() { + IMAGE_HEADER_SIZE=${IMAGE_HEADER_SIZE} ./tools/keytools/sign ${SIGN_ARG} ${HASH_ARG} test-app/image.bin wolfboot_signing_private_key.der "$1" +} + +# Function to print summary +print_summary() { + echo "Computed addresses:" + echo " BOOT_ADDRESS: ${BOOT_ADDRESS}" + echo " UPDATE_ADDRESS: ${UPDATE_ADDRESS}" + [ -n "$1" ] && echo " TRIGGER_ADDRESS: $1" + echo "Sign/Hash configuration:" + echo " SIGN: ${SIGN} (${SIGN_ARG})" + echo " HASH: ${HASH} (${HASH_ARG})" + [ -n "$2" ] && echo " PREV_VERSION: $2" + echo " $([ -n "$2" ] && echo "NEW_VERSION" || echo "VERSION"): ${VERSION}" +} + +if [ "$MODE" = "clean" ]; then + sign_image ${VERSION} + dd if=/dev/zero of=blank_update.bin bs=1K count=108 + ./tools/bin-assemble/bin-assemble factory.bin 0x0 wolfboot.bin \ + ${BOOT_ADDRESS} test-app/image_v${VERSION}_signed.bin \ + ${UPDATE_ADDRESS} blank_update.bin + JLinkExe -CommanderScript tools/scripts/va416x0/flash_va416xx.jlink + print_summary +else + PARTITION_SIZE=$(get_config_value "WOLFBOOT_PARTITION_SIZE") + TRIGGER_ADDRESS=$(printf "0x%X" $((${UPDATE_ADDRESS} + ${PARTITION_SIZE} - 5))) + PREV_VERSION=$((${VERSION} - 1)) + sign_image ${PREV_VERSION} && sign_image ${VERSION} + echo -n "pBOOT" > trigger_magic.bin + ./tools/bin-assemble/bin-assemble update.bin 0x0 wolfboot.bin \ + ${BOOT_ADDRESS} test-app/image_v${PREV_VERSION}_signed.bin \ + ${UPDATE_ADDRESS} test-app/image_v${VERSION}_signed.bin \ + ${TRIGGER_ADDRESS} trigger_magic.bin + JLinkExe -CommanderScript tools/scripts/va416x0/flash_va416xx_update.jlink + print_summary "${TRIGGER_ADDRESS}" "${PREV_VERSION}" +fi diff --git a/tools/scripts/va416x0/flash_va416xx.jlink b/tools/scripts/va416x0/flash_va416xx.jlink new file mode 100644 index 0000000000..849a42179e --- /dev/null +++ b/tools/scripts/va416x0/flash_va416xx.jlink @@ -0,0 +1,11 @@ +device VA416XX +si 1 +speed 2000 +r +h +write4 0x40010010 0x1 +exec SetCompareMode = 0 +loadbin factory.bin 0x0 +write4 0x40010010 0x0 +loadfile ../VA416xx_SDK/loader.elf +exit \ No newline at end of file diff --git a/tools/scripts/va416x0/flash_va416xx_update.jlink b/tools/scripts/va416x0/flash_va416xx_update.jlink new file mode 100644 index 0000000000..1a49fbbe52 --- /dev/null +++ b/tools/scripts/va416x0/flash_va416xx_update.jlink @@ -0,0 +1,11 @@ +device VA416XX +si 1 +speed 2000 +r +h +write4 0x40010010 0x1 +exec SetCompareMode = 0 +loadbin update.bin 0x0 +write4 0x40010010 0x0 +loadfile ../VA416xx_SDK/loader.elf +exit \ No newline at end of file From 14bee1278195969caa21c654403820102ba33085 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 14 Nov 2025 16:43:53 -0800 Subject: [PATCH 2/3] Unify the hdr_cpy (we don't need two) --- docs/Targets.md | 13 +++++++++++++ src/image.c | 6 ++++++ src/libwolfboot.c | 8 ++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/Targets.md b/docs/Targets.md index c7cb0816fd..ba83258018 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -3654,6 +3654,19 @@ make VORAGO_SDK_DIR=$PWD../VA416xx_SDK/ 34636 4 26976 61616 f0b0 wolfboot.elf ``` +Example of wolfBoot binary sizes based on algorithms: + +| Authentication | Hash | wolfBoot Size | +|----------------|------|---------------| +| ECC256 | SHA256 | 25,836 | +| ECC384 | SHA384 | 34,652 | +| ECC521 | SHA384 | 38,608 | +| ED25519 | SHA256 | 31,448 | +| RSA2048 | SHA256 | 19,148 | +| RSA3072 | SHA384 | 28,828 | +| RSA4096 | SHA3-384 | 19,216 | +| ML-DSA 87 | SHA256 | 25,168 | + ### Flashing Vorago VA416x0 Flash using Segger JLink: `JLinkExe -CommanderScript tools/scripts/va416x0/flash_va416xx.jlink` diff --git a/src/image.c b/src/image.c index 66ee114659..2f7652bf34 100644 --- a/src/image.c +++ b/src/image.c @@ -875,8 +875,14 @@ static uint8_t *get_sha_block(struct wolfBoot_image *img, uint32_t offset) } #ifdef EXT_FLASH +#ifdef UNIT_TEST static uint8_t hdr_cpy[IMAGE_HEADER_SIZE] XALIGNED(4); static int hdr_cpy_done = 0; +#else +/* use from libwolfboot.c */ +extern uint8_t hdr_cpy[IMAGE_HEADER_SIZE] XALIGNED(4); +extern int hdr_cpy_done; +#endif /** * @brief Get a copy of the image header. diff --git a/src/libwolfboot.c b/src/libwolfboot.c index 4ad30d096c..ddbe0282be 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -904,8 +904,8 @@ uint16_t wolfBoot_find_header(uint8_t *haystack, uint16_t type, uint8_t **ptr) } #ifdef EXT_FLASH -static uint8_t hdr_cpy[IMAGE_HEADER_SIZE] XALIGNED(4); -static uint32_t hdr_cpy_done = 0; +uint8_t hdr_cpy[IMAGE_HEADER_SIZE] XALIGNED(4); +uint32_t hdr_cpy_done = 0; #endif /** @@ -949,6 +949,10 @@ static inline uint16_t im2ns(uint16_t val) } #ifdef DELTA_UPDATES + +/* forward declaration */ +static uint8_t* wolfBoot_get_image_from_part(uint8_t part); + /** * @brief Get delta update information. * From 26787f267d13f54ccf871dd6b3d07c8ffd85b2a2 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 18 Nov 2025 11:04:43 -0800 Subject: [PATCH 3/3] Peer review fixes. Added new WOLFBOOT_RESTORE_CLOCK option --- arch.mk | 2 +- config/examples/vorago_va416x0.config | 4 ++-- docs/HAL.md | 3 ++- hal/nrf52.c | 2 ++ hal/pic32ck.c | 2 +- hal/pic32cz.c | 2 ++ hal/same51.c | 2 ++ hal/samr21.c | 2 ++ hal/stm32c0.c | 2 ++ hal/stm32f1.c | 2 ++ hal/stm32f4.c | 3 ++- hal/stm32f7.c | 3 ++- hal/stm32g0.c | 2 ++ hal/stm32h5.c | 2 ++ hal/stm32h7.c | 2 ++ hal/stm32l0.c | 2 ++ hal/stm32l4.c | 3 ++- hal/stm32l5.c | 2 ++ hal/stm32u5.c | 3 ++- hal/stm32wb.c | 2 ++ hal/va416x0.ld | 8 +++----- {include => hal}/vorago/board.h | 0 {include => hal}/vorago/hal_config.h | 0 options.mk | 5 +++++ 24 files changed, 46 insertions(+), 14 deletions(-) rename {include => hal}/vorago/board.h (100%) rename {include => hal}/vorago/hal_config.h (100%) diff --git a/arch.mk b/arch.mk index 3dfca22d87..61d9313d9f 100644 --- a/arch.mk +++ b/arch.mk @@ -267,7 +267,7 @@ ifeq ($(ARCH),ARM) endif ifeq ($(TARGET),va416x0) - CFLAGS+=-I$(WOLFBOOT_ROOT)/include/vorago/ \ + CFLAGS+=-I$(WOLFBOOT_ROOT)/hal/vorago/ \ -I$(VORAGO_SDK_DIR)/common/drivers/hdr/ \ -I$(VORAGO_SDK_DIR)/common/mcu/hdr/ \ -I$(VORAGO_SDK_DIR)/common/utils/hdr/ diff --git a/config/examples/vorago_va416x0.config b/config/examples/vorago_va416x0.config index 4b94dbfa46..bb2d6beb05 100644 --- a/config/examples/vorago_va416x0.config +++ b/config/examples/vorago_va416x0.config @@ -75,5 +75,5 @@ USE_HAL_SPI_FRAM=1 #CFLAGS_EXTRA+=-DWOLFBOOT_EDAC_RAM_SCRUB=1000 #CFLAGS_EXTRA+=-DWOLFBOOT_EDAC_ROM_SCRUB=125 -# Optionally restore clock to heart-beat oscillator after boot -#CFLAGS_EXTRA+=-DWOLFBOOT_RESTORE_CLOCK \ No newline at end of file +# Leave clock at 100MHz (to restore clock to heart beat oscillator use =1) +WOLFBOOT_RESTORE_CLOCK?=0 diff --git a/docs/HAL.md b/docs/HAL.md index cecb092100..6cfabcccb5 100644 --- a/docs/HAL.md +++ b/docs/HAL.md @@ -69,7 +69,8 @@ the geometry of the flash sectors, and erase all the sectors in between. This function is called by the bootloader at a very late stage, before chain-loading the firmware in the next stage. This can be used to revert all the changes made to the clock settings, to ensure -that the state of the microcontroller is restored to its original settings. +that the state of the microcontroller is restored to its original settings. By default most targets will restore the +clock settings. Use the `WOLFBOOT_RESTORE_CLOCK=0` option to disable clock restoration. ### Optional support for external flash memory diff --git a/hal/nrf52.c b/hal/nrf52.c index 1ef70d9569..981c83c272 100644 --- a/hal/nrf52.c +++ b/hal/nrf52.c @@ -124,7 +124,9 @@ void hal_init(void) void hal_prepare_boot(void) { +#ifdef WOLFBOOT_RESTORE_CLOCK TASKS_HFCLKSTOP = 1; +#endif } #endif /* TARGET_nrf52 */ diff --git a/hal/pic32ck.c b/hal/pic32ck.c index 2ec84db055..8c25bd6252 100644 --- a/hal/pic32ck.c +++ b/hal/pic32ck.c @@ -73,7 +73,7 @@ void hal_init(void) void hal_prepare_boot(void) { -#ifndef TZEN +#if !defined(TZEN) && defined(WOLFBOOT_RESTORE_CLOCK) pic32_clock_reset(); #endif } diff --git a/hal/pic32cz.c b/hal/pic32cz.c index dde760563a..1d79960ab9 100644 --- a/hal/pic32cz.c +++ b/hal/pic32cz.c @@ -104,5 +104,7 @@ void hal_init(void) void hal_prepare_boot(void) { +#ifdef WOLFBOOT_RESTORE_CLOCK pic32_clock_reset(); +#endif } diff --git a/hal/same51.c b/hal/same51.c index 9c761e8e3b..9c5469c166 100644 --- a/hal/same51.c +++ b/hal/same51.c @@ -317,6 +317,7 @@ void RAMFUNCTION hal_flash_dualbank_swap(void) void RAMFUNCTION hal_prepare_boot(void) { +#ifdef WOLFBOOT_RESTORE_CLOCK /* Reset clock controller */ GCLK_CTRLA |= CTRLA_SWRST; @@ -332,6 +333,7 @@ void RAMFUNCTION hal_prepare_boot(void) /* Clear PLL options */ OSCCTRL_DPLL0CTRLB = 0; +#endif } #endif /* __WOLFBOOT */ diff --git a/hal/samr21.c b/hal/samr21.c index a887f41ca5..37c2d7b7e7 100644 --- a/hal/samr21.c +++ b/hal/samr21.c @@ -144,6 +144,7 @@ void hal_init(void) void hal_prepare_boot(void) { +#ifdef WOLFBOOT_RESTORE_CLOCK /* Reset NVM wait states */ APBBMASK_REG |= APBBMASK_NVM_EN; NVMCTRLB_REG &= ~((WAITSTATES & 0x0f) << 1); @@ -152,6 +153,7 @@ void hal_prepare_boot(void) /* Reset clock controller */ GCLK_CTRL = GCLK_CTRL_RESET; GCLK_WAITBUSY(); +#endif } diff --git a/hal/stm32c0.c b/hal/stm32c0.c index ceb8231fc2..30a335769f 100644 --- a/hal/stm32c0.c +++ b/hal/stm32c0.c @@ -301,7 +301,9 @@ void RAMFUNCTION hal_prepare_boot(void) #ifdef SPI_FLASH spi_flash_release(); #endif +#ifdef WOLFBOOT_RESTORE_CLOCK clock_pll_off(); +#endif #ifdef FLASH_SECURABLE_MEMORY_SUPPORT do_secure_boot(); #endif diff --git a/hal/stm32f1.c b/hal/stm32f1.c index 5874d63dd7..8b82b492ac 100644 --- a/hal/stm32f1.c +++ b/hal/stm32f1.c @@ -330,5 +330,7 @@ void hal_init(void) void hal_prepare_boot(void) { +#ifdef WOLFBOOT_RESTORE_CLOCK clock_pll_off(); +#endif } diff --git a/hal/stm32f4.c b/hal/stm32f4.c index bddd821d1c..0ac8d17a00 100644 --- a/hal/stm32f4.c +++ b/hal/stm32f4.c @@ -345,7 +345,8 @@ void hal_prepare_boot(void) #ifdef SPI_FLASH spi_flash_release(); #endif - +#ifdef WOLFBOOT_RESTORE_CLOCK clock_pll_off(); +#endif } diff --git a/hal/stm32f7.c b/hal/stm32f7.c index 11c5c4c5d2..c68c004777 100644 --- a/hal/stm32f7.c +++ b/hal/stm32f7.c @@ -423,8 +423,9 @@ void RAMFUNCTION hal_prepare_boot(void) #ifdef SPI_FLASH spi_flash_release(); #endif - +#ifdef WOLFBOOT_RESTORE_CLOCK clock_pll_off(); +#endif } void RAMFUNCTION hal_erase_bank2(void) diff --git a/hal/stm32g0.c b/hal/stm32g0.c index d4e7b31668..20ab6df2ee 100644 --- a/hal/stm32g0.c +++ b/hal/stm32g0.c @@ -333,7 +333,9 @@ void RAMFUNCTION hal_prepare_boot(void) #ifdef SPI_FLASH spi_flash_release(); #endif +#ifdef WOLFBOOT_RESTORE_CLOCK clock_pll_off(); +#endif #ifdef FLASH_SECURABLE_MEMORY_SUPPORT do_secure_boot(); #endif diff --git a/hal/stm32h5.c b/hal/stm32h5.c index aa83f51441..157d4bb6f7 100644 --- a/hal/stm32h5.c +++ b/hal/stm32h5.c @@ -608,7 +608,9 @@ void hal_prepare_boot(void) #if (TZ_SECURE()) periph_unsecure(); #else + #ifdef WOLFBOOT_RESTORE_CLOCK clock_pll_off(); + #endif #endif } diff --git a/hal/stm32h7.c b/hal/stm32h7.c index 728d396739..d202c136a5 100644 --- a/hal/stm32h7.c +++ b/hal/stm32h7.c @@ -510,7 +510,9 @@ void hal_prepare_boot(void) #ifdef SPI_FLASH spi_flash_release(); #endif +#ifdef WOLFBOOT_RESTORE_CLOCK clock_pll_off(); +#endif } #ifdef FLASH_OTP_KEYSTORE diff --git a/hal/stm32l0.c b/hal/stm32l0.c index 6674622394..1f7fe7c58c 100644 --- a/hal/stm32l0.c +++ b/hal/stm32l0.c @@ -262,8 +262,10 @@ void hal_prepare_boot(void) spi_flash_release(); #endif hal_flash_lock(); +#ifdef WOLFBOOT_RESTORE_CLOCK if ((FLASH_PECR & FLASH_PECR_PELOCK) == 0) FLASH_PECR |= FLASH_PECR_PELOCK; clock_pll_off(); +#endif } diff --git a/hal/stm32l4.c b/hal/stm32l4.c index 426814c35b..b4ddaece94 100644 --- a/hal/stm32l4.c +++ b/hal/stm32l4.c @@ -279,8 +279,9 @@ void hal_prepare_boot(void) #ifdef SPI_FLASH spi_flash_release(); #endif - +#ifdef WOLFBOOT_RESTORE_CLOCK clock_pll_off(); +#endif } /* This value is unused, the function is never called diff --git a/hal/stm32l5.c b/hal/stm32l5.c index f45c9f7716..dfb2e4d14d 100644 --- a/hal/stm32l5.c +++ b/hal/stm32l5.c @@ -409,7 +409,9 @@ void hal_init(void) void hal_prepare_boot(void) { +#ifdef WOLFBOOT_RESTORE_CLOCK clock_pll_off(); + #endif #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) periph_unsecure(); #endif diff --git a/hal/stm32u5.c b/hal/stm32u5.c index 291dcd96b5..9156cd7f39 100644 --- a/hal/stm32u5.c +++ b/hal/stm32u5.c @@ -520,8 +520,9 @@ void hal_init(void) void hal_prepare_boot(void) { +#ifdef WOLFBOOT_RESTORE_CLOCK clock_pll_off(); - +#endif #if TZ_SECURE() led_unsecure(); #endif diff --git a/hal/stm32wb.c b/hal/stm32wb.c index ea00d954f5..b51334ab21 100644 --- a/hal/stm32wb.c +++ b/hal/stm32wb.c @@ -325,7 +325,9 @@ void hal_prepare_boot(void) #ifdef SPI_FLASH spi_flash_release(); #endif +#ifdef WOLFBOOT_RESTORE_CLOCK clock_pll_off(); +#endif } #ifdef WOLFSSL_STM32_PKA diff --git a/hal/va416x0.ld b/hal/va416x0.ld index ef13006fb5..922bb40456 100644 --- a/hal/va416x0.ld +++ b/hal/va416x0.ld @@ -1,4 +1,4 @@ -_Min_Heap_Size = 0x00000200; /* required amount of heap */ +# no heap _Min_Stack_Size = 0x00006000; /* required amount of stack */ /* Memory areas */ @@ -140,14 +140,12 @@ SECTIONS *(dma_blk) } >RAM1 - /* User_heap_stack section, used to check that there is enough RAM left */ - ._user_heap_stack : + /* User_stack section, used to check that there is enough RAM left */ + ._user_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); - PROVIDE ( _start_heap = . ); - . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); PROVIDE ( END_STACK = . ); diff --git a/include/vorago/board.h b/hal/vorago/board.h similarity index 100% rename from include/vorago/board.h rename to hal/vorago/board.h diff --git a/include/vorago/hal_config.h b/hal/vorago/hal_config.h similarity index 100% rename from include/vorago/hal_config.h rename to hal/vorago/hal_config.h diff --git a/options.mk b/options.mk index 9a388b5b6c..5614127b1c 100644 --- a/options.mk +++ b/options.mk @@ -1040,3 +1040,8 @@ endif ifneq ($(WOLFBOOT_PARTITION_FILENAME),) CFLAGS += -DWOLFBOOT_PARTITION_FILENAME=$(WOLFBOOT_PARTITION_FILENAME) endif + +# Clock Restore Option (default on) +ifneq ($(WOLFBOOT_RESTORE_CLOCK),0) + CFLAGS += -DWOLFBOOT_RESTORE_CLOCK +endif