diff --git a/.github/workflows/test-configs.yml b/.github/workflows/test-configs.yml index d173cdec91..7b70330050 100644 --- a/.github/workflows/test-configs.yml +++ b/.github/workflows/test-configs.yml @@ -546,6 +546,12 @@ jobs: arch: arm config-file: ./config/examples/stm32wb.config + stm32wb_wolfhal_test: + uses: ./.github/workflows/test-build.yml + with: + arch: arm + config-file: ./config/examples/stm32wb-wolfhal.config + # TODO: ti-tms570lc435.config requires F021 Flash API (Windows installer only) # ti_tms570lc435_test: # uses: ./.github/workflows/test-build-ti-hercules.yml diff --git a/.gitmodules b/.gitmodules index 6cd81662fe..13396fd2ec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "lib/wolfPSA"] path = lib/wolfPSA url = https://github.com/wolfSSL/wolfPSA.git +[submodule "lib/wolfHAL"] + path = lib/wolfHAL + url = https://github.com/wolfSSL/wolfHAL.git diff --git a/Makefile b/Makefile index 1d72f3285e..6726c757a9 100644 --- a/Makefile +++ b/Makefile @@ -142,6 +142,7 @@ WOLFBOOT_LIB_WOLFTPM?=lib/wolfTPM WOLFBOOT_LIB_WOLFPKCS11?=lib/wolfPKCS11 WOLFBOOT_LIB_WOLFPSA?=lib/wolfPSA WOLFBOOT_LIB_WOLFHSM?=lib/wolfHSM +WOLFBOOT_LIB_WOLFHAL?=lib/wolfHAL # Convert to absolute paths using abspath function WOLFBOOT_LIB_WOLFSSL:=$(abspath $(WOLFBOOT_LIB_WOLFSSL)) @@ -149,6 +150,7 @@ WOLFBOOT_LIB_WOLFTPM:=$(abspath $(WOLFBOOT_LIB_WOLFTPM)) WOLFBOOT_LIB_WOLFPKCS11:=$(abspath $(WOLFBOOT_LIB_WOLFPKCS11)) WOLFBOOT_LIB_WOLFPSA:=$(abspath $(WOLFBOOT_LIB_WOLFPSA)) WOLFBOOT_LIB_WOLFHSM:=$(abspath $(WOLFBOOT_LIB_WOLFHSM)) +WOLFBOOT_LIB_WOLFHAL:=$(abspath $(WOLFBOOT_LIB_WOLFHAL)) # Export variables so they are available to sub-makefiles export WOLFBOOT_LIB_WOLFSSL @@ -156,6 +158,7 @@ export WOLFBOOT_LIB_WOLFTPM export WOLFBOOT_LIB_WOLFPKCS11 export WOLFBOOT_LIB_WOLFPSA export WOLFBOOT_LIB_WOLFHSM +export WOLFBOOT_LIB_WOLFHAL ## Architecture/CPU configuration include arch.mk @@ -227,6 +230,13 @@ ifeq ($(TARGET),stm32h5) endif endif # TZEN=1 +ifeq ($(TARGET),wolfhal) + LSCRIPT_IN:=hal/$(WOLFHAL_TARGET).ld + CFLAGS+= -I$(WOLFBOOT_LIB_WOLFHAL) + OBJS+=hal/wolfHAL/$(WOLFHAL_BOARD).o + include hal/wolfHAL/$(WOLFHAL_BOARD).mk +endif + ifeq ($(TARGET),x86_64_efi) MAIN_TARGET:=wolfboot.efi endif diff --git a/arch.mk b/arch.mk index d4467bf886..34acaebd6f 100644 --- a/arch.mk +++ b/arch.mk @@ -203,6 +203,12 @@ ifeq ($(ARCH),ARM) endif endif + ifeq ($(TARGET),wolfhal) + ifeq ($(WOLFHAL_TARGET),stm32wb) + ARCH_FLASH_OFFSET=0x08000000 + SPI_TARGET=stm32 + endif + endif ifeq ($(TARGET),stm32l5) CORTEX_M33=1 diff --git a/config/examples/stm32wb-wolfhal.config b/config/examples/stm32wb-wolfhal.config new file mode 100644 index 0000000000..0307f97a31 --- /dev/null +++ b/config/examples/stm32wb-wolfhal.config @@ -0,0 +1,15 @@ +TARGET=wolfhal +SIGN=ECC256 +HASH=SHA256 +WOLFBOOT_SECTOR_SIZE=0x1000 +WOLFBOOT_PARTITION_SIZE=0x20000 +WOLFBOOT_PARTITION_BOOT_ADDRESS=0x08010000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08028000 +WOLFBOOT_PARTITION_SWAP_ADDRESS=0x08048000 +NVM_FLASH_WRITEONCE=1 +PKA=0 +WOLFHAL_TARGET=stm32wb +WOLFHAL_BOARD=stm32wb55_nucleo +WOLFHAL_FLASH_START=0x08000000 +WOLFHAL_FLASH_SIZE=0x100000 +WOLFHAL_NO_GPIO=1 diff --git a/config/examples/stm32wb.config b/config/examples/stm32wb.config index 81baaf6930..c2e012c1bc 100644 --- a/config/examples/stm32wb.config +++ b/config/examples/stm32wb.config @@ -3,7 +3,7 @@ SIGN=ECC256 HASH=SHA256 WOLFBOOT_SECTOR_SIZE=0x1000 WOLFBOOT_PARTITION_SIZE=0x20000 -WOLFBOOT_PARTITION_BOOT_ADDRESS=0x08008000 +WOLFBOOT_PARTITION_BOOT_ADDRESS=0x08010000 WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x08028000 WOLFBOOT_PARTITION_SWAP_ADDRESS=0x08048000 NVM_FLASH_WRITEONCE=1 diff --git a/hal/uart/uart_drv_wolfhal.c b/hal/uart/uart_drv_wolfhal.c new file mode 100644 index 0000000000..17a5bfbf39 --- /dev/null +++ b/hal/uart/uart_drv_wolfhal.c @@ -0,0 +1,75 @@ +/* uart_drv_wolfhal.c + * + * A generic UART driver using the wolfHAL API module. + * + * 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 + */ + +#ifdef TARGET_wolfhal + +#include +#include + +extern whal_Uart wbUart; + +int uart_tx(const uint8_t c) +{ + whal_Error err; + err = whal_Uart_Send(&wbUart, &c, 1); + if (err) { + return err; + } + return 1; +} + +int uart_rx(uint8_t *c) +{ + whal_Error err; + err = whal_Uart_Recv(&wbUart, c, 1); + if (err) { + return err; + } + return 1; +} + +int uart_init(uint32_t bitrate, uint8_t data, char parity, uint8_t stop) +{ + /* Handle these configure options in the wolfHAL UART config */ + (void)bitrate; + (void)data; + (void)parity; + (void)stop; + + whal_Error err; + err = whal_Uart_Init(&wbUart); + if (err) { + return err; + } + + return 0; +} + +#ifdef DEBUG_UART +void uart_write(const char *buf, unsigned int len) +{ + whal_Uart_Send(&wbUart, (uint8_t *)buf, len); +} +#endif + +#endif /* TARGET_wolfhal */ diff --git a/hal/wolfHAL/stm32wb55_nucleo.c b/hal/wolfHAL/stm32wb55_nucleo.c new file mode 100644 index 0000000000..4546cbcadd --- /dev/null +++ b/hal/wolfHAL/stm32wb55_nucleo.c @@ -0,0 +1,109 @@ +#include + +/* + * STM32WB55 Nucleo board configuration for wolfHAL. + * + * This file wires up the board-level clock, flash, GPIO, and optional UART + * instances used by wolfBoot. Most values are board defaults; override with + * build-time defines (e.g., DEBUG_UART/UART_FLASH) as needed. + */ + +whal_Clock wbClockController; +whal_Flash wbFlash; + +/* Core clock controller (MSI -> PLL -> SYSCLK at 64 MHz). */ +whal_Clock wbClockController = { + WHAL_STM32WB55_RCC_PLL_DEVICE, + + .cfg = &(whal_Stm32wbRcc_Cfg) { + .flash = &wbFlash, + .flashLatency = WHAL_STM32WB_FLASH_LATENCY_3, + + .sysClkSrc = WHAL_STM32WB_RCC_SYSCLK_SRC_PLL, + .sysClkCfg = &(whal_Stm32wbRcc_PllClkCfg) + { + .clkSrc = WHAL_STM32WB_RCC_PLLCLK_SRC_MSI, + /* 64 MHz */ + .n = 32, + .m = 0, + .r = 1, + .q = 0, + .p = 0, + }, + }, +}; + +/* Internal flash mapping used by wolfBoot. */ +whal_Flash wbFlash = { + WHAL_STM32WB55_FLASH_DEVICE, + + .cfg = &(whal_Stm32wbFlash_Cfg) { + .clkCtrl = &wbClockController, + .clk = &(whal_Stm32wbRcc_Clk){WHAL_STM32WB55_FLASH_CLOCK}, + + .startAddr = 0x08000000, + .size = 0x100000, + }, +}; + +#ifndef WOLFHAL_NO_GPIO +/* GPIO pin configuration: LED on PB5 and optional UART1 pins. */ +whal_Stm32wbGpio_PinCfg pinCfg[] = { + { /* LED */ + .port = WHAL_STM32WB_GPIO_PORT_B, + .pin = 5, + .mode = WHAL_STM32WB_GPIO_MODE_OUT, + .outType = WHAL_STM32WB_GPIO_OUTTYPE_PUSHPULL, + .speed = WHAL_STM32WB_GPIO_SPEED_LOW, + .pull = WHAL_STM32WB_GPIO_PULL_UP, + .altFn = 0, + }, +#if defined(DEBUG_UART) || defined(UART_FLASH) + { /* UART1 TX */ + .port = WHAL_STM32WB_GPIO_PORT_B, + .pin = 6, + .mode = WHAL_STM32WB_GPIO_MODE_ALTFN, + .outType = WHAL_STM32WB_GPIO_OUTTYPE_PUSHPULL, + .speed = WHAL_STM32WB_GPIO_SPEED_FAST, + .pull = WHAL_STM32WB_GPIO_PULL_UP, + .altFn = 7, + }, + { /* UART1 RX */ + .port = WHAL_STM32WB_GPIO_PORT_B, + .pin = 7, + .mode = WHAL_STM32WB_GPIO_MODE_ALTFN, + .outType = WHAL_STM32WB_GPIO_OUTTYPE_PUSHPULL, + .speed = WHAL_STM32WB_GPIO_SPEED_FAST, + .pull = WHAL_STM32WB_GPIO_PULL_UP, + .altFn = 7, + }, +#endif /* DEBUG_UART || UART_FLASH */ +}; + +/* GPIO controller for configured pins. */ +whal_Gpio wbGpio = { + WHAL_STM32WB55_GPIO_DEVICE, + + .cfg = &(whal_Stm32wbGpio_Cfg) { + .clkCtrl = &wbClockController, + .clk = &(whal_Stm32wbRcc_Clk) {WHAL_STM32WB55_GPIOB_CLOCK}, + + .pinCfg = pinCfg, + .pinCount = sizeof(pinCfg) / sizeof(whal_Stm32wbGpio_PinCfg), + }, +}; +#endif + +#if defined(DEBUG_UART) || defined(UART_FLASH) +/* UART1 configuration for debug/flash operations. */ +whal_Uart wbUart = { + WHAL_STM32WB55_UART1_DEVICE, + + .cfg = &(whal_Stm32wbUart_Cfg){ + .clkCtrl = &wbClockController, + .clk = &(whal_Stm32wbRcc_Clk) {WHAL_STM32WB55_UART1_CLOCK}, + + .baud = 115200, + }, +}; +#endif /* DEBUG_UART || UART_FLASH */ diff --git a/hal/wolfHAL/stm32wb55_nucleo.mk b/hal/wolfHAL/stm32wb55_nucleo.mk new file mode 100644 index 0000000000..b26337a850 --- /dev/null +++ b/hal/wolfHAL/stm32wb55_nucleo.mk @@ -0,0 +1,25 @@ +CFLAGS += -DWHAL_CFG_NO_CALLBACKS=1 + +OBJS += $(WOLFBOOT_LIB_WOLFHAL)/src/reg.o + +OBJS += $(WOLFBOOT_LIB_WOLFHAL)/src/clock/stm32wb_rcc.o \ + $(WOLFBOOT_LIB_WOLFHAL)/src/flash/stm32wb_flash.o + +ifeq ($(DEBUG_UART),1) +endif + +APP_OBJS += $(WOLFBOOT_LIB_WOLFHAL)/src/reg.o + +APP_OBJS += $(WOLFBOOT_LIB_WOLFHAL)/src/clock/stm32wb_rcc.o \ + $(WOLFBOOT_LIB_WOLFHAL)/src/flash/stm32wb_flash.o + + +ifeq ($(WOLFHAL_NO_GPIO),) + OBJS += $(WOLFBOOT_LIB_WOLFHAL)/src/gpio/stm32wb_gpio.o + APP_OBJS += $(WOLFBOOT_LIB_WOLFHAL)/src/gpio/stm32wb_gpio.o +endif + +ifeq ($(DEBUG_UART),1) + OBJS += $(WOLFBOOT_LIB_WOLFHAL)/src/uart/stm32wb_uart.o + APP_OBJS += $(WOLFBOOT_LIB_WOLFHAL)/src/uart/stm32wb_uart.o +endif diff --git a/hal/wolfhal.c b/hal/wolfhal.c new file mode 100644 index 0000000000..4e90354837 --- /dev/null +++ b/hal/wolfhal.c @@ -0,0 +1,78 @@ +/* stm32wb.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 +#include "image.h" + +extern whal_Clock wbClockController; +#ifndef WOLFHAL_NO_GPIO +extern whal_Gpio wbGpio; +#endif +extern whal_Flash wbFlash; +#if defined(DEBUG_UART) || defined(UART_FLASH) +extern whal_Uart wbUart; +#endif /* DEBUG_UART || UART_FLASH */ + +void hal_init(void) +{ + whal_Error err; + + err = whal_Clock_Init(&wbClockController); + if (err) { + return; + } + +#ifndef WOLFHAL_NO_GPIO + err = whal_Gpio_Init(&wbGpio); + if (err) { + return; + } +#endif + + err = whal_Flash_Init(&wbFlash); + if (err) { + return; + } + +#if defined(DEBUG_UART) || defined(UART_FLASH) + err = whal_Uart_Init(&wbUart); + if (err) { + return; + } +#endif /* DEBUG_UART || UART_FLASH */ + +} + +void hal_prepare_boot(void) +{ +#if defined(DEBUG_UART) || defined(UART_FLASH) + whal_Uart_Deinit(&wbUart); +#endif /* DEBUG_UART || UART_FLASH */ + + whal_Flash_Deinit(&wbFlash); + +#ifndef WOLFHAL_NO_GPIO + whal_Gpio_Deinit(&wbGpio); +#endif + + whal_Clock_Deinit(&wbClockController); +} diff --git a/include/hal.h b/include/hal.h index 1804e05465..f746f0d147 100644 --- a/include/hal.h +++ b/include/hal.h @@ -31,6 +31,17 @@ extern "C" { #include "target.h" #include +#ifdef TARGET_wolfhal +#include +extern whal_Clock wbClockController; +extern whal_Flash wbFlash; +extern whal_Flash wbFlash; +extern whal_Gpio wbGpio; +#if defined(DEBUG_UART) || defined(UART_FLASH) +extern whal_Uart wbUart; +#endif /* DEBUG_UART || UART_FLASH */ +#endif + /* Architecture specific calls */ #ifdef MMU extern void do_boot(const uint32_t *app_offset, const uint32_t* dts_offset); @@ -62,13 +73,23 @@ uint64_t hal_get_timer_us(void); typedef uintptr_t haladdr_t; /* 64-bit platforms */ int hal_flash_write(uintptr_t address, const uint8_t *data, int len); int hal_flash_erase(uintptr_t address, int len); +#elif TARGET_wolfhal + #define hal_flash_write(address, data, len) whal_Flash_Write(&wbFlash, address, data, len) + #define hal_flash_erase(address, len) whal_Flash_Erase(&wbFlash, address, len) #else typedef uint32_t haladdr_t; /* original 32-bit */ int hal_flash_write(uint32_t address, const uint8_t *data, int len); int hal_flash_erase(uint32_t address, int len); #endif + +#ifdef TARGET_wolfhal + #define hal_flash_unlock() whal_Flash_Unlock(&wbFlash, WOLFHAL_FLASH_START, WOLFHAL_FLASH_SIZE) + #define hal_flash_lock() whal_Flash_Lock(&wbFlash, WOLFHAL_FLASH_START, WOLFHAL_FLASH_SIZE) +#else void hal_flash_unlock(void); void hal_flash_lock(void); +#endif + void hal_prepare_boot(void); #ifdef DUALBANK_SWAP diff --git a/lib/wolfHAL b/lib/wolfHAL new file mode 160000 index 0000000000..76f4822837 --- /dev/null +++ b/lib/wolfHAL @@ -0,0 +1 @@ +Subproject commit 76f48228379465113fac6a90a31affb311849752 diff --git a/options.mk b/options.mk index d55dd160c4..ece18cb0ea 100644 --- a/options.mk +++ b/options.mk @@ -1145,3 +1145,15 @@ endif ifeq ($(TZEN),1) CFLAGS+=-DTZEN endif + +ifneq ($(WOLFHAL_FLASH_START),) + CFLAGS+=-DWOLFHAL_FLASH_START=$(WOLFHAL_FLASH_START) +endif + +ifneq ($(WOLFHAL_FLASH_SIZE),) + CFLAGS+=-DWOLFHAL_FLASH_SIZE=$(WOLFHAL_FLASH_SIZE) +endif + +ifneq ($(WOLFHAL_NO_GPIO),) + CFLAGS+=-DWOLFHAL_NO_GPIO=$(WOLFHAL_NO_GPIO) +endif diff --git a/test-app/Makefile b/test-app/Makefile index d2e39d218b..82829ac5c0 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -64,6 +64,13 @@ else endif endif +ifeq ($(TARGET),wolfhal) + WOLFBOOT_LIB_WOLFHAL?=../lib/wolfHAL + CFLAGS += -I$(WOLFBOOT_LIB_WOLFHAL) + APP_OBJS += ../hal/wolfHAL/$(WOLFHAL_BOARD).o + include ../hal/wolfHAL/$(WOLFHAL_BOARD).mk +endif + include ../arch.mk # Setup default linker flags diff --git a/test-app/app_wolfhal.c b/test-app/app_wolfhal.c new file mode 100644 index 0000000000..af7a1ea0b0 --- /dev/null +++ b/test-app/app_wolfhal.c @@ -0,0 +1,95 @@ +/* main.c + * + * Test bare-metal boot-led-on 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 + */ +#define WOLFBOOT_FIXED_PARTITIONS + +#include +#include +#include +#include "wolfboot/wolfboot.h" +#include +#include "target.h" +#include "hal.h" + +#ifdef TARGET_wolfhal + +#define BOOT_LED_PIN 0 + +extern whal_Clock wbClock; +#ifndef WOLFHAL_NO_GPIO +extern whal_Gpio wbGpio; +#endif +extern whal_Flash wbFlash; +#if defined(DEBUG_UART) || defined(UART_FLASH) +extern whal_Uart wbUart; +#endif /* DEBUG_UART || UART_FLASH */ + +/* Matches all keys: + * - chacha (32 + 12) + * - aes128 (16 + 16) + * - aes256 (32 + 16) + */ +/* Longest key possible: AES256 (32 key + 16 IV = 48) */ +char enc_key[] = "0123456789abcdef0123456789abcdef" + "0123456789abcdef"; + +volatile uint32_t time_elapsed = 0; +void main(void) { + uint32_t version; + uint32_t l = 0; + uint32_t updv; + + hal_init(); + +#ifndef WOLFHAL_NO_GPIO + whal_Gpio_Set(&wbGpio, BOOT_LED_PIN, 1); +#endif + + version = wolfBoot_current_firmware_version(); + updv = wolfBoot_update_firmware_version(); + +#if defined(DEBUG_UART) || defined(UART_FLASH) + whal_Uart_Send(&wbUart, "*", 1); + whal_Uart_Send(&wbUart, (uint8_t *)&version, 4); +#endif /* DEBUG_UART || UART_FLASH */ + + if ((version == 1) && (updv != 8)) { + uint32_t sz; +#ifndef WOLFHAL_NO_GPIO + whal_Gpio_Set(&wbGpio, BOOT_LED_PIN, 0); +#endif +#if EXT_ENCRYPTED + wolfBoot_set_encrypt_key((uint8_t *)enc_key,(uint8_t *)(enc_key + 32)); +#endif + wolfBoot_update_trigger(); +#ifndef WOLFHAL_NO_GPIO + whal_Gpio_Set(&wbGpio, BOOT_LED_PIN, 1); +#endif + } else { + if (version != 7) + wolfBoot_success(); + } + /* Wait for reboot */ + while(1) + asm volatile("wfi"); +} +#endif /** PLATFROM_wolfhal **/