diff --git a/.github/renode-test/stm32h753/CMakeLists.txt b/.github/renode-test/stm32h753/CMakeLists.txt new file mode 100644 index 0000000000..5bd077e496 --- /dev/null +++ b/.github/renode-test/stm32h753/CMakeLists.txt @@ -0,0 +1,108 @@ +cmake_minimum_required(VERSION 3.18) +project(wolfcrypt_stm32h753 LANGUAGES C ASM) + +set(WOLFSSL_ROOT "/opt/wolfssl" CACHE PATH "wolfSSL source") + +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +enable_language(ASM) + +# Include paths for CMSIS device headers and STM32 HAL +# Order matters: CMSIS must come before HAL +include_directories(BEFORE + ${CMAKE_SOURCE_DIR} + /opt/CMSIS_5/CMSIS/Core/Include # Core CMSIS (core_cm7.h, etc.) - must be first + /opt/cmsis-device-h7/Include # Device-specific CMSIS (stm32h7xx.h) + /opt/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Inc/Legacy + /opt/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Inc +) + +# STM32 HAL source files (minimal set for CRYP and HASH) +# Note: These files are cloned in the Dockerfile before CMake runs +set(HAL_SRC_DIR /opt/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Src) + +# Check if HAL directory exists, then add source files +if(EXISTS ${HAL_SRC_DIR}) + set(HAL_SOURCES + ${HAL_SRC_DIR}/stm32h7xx_hal.c + ${HAL_SRC_DIR}/stm32h7xx_hal_rcc.c + ${HAL_SRC_DIR}/stm32h7xx_hal_rcc_ex.c + ${HAL_SRC_DIR}/stm32h7xx_hal_cortex.c + ${HAL_SRC_DIR}/stm32h7xx_hal_dma.c + ${HAL_SRC_DIR}/stm32h7xx_hal_dma_ex.c + ${HAL_SRC_DIR}/stm32h7xx_hal_rng.c + # CRYP HAL files enabled for AES_GCM only + ${HAL_SRC_DIR}/stm32h7xx_hal_cryp.c + ${HAL_SRC_DIR}/stm32h7xx_hal_cryp_ex.c + # HASH HAL files disabled - Renode doesn't implement HASH peripheral + # ${HAL_SRC_DIR}/stm32h7xx_hal_hash.c + # ${HAL_SRC_DIR}/stm32h7xx_hal_hash_ex.c + ) +else() + message(WARNING "HAL source directory not found: ${HAL_SRC_DIR}") + set(HAL_SOURCES "") +endif() + +# wolfSSL build options +set(WOLFSSL_USER_SETTINGS ON CACHE BOOL "Use user_settings.h") +set(WOLFSSL_CRYPT_TESTS OFF CACHE BOOL "") +set(WOLFSSL_EXAMPLES OFF CACHE BOOL "") +set(BUILD_SHARED_LIBS OFF CACHE BOOL "") + +add_subdirectory(${WOLFSSL_ROOT} ${CMAKE_BINARY_DIR}/wolfssl-build EXCLUDE_FROM_ALL) +target_include_directories(wolfssl PRIVATE + /opt/CMSIS_5/CMSIS/Core/Include # Core CMSIS first + /opt/cmsis-device-h7/Include # Device CMSIS + /opt/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Inc/Legacy + /opt/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Inc + ${CMAKE_SOURCE_DIR} # For stm32h7xx_hal_conf.h +) +# Suppress the GENSEED_FORTEST warning (expected for emulation/test builds) +target_compile_options(wolfssl PRIVATE -Wno-cpp) + +# wolfSSL STM32 port source file (needed for HASH and CRYPTO hardware acceleration) +set(WOLFSSL_STM32_PORT_SRC ${WOLFSSL_ROOT}/wolfcrypt/src/port/st/stm32.c) + +add_executable(wolfcrypt_test.elf + startup_stm32h753.c + main.c + ${WOLFSSL_ROOT}/wolfcrypt/test/test.c + ${HAL_SOURCES} + ${WOLFSSL_STM32_PORT_SRC} +) + +target_include_directories(wolfcrypt_test.elf PRIVATE + ${CMAKE_SOURCE_DIR} + ${WOLFSSL_ROOT} + /opt/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Inc + /opt/STM32CubeH7/Drivers/STM32H7xx_HAL_Driver/Inc/Legacy +) + +target_compile_definitions(wolfcrypt_test.elf PRIVATE + WOLFSSL_USER_SETTINGS + STM32H753xx + USE_HAL_DRIVER + USE_HAL_CONF # Enable HAL configuration + # NO_AES_CBC is defined in user_settings.h, no need to define it here +) + +# HAL source files need the same compile options and must include stdint.h +# Disable all warnings for HAL files (third-party code we don't control) +set_source_files_properties(${HAL_SOURCES} PROPERTIES + COMPILE_FLAGS "-mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Os -include stdint.h -w" +) + +target_compile_options(wolfcrypt_test.elf PRIVATE + -mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard + -ffunction-sections -fdata-sections -Os +) + +target_link_options(wolfcrypt_test.elf PRIVATE + -T${CMAKE_SOURCE_DIR}/stm32h753.ld + -Wl,--gc-sections + -nostartfiles + -specs=nano.specs + -specs=nosys.specs +) + +target_link_libraries(wolfcrypt_test.elf PRIVATE wolfssl m c gcc nosys) + diff --git a/.github/renode-test/stm32h753/entrypoint.sh b/.github/renode-test/stm32h753/entrypoint.sh new file mode 100755 index 0000000000..312813910b --- /dev/null +++ b/.github/renode-test/stm32h753/entrypoint.sh @@ -0,0 +1,194 @@ +#!/bin/bash +set -euo pipefail + +LOG=/tmp/wolfcrypt-renode.log +TIMEOUT=300 # Maximum 5 minutes + +echo "Running wolfCrypt test in Renode..." + +# Try to find Renode binary in common installation locations +# When installed via .deb package, Renode is typically in /usr/bin/renode +RENODE_BIN="${RENODE_BIN:-$(command -v renode 2>/dev/null || true)}" +if [ -z "$RENODE_BIN" ]; then + # Check common installation paths (order matters - check standard locations first) + for path in /usr/bin/renode /usr/local/bin/renode /opt/renode/renode; do + if [ -x "$path" ]; then + RENODE_BIN="$path" + break + fi + done +fi + +if [ -z "$RENODE_BIN" ] || [ ! -x "$RENODE_BIN" ]; then + echo "Renode binary not found in image." + echo "Checked paths: /usr/bin/renode, /usr/local/bin/renode, /opt/renode/renode" + echo "PATH: $PATH" + which renode || echo "renode not in PATH" + exit 2 +fi + +echo "Using Renode binary: $RENODE_BIN" + +# Determine Renode root directory (where platforms/ directory is located) +if [ -d "/opt/renode/platforms" ]; then + RENODE_ROOT="/opt/renode" +elif [ -d "/usr/lib/renode/platforms" ]; then + RENODE_ROOT="/usr/lib/renode" +elif [ -d "/usr/share/renode/platforms" ]; then + RENODE_ROOT="/usr/share/renode" +else + # Try to find Renode root by checking where the binary is + RENODE_DIR=$(dirname "$(readlink -f "${RENODE_BIN}" 2>/dev/null || echo "${RENODE_BIN}")") + if [ -d "${RENODE_DIR}/../platforms" ]; then + RENODE_ROOT=$(readlink -f "${RENODE_DIR}/.." 2>/dev/null || echo "${RENODE_DIR}/..") + else + echo "Warning: Could not determine Renode root directory" + RENODE_ROOT="" + fi +fi + +# Set RENODE_ROOT environment variable (Renode uses this to find platform files) +if [ -n "$RENODE_ROOT" ]; then + export RENODE_ROOT + echo "Using Renode root: ${RENODE_ROOT}" + # Also create .renode-root file in firmware directory as backup + echo "${RENODE_ROOT}" > /opt/firmware/.renode-root + chmod 644 /opt/firmware/.renode-root +else + echo "ERROR: Could not determine Renode root directory" + exit 1 +fi + +# Verify platform file exists +PLATFORM_FILE="${RENODE_ROOT}/platforms/cpus/stm32h753.repl" +if [ ! -f "${PLATFORM_FILE}" ]; then + echo "ERROR: Platform file not found at ${PLATFORM_FILE}" + echo "Searching for platform files..." + find "${RENODE_ROOT}" -name "stm32h753.repl" 2>/dev/null | head -5 || true + exit 1 +fi + +echo "Platform file found at: ${PLATFORM_FILE}" + +# Change to firmware directory +cd /opt/firmware + +# Create a modified Renode script with absolute path to platform file +# This avoids the .renode-root file lookup issue +cat > /opt/firmware/run-renode-absolute.resc < "${LOG}" 2>&1 & +RENODE_PID=$! +echo "Renode PID: $RENODE_PID" + +# Monitor the log for completion, errors, and flush output frequently +START_TIME=$(date +%s) +RESULT="" +LAST_LOG_SIZE=0 + +while true; do + # Check if Renode is still running + if ! kill -0 "$RENODE_PID" 2>/dev/null; then + break + fi + + # Flush new log content to stdout (unbuffered) + if [ -f "${LOG}" ]; then + CURRENT_LOG_SIZE=$(stat -f%z "${LOG}" 2>/dev/null || stat -c%s "${LOG}" 2>/dev/null || echo 0) + if [ "$CURRENT_LOG_SIZE" -gt "$LAST_LOG_SIZE" ]; then + # Output new lines + tail -c +$((LAST_LOG_SIZE + 1)) "${LOG}" 2>/dev/null | head -c $((CURRENT_LOG_SIZE - LAST_LOG_SIZE)) + LAST_LOG_SIZE=$CURRENT_LOG_SIZE + fi + fi + + # Check for Renode errors (must check before completion to catch errors early) + if grep -q "\[ERROR\]" "${LOG}" 2>/dev/null; then + echo "" + echo "ERROR: Renode reported an error!" + RESULT="renode_error" + break + fi + + # Check for completion messages + if grep -q "=== wolfCrypt test passed! ===" "${LOG}" 2>/dev/null; then + RESULT="passed" + break + fi + + if grep -q "=== wolfCrypt test FAILED ===" "${LOG}" 2>/dev/null; then + RESULT="failed" + break + fi + + # Check timeout + CURRENT_TIME=$(date +%s) + ELAPSED=$((CURRENT_TIME - START_TIME)) + if [ "$ELAPSED" -ge "$TIMEOUT" ]; then + echo "" + echo "Timeout after ${TIMEOUT} seconds" + RESULT="timeout" + break + fi + + sleep 0.5 +done + +# Kill Renode if still running +if kill -0 "$RENODE_PID" 2>/dev/null; then + kill "$RENODE_PID" 2>/dev/null || true + wait "$RENODE_PID" 2>/dev/null || true +fi + +# Show the log output +cat "${LOG}" + +# Report result +case "$RESULT" in + passed) + echo "" + echo "wolfCrypt tests completed successfully." + exit 0 + ;; + failed) + echo "" + echo "wolfCrypt tests FAILED." + exit 1 + ;; + renode_error) + echo "" + echo "Renode reported an error - test aborted." + exit 1 + ;; + timeout) + echo "" + echo "wolfCrypt tests timed out after ${TIMEOUT} seconds." + exit 1 + ;; + *) + echo "" + echo "wolfCrypt tests did not report a result." + exit 1 + ;; +esac + diff --git a/.github/renode-test/stm32h753/main.c b/.github/renode-test/stm32h753/main.c new file mode 100644 index 0000000000..82eedb4f4a --- /dev/null +++ b/.github/renode-test/stm32h753/main.c @@ -0,0 +1,137 @@ +/* main.c - Entry point for wolfCrypt test on STM32H753 under Renode + * + * Runs the wolfCrypt test suite with output via USART3. + */ + +#include +#include +#include + +/* wolfCrypt test entry point */ +extern int wolfcrypt_test(void *args); + +/* USART3 registers (STM32H7) */ +#define USART3_BASE 0x40004800UL +#define USART3_CR1 (*(volatile uint32_t *)(USART3_BASE + 0x00)) +#define USART3_BRR (*(volatile uint32_t *)(USART3_BASE + 0x0C)) +#define USART3_ISR (*(volatile uint32_t *)(USART3_BASE + 0x1C)) +#define USART3_TDR (*(volatile uint32_t *)(USART3_BASE + 0x28)) + +#define USART_CR1_UE (1 << 0) +#define USART_CR1_TE (1 << 3) +#define USART_ISR_TXE (1 << 7) + +/* RCC registers for enabling USART3 clock */ +#define RCC_BASE 0x58024400UL +#define RCC_APB1LENR (*(volatile uint32_t *)(RCC_BASE + 0xE8)) +#define RCC_APB1LENR_USART3EN (1 << 18) + +static void uart_init(void) +{ + /* Enable USART3 clock */ + RCC_APB1LENR |= RCC_APB1LENR_USART3EN; + + /* Configure USART3: 115200 baud at 64MHz HSI */ + USART3_BRR = 64000000 / 115200; + USART3_CR1 = USART_CR1_UE | USART_CR1_TE; +} + +static void uart_putc(char c) +{ + while (!(USART3_ISR & USART_ISR_TXE)) + ; + USART3_TDR = c; +} + +static void uart_puts(const char *s) +{ + while (*s) { + if (*s == '\n') + uart_putc('\r'); + uart_putc(*s++); + } +} + +/* newlib _write syscall - redirects printf to UART */ +int _write(int fd, const char *buf, int len) +{ + (void)fd; + for (int i = 0; i < len; i++) { + if (buf[i] == '\n') + uart_putc('\r'); + uart_putc(buf[i]); + } + return len; +} + +/* Heap management for malloc - required by printf with format strings */ +extern char __heap_start__; +extern char __heap_end__; + +void *_sbrk(ptrdiff_t incr) +{ + static char *heap_ptr = NULL; + char *prev_heap_ptr; + + if (heap_ptr == NULL) { + heap_ptr = &__heap_start__; + } + + prev_heap_ptr = heap_ptr; + + if (heap_ptr + incr > &__heap_end__) { + /* Out of heap memory */ + return (void *)-1; + } + + heap_ptr += incr; + return prev_heap_ptr; +} + +/* Simple counter for time - used by GENSEED_FORTEST */ +static volatile uint32_t tick_counter = 0; + +/* time() stub for wolfSSL GENSEED_FORTEST */ +#include +time_t time(time_t *t) +{ + tick_counter += 12345; /* Simple pseudo-random increment */ + time_t val = (time_t)tick_counter; + if (t) + *t = val; + return val; +} + +/* Result variable - can be monitored by Renode at fixed address */ +volatile int test_result __attribute__((section(".data"))) = -1; +volatile int test_complete __attribute__((section(".data"))) = 0; + + +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + setvbuf(stdin, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + uart_init(); + uart_puts("\n\n=== Starting wolfCrypt test ===\n\n"); + + test_result = wolfcrypt_test(NULL); + test_complete = 1; + + if (test_result == 0) { + uart_puts("\n\n=== wolfCrypt test passed! ===\n"); + } else { + uart_puts("\n\n=== wolfCrypt test FAILED ===\n"); + } + + /* Spin forever after the test completes */ + while (1) { + __asm__ volatile ("wfi"); + } + + return test_result; +} + diff --git a/.github/renode-test/stm32h753/run-renode.resc b/.github/renode-test/stm32h753/run-renode.resc new file mode 100644 index 0000000000..662895456d --- /dev/null +++ b/.github/renode-test/stm32h753/run-renode.resc @@ -0,0 +1,20 @@ +# Renode test script for STM32H753 +# Note: @platforms/cpus/stm32h753.repl is relative to Renode root +# If RENODE_ROOT is set, Renode will use it; otherwise it looks for .renode-root file +using sysbus + +mach create "stm32h753" + +# Try relative path first (works if RENODE_ROOT or .renode-root is set correctly) +# If this fails, the absolute path will be tried in entrypoint.sh +machine LoadPlatformDescription @platforms/cpus/stm32h753.repl + +sysbus LoadELF @/opt/firmware/wolfcrypt_test.elf + +# Connect USART3 to the console for wolfCrypt output +showAnalyzer usart3 + +# Start emulation and run for a long time +# The entrypoint script will kill Renode when test completes +emulation RunFor "600s" + diff --git a/.github/renode-test/stm32h753/startup_stm32h753.c b/.github/renode-test/stm32h753/startup_stm32h753.c new file mode 100644 index 0000000000..2b9ac9a20c --- /dev/null +++ b/.github/renode-test/stm32h753/startup_stm32h753.c @@ -0,0 +1,102 @@ +/* Minimal startup code for STM32H753 running under Renode */ + +#include +#include + +extern int main(int argc, char** argv); + +void Default_Handler(void); +void Reset_Handler(void); + +/* Symbols provided by the linker script */ +extern unsigned long _estack; +extern unsigned long __data_start__; +extern unsigned long __data_end__; +extern unsigned long __bss_start__; +extern unsigned long __bss_end__; +extern unsigned long _sidata; /* start of .data in flash */ + +/* Minimal init_array support */ +extern void (*__preinit_array_start[])(void); +extern void (*__preinit_array_end[])(void); +extern void (*__init_array_start[])(void); +extern void (*__init_array_end[])(void); + +static void call_init_array(void) +{ + size_t count, i; + + count = __preinit_array_end - __preinit_array_start; + for (i = 0; i < count; i++) + __preinit_array_start[i](); + + count = __init_array_end - __init_array_start; + for (i = 0; i < count; i++) + __init_array_start[i](); +} + +void Reset_Handler(void) +{ + unsigned long *src, *dst; + + /* Copy .data from flash to RAM */ + src = &_sidata; + for (dst = &__data_start__; dst < &__data_end__;) + *dst++ = *src++; + + /* Zero .bss */ + for (dst = &__bss_start__; dst < &__bss_end__;) + *dst++ = 0; + + /* Call static constructors */ + call_init_array(); + + /* Call main */ + (void)main(0, (char**)0); + + /* Infinite loop after main returns */ + while (1) { + __asm__ volatile ("wfi"); + } +} + +void Default_Handler(void) +{ + while (1) { + __asm__ volatile ("wfi"); + } +} + +/* Exception handlers - all weak aliases to Default_Handler */ +__attribute__((weak, alias("Default_Handler"))) void NMI_Handler(void); +__attribute__((weak, alias("Default_Handler"))) void HardFault_Handler(void); +__attribute__((weak, alias("Default_Handler"))) void MemManage_Handler(void); +__attribute__((weak, alias("Default_Handler"))) void BusFault_Handler(void); +__attribute__((weak, alias("Default_Handler"))) void UsageFault_Handler(void); +__attribute__((weak, alias("Default_Handler"))) void SVC_Handler(void); +__attribute__((weak, alias("Default_Handler"))) void DebugMon_Handler(void); +__attribute__((weak, alias("Default_Handler"))) void PendSV_Handler(void); +__attribute__((weak, alias("Default_Handler"))) void SysTick_Handler(void); + +/* Vector table */ +__attribute__ ((section(".isr_vector"), used)) +void (* const g_pfnVectors[])(void) = { + (void (*)(void))(&_estack), /* Initial stack pointer */ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler /* SysTick Handler */ + /* IRQ vectors would continue here */ +}; + diff --git a/.github/renode-test/stm32h753/stm32h753.ld b/.github/renode-test/stm32h753/stm32h753.ld new file mode 100644 index 0000000000..5900f3eed3 --- /dev/null +++ b/.github/renode-test/stm32h753/stm32h753.ld @@ -0,0 +1,109 @@ +/* Minimal STM32H753 memory map for Renode run */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + DTCM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K + RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 512K +} + +_estack = ORIGIN(RAM) + LENGTH(RAM); +_Min_Heap_Size = 128K; +_Min_Stack_Size = 128K; + +ENTRY(Reset_Handler) + +SECTIONS +{ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) + . = ALIGN(4); + } > FLASH + + .text : + { + . = ALIGN(4); + *(.text*) + *(.rodata*) + *(.glue_7) + *(.glue_7t) + *(.eh_frame) + . = ALIGN(4); + _etext = .; + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > FLASH + + .preinit_array : + { + PROVIDE_HIDDEN(__preinit_array_start = .); + KEEP(*(.preinit_array*)) + PROVIDE_HIDDEN(__preinit_array_end = .); + } > FLASH + + .init_array : + { + PROVIDE_HIDDEN(__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array*)) + PROVIDE_HIDDEN(__init_array_end = .); + } > FLASH + + .fini_array : + { + PROVIDE_HIDDEN(__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array*)) + PROVIDE_HIDDEN(__fini_array_end = .); + } > FLASH + + /* Location in flash where .data will be stored */ + _sidata = LOADADDR(.data); + + .data : + { + . = ALIGN(4); + __data_start__ = .; + *(.data*) + . = ALIGN(4); + __data_end__ = .; + } > RAM AT> FLASH + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap_stack (NOLOAD): + { + . = ALIGN(8); + PROVIDE(__heap_start__ = .); + . = . + _Min_Heap_Size; + PROVIDE(__heap_end__ = .); + PROVIDE(end = __heap_end__); + . = ALIGN(8); + PROVIDE(__stack_start__ = .); + . = . + _Min_Stack_Size; + PROVIDE(__stack_end__ = .); + } > RAM +} + +PROVIDE(_init = 0); +PROVIDE(_fini = 0); + diff --git a/.github/renode-test/stm32h753/stm32h7xx_hal_conf.h b/.github/renode-test/stm32h753/stm32h7xx_hal_conf.h new file mode 100644 index 0000000000..eb6430b167 --- /dev/null +++ b/.github/renode-test/stm32h753/stm32h7xx_hal_conf.h @@ -0,0 +1,208 @@ +/* Minimal HAL configuration for STM32H753 wolfCrypt build under Renode. + * RNG and CRYP HAL are enabled. CRYP is used for AES_GCM only (other AES modes disabled). + * HASH is disabled as Renode doesn't implement it. + */ + +#ifndef STM32H7xx_HAL_CONF_H +#define STM32H7xx_HAL_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------------- Module Selection ----------------------------- */ +#define HAL_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_RNG_MODULE_ENABLED +#define HAL_CRYP_MODULE_ENABLED /* Enabled for AES_GCM only */ +/* #define HAL_HASH_MODULE_ENABLED */ /* Disabled - Renode doesn't implement HASH */ +#define HAL_DMA_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED + +/* Disabled modules (explicit for clarity) */ +/* #define HAL_SDRAM_MODULE_ENABLED */ + +/* ------------------------- Oscillator Values ---------------------------- */ +#if !defined(HSE_VALUE) +#define HSE_VALUE 25000000UL /* External oscillator frequency in Hz */ +#endif + +#if !defined(HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT 100UL /* Time out for HSE start up in ms */ +#endif + +#if !defined(CSI_VALUE) +#define CSI_VALUE 4000000UL /* Internal oscillator CSI in Hz */ +#endif + +#if !defined(HSI_VALUE) +#define HSI_VALUE 64000000UL /* Internal oscillator HSI in Hz */ +#endif + +#if !defined(HSI48_VALUE) +#define HSI48_VALUE 48000000UL /* Value of the Internal High Speed oscillator for USB in Hz */ +#endif + +#if !defined(LSE_VALUE) +#define LSE_VALUE 32768UL /* External low speed oscillator in Hz */ +#endif + +#if !defined(LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT 5000UL /* Time out for LSE start up in ms */ +#endif + +#if !defined(LSI_VALUE) +#define LSI_VALUE 32000UL /* Internal low speed oscillator in Hz */ +#endif + +#if !defined(EXTERNAL_CLOCK_VALUE) +#define EXTERNAL_CLOCK_VALUE 12288000UL /* External audio clock in Hz */ +#endif + +/* ------------------------- System Configuration -------------------------- */ +#define VDD_VALUE 3300UL /* Value of VDD in mV */ +#define TICK_INT_PRIORITY 0x0FUL /* Tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U +#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U +#define USE_HAL_DMA_REGISTER_CALLBACKS 0U +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U +#define USE_HAL_DTS_REGISTER_CALLBACKS 0U +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U +#define USE_HAL_FMAC_REGISTER_CALLBACKS 0U +#define USE_HAL_GFXMMU_REGISTER_CALLBACKS 0U +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U +#define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U +#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U +#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U +#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U +#define USE_HAL_OSPI_REGISTER_CALLBACKS 0U +#define USE_HAL_OTFDEC_REGISTER_CALLBACKS 0U +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U +#define USE_HAL_PSSI_REGISTER_CALLBACKS 0U +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U +#define USE_HAL_SD_REGISTER_CALLBACKS 0U +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U +#define USE_HAL_SWPMI_REGISTER_CALLBACKS 0U +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U +#define USE_HAL_UART_REGISTER_CALLBACKS 0U +#define USE_HAL_USART_REGISTER_CALLBACKS 0U +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U +#define USE_HAL_XSPI_REGISTER_CALLBACKS 0U + +/* ------------------------- SPI peripheral configuration ------------------ */ +#define USE_SPI_CRC 0U + +/* ------------------------- Assertion ------------------------------------- */ +/* #define USE_FULL_ASSERT 1U */ +#define assert_param(expr) ((void)0U) + +/* ------------------------- Ethernet Configuration ------------------------ */ +#define ETH_TX_DESC_CNT 4U +#define ETH_RX_DESC_CNT 4U +#define ETH_MAC_ADDR0 0x02U +#define ETH_MAC_ADDR1 0x00U +#define ETH_MAC_ADDR2 0x00U +#define ETH_MAC_ADDR3 0x00U +#define ETH_MAC_ADDR4 0x00U +#define ETH_MAC_ADDR5 0x00U + +/* ------------------------- Include HAL headers --------------------------- */ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32h7xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32h7xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32h7xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32h7xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32h7xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32h7xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32h7xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32h7xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +/* CRYP enabled for AES_GCM only */ +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32h7xx_hal_cryp.h" +#endif + +/* #ifdef HAL_HASH_MODULE_ENABLED + #include "stm32h7xx_hal_hash.h" +#endif */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t *file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7xx_HAL_CONF_H */ + diff --git a/.github/renode-test/stm32h753/toolchain-arm-none-eabi.cmake b/.github/renode-test/stm32h753/toolchain-arm-none-eabi.cmake new file mode 100644 index 0000000000..1ea559a576 --- /dev/null +++ b/.github/renode-test/stm32h753/toolchain-arm-none-eabi.cmake @@ -0,0 +1,24 @@ +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR arm) + +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set(CMAKE_C_COMPILER arm-none-eabi-gcc) +set(CMAKE_CXX_COMPILER arm-none-eabi-g++) +set(CMAKE_ASM_COMPILER arm-none-eabi-gcc) + +set(CMAKE_AR arm-none-eabi-ar) +set(CMAKE_RANLIB arm-none-eabi-ranlib) + +set(CMAKE_C_STANDARD 11) + +set(CPU_FLAGS "-mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard") +set(OPT_FLAGS "-Os -ffunction-sections -fdata-sections") +set(CMSIS_INCLUDES "-I/opt/cmsis-device-h7/Include -I/opt/CMSIS_5/CMSIS/Core/Include -I/opt/firmware") + +set(CMAKE_C_FLAGS_INIT "${CPU_FLAGS} ${OPT_FLAGS} ${CMSIS_INCLUDES} -DSTM32H753xx") +set(CMAKE_CXX_FLAGS_INIT "${CPU_FLAGS} ${OPT_FLAGS} ${CMSIS_INCLUDES} -DSTM32H753xx") +set(CMAKE_ASM_FLAGS_INIT "${CPU_FLAGS}") + +set(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,--gc-sections -static") + diff --git a/.github/renode-test/stm32h753/user_settings.h b/.github/renode-test/stm32h753/user_settings.h new file mode 100644 index 0000000000..19ac73b4fc --- /dev/null +++ b/.github/renode-test/stm32h753/user_settings.h @@ -0,0 +1,95 @@ +/* user_settings_renode.h - wolfSSL/wolfCrypt configuration for STM32H753 under Renode + * + * Minimal, semihosting-friendly build for Cortex-M7 / STM32H753. + * Hardware RNG and CRYPTO (AES-GCM only) are enabled via Renode's STM32H753 emulation. + * HASH is disabled as Renode doesn't implement the HASH peripheral. + */ + +#ifndef USER_SETTINGS_RENODE_H +#define USER_SETTINGS_RENODE_H + +/* ------------------------- Platform ------------------------------------- */ +#define WOLFSSL_ARM_CORTEX_M +#define WOLFSSL_STM32H7 /* STM32H7 series (includes H753) */ +#define WOLFSSL_STM32_CUBEMX /* Use STM32 HAL for CRYPTO */ +/* NO_STM32_CRYPTO is NOT defined, so CRYPTO will be enabled */ +/* Disable HASH - Renode doesn't implement HASH peripheral */ +#define NO_STM32_HASH + +/* Required for consistent math library settings (CTC_SETTINGS) */ +#define SIZEOF_LONG 4 +#define SIZEOF_LONG_LONG 8 + +/* ------------------------- Threading / OS ------------------------------- */ +#define SINGLE_THREADED + +/* ------------------------- Filesystem / I/O ----------------------------- */ +#define WOLFSSL_NO_CURRDIR +#define NO_FILESYSTEM +#define NO_WRITEV + +/* ------------------------- wolfCrypt Only ------------------------------- */ +#define WOLFCRYPT_ONLY +#define NO_DH +#define NO_DSA +/* Disable DES/3DES - Renode CRYPTO only supports AES_GCM */ +#define NO_DES +#define NO_DES3 + +/* ------------------------- AES Mode Configuration ----------------------- */ +/* Disable all AES modes except GCM - Renode CRYPTO only supports AES_GCM */ +/* NO_AES_CBC prevents HAVE_AES_CBC from being defined in settings.h */ +#define NO_AES_CBC + +/* ------------------------- RNG Configuration ---------------------------- */ +/* Enable STM32 hardware RNG (emulated by Renode) using direct register access */ +#define WOLFSSL_STM32_RNG_NOLIB +/* NO_STM32_RNG is NOT defined, so STM32_RNG will be auto-enabled */ +#define NO_DEV_RANDOM +#define HAVE_HASHDRBG + +/* ------------------------- Math Library --------------------------------- */ +/* Use SP Math (Single Precision) - modern, efficient, and secure */ +#define WOLFSSL_SP_MATH_ALL +#define WOLFSSL_HAVE_SP_RSA +#define WOLFSSL_HAVE_SP_DH +#define WOLFSSL_HAVE_SP_ECC +#define WOLFSSL_SP_ARM_CORTEX_M_ASM +#define SP_WORD_SIZE 32 + +/* ------------------------- Crypto Hardening ----------------------------- */ +#define WC_RSA_BLINDING +#define ECC_TIMING_RESISTANT + +/* ------------------------- Size Optimization ---------------------------- */ +#define WOLFSSL_SMALL_STACK + +/* ------------------------- Test Configuration --------------------------- */ +/* Use smaller key sizes for faster test runs in emulation */ +#define BENCH_EMBEDDED + +/* Use our own main() instead of the one in test.c */ +#define NO_MAIN_DRIVER + +/* ------------------------- Post-options.h cleanup ----------------------- */ +/* Ensure unsupported AES modes stay disabled even after options.h processing */ +/* These undefs will be processed after options.h includes, preventing + * Renode-unsupported modes from being used */ +#ifdef HAVE_AES_CBC +#undef HAVE_AES_CBC +#endif +#ifdef HAVE_AES_ECB +#undef HAVE_AES_ECB +#endif +#ifdef HAVE_AES_CTR +#undef HAVE_AES_CTR +#endif +#ifdef HAVE_AES_CFB +#undef HAVE_AES_CFB +#endif +#ifdef HAVE_AES_OFB +#undef HAVE_AES_OFB +#endif + +#endif /* USER_SETTINGS_RENODE_H */ + diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 00b64013d5..e188e2e70f 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -23,7 +23,7 @@ jobs: check_filenames: true check_hidden: true # Add comma separated list of words that occur multiple times that should be ignored (sorted alphabetically, case sensitive) - ignore_words_list: adin,aNULL,brunch,carryIn,chainG,ciph,cLen,cliKs,dout,haveA,inCreated,inOut,inout,larg,LEAPYEAR,Merget,optionA,parm,parms,repid,rIn,userA,ser,siz,te,Te, + ignore_words_list: adin,aNULL,brunch,carryIn,chainG,ciph,cLen,cliKs,dout,haveA,inCreated,inOut,inout,larg,LEAPYEAR,Merget,optionA,parm,parms,repid,rIn,userA,ser,siz,te,Te,HSI, # The exclude_file contains lines of code that should be ignored. This is useful for individual lines which have non-words that can safely be ignored. exclude_file: '.codespellexcludelines' # To skip files entirely from being processed, add it to the following list: diff --git a/.github/workflows/renode-stm32h753.yml b/.github/workflows/renode-stm32h753.yml new file mode 100644 index 0000000000..4fa8d872d7 --- /dev/null +++ b/.github/workflows/renode-stm32h753.yml @@ -0,0 +1,271 @@ +name: Renode STM32H753 Test + +# Platform-specific configuration +# To add a new platform, create a new workflow file based on this template +# and update these variables for the target MCU +env: + PLATFORM_NAME: stm32h753 + PLATFORM_DISPLAY_NAME: STM32H753 + CMSIS_DEVICE_REPO: cmsis-device-h7 + CMSIS_DEVICE_PATH: /opt/cmsis-device-h7 + CMSIS_DEVICE_CACHE_KEY: cmsis-device-h7-v1 + STM32CUBE_REPO: STM32CubeH7 + STM32CUBE_BRANCH: v1.11.2 + STM32CUBE_PATH: /opt/STM32CubeH7 + STM32CUBE_CACHE_KEY: stm32cubeh7-v1.11.2-v1 + HAL_CONFIG_FILE: stm32h7xx_hal_conf.h + HAL_DRIVER_INC_PATH: STM32H7xx_HAL_Driver/Inc + HAL_DRIVER_SRC_PATH: STM32H7xx_HAL_Driver/Src + RENODE_PLATFORM_NAME: stm32h753 + RENODE_REPL_PATH: platforms/cpus/stm32h753.repl + RENODE_TEST_DIR: .github/renode-test/stm32h753 + +on: + push: + branches: [ main, master, develop ] + pull_request: + branches: [ main, master, develop ] + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout wolfSSL + uses: actions/checkout@v4 + + - name: Set up build environment + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + cmake \ + ninja-build \ + python3 \ + git \ + gcc-arm-none-eabi \ + libnewlib-arm-none-eabi \ + libstdc++-arm-none-eabi-newlib \ + wget \ + unzip + + - name: Cache CMSIS Device + id: cache-cmsis-device + uses: actions/cache@v4 + with: + path: ${{ env.CMSIS_DEVICE_PATH }} + key: ${{ env.CMSIS_DEVICE_CACHE_KEY }} + restore-keys: | + ${{ env.CMSIS_DEVICE_CACHE_KEY }}- + + - name: Cache CMSIS 5 + id: cache-cmsis-5 + uses: actions/cache@v4 + with: + path: /opt/CMSIS_5 + key: cmsis-5-v1 + restore-keys: | + cmsis-5- + + - name: Cache STM32Cube + id: cache-stm32cube + uses: actions/cache@v4 + with: + path: ${{ env.STM32CUBE_PATH }} + key: ${{ env.STM32CUBE_CACHE_KEY }} + restore-keys: | + ${{ env.STM32CUBE_CACHE_KEY }}- + + - name: Cache Renode + id: cache-renode + uses: actions/cache@v4 + with: + path: /opt/renode + key: renode-1.15.3-v1 + restore-keys: | + renode-1.15.3- + + - name: Install Renode dependencies + run: | + # Install Mono and other dependencies needed for Renode (always needed, even when cached) + sudo apt-get install -y --no-install-recommends \ + mono-runtime \ + libmono-cil-dev \ + screen \ + policykit-1 || true + + - name: Install Renode (if not cached) + if: steps.cache-renode.outputs.cache-hit != 'true' + run: | + # Install Renode by extracting .deb (avoids GUI dependency issues for headless use) + cd /tmp + wget -q https://github.com/renode/renode/releases/download/v1.15.3/renode_1.15.3_amd64.deb + # Extract the .deb file + dpkg-deb -x renode_1.15.3_amd64.deb /tmp/renode-extract + # Copy Renode files to system locations + sudo mkdir -p /opt/renode + sudo cp -r /tmp/renode-extract/opt/renode/* /opt/renode/ || true + sudo cp -r /tmp/renode-extract/usr/* /usr/ || true + # Create symlink for easy access + if [ -f /opt/renode/renode ]; then + sudo ln -sf /opt/renode/renode /usr/local/bin/renode + elif [ -f /usr/bin/renode ]; then + echo "Renode already in PATH at /usr/bin/renode" + fi + # Cleanup + rm -rf /tmp/renode-extract renode_1.15.3_amd64.deb + + - name: Setup Renode symlinks and permissions + run: | + # When Renode is cached, we need to recreate /usr/bin/renode wrapper script + # The /usr/bin/renode is a wrapper that checks Mono and calls /opt/renode/bin/Renode.exe + if [ -d /opt/renode ] && [ ! -x /usr/bin/renode ]; then + echo "Renode cached but /usr/bin/renode wrapper missing, recreating..." + # Create the wrapper script + sudo bash -c 'cat > /usr/bin/renode << '\''SCRIPT_EOF'\'' + #!/bin/sh + MONOVERSION=5.20 + REQUIRED_MAJOR=5 + REQUIRED_MINOR=20 + + LAUNCHER=mono + + if ! [ -x "$(command -v $LAUNCHER)" ] + then + echo "$LAUNCHER not found. Renode requires Mono $MONOVERSION or newer. Please refer to documentation for installation instructions. Exiting!" + exit 1 + fi + + # Check installed mono version + INSTALLED_MONO=`$LAUNCHER --version | head -n1 | cut -d'\'' '\'' -f5` + INSTALLED_MONO_MAJOR=`echo $INSTALLED_MONO | cut -d'\''.'\'' -f1` + INSTALLED_MONO_MINOR=`echo $INSTALLED_MONO | cut -d'\''.'\'' -f2` + + if [ $INSTALLED_MONO_MAJOR -lt $REQUIRED_MAJOR ] || [ $INSTALLED_MONO_MAJOR -eq $REQUIRED_MAJOR -a $INSTALLED_MONO_MINOR -lt $REQUIRED_MINOR ] + then + echo "Wrong Mono version detected: $INSTALLED_MONO. Renode requires Mono $MONOVERSION or newer. Please refer to documentation for installation instructions. Exiting!" + exit 1 + fi + + exec $LAUNCHER $MONO_OPTIONS /opt/renode/bin/Renode.exe "$@" + SCRIPT_EOF' + sudo chmod +x /usr/bin/renode + echo "Created /usr/bin/renode wrapper script" + fi + + # Also ensure /usr/local/bin/renode symlink exists + if [ -x /usr/bin/renode ] && [ ! -x /usr/local/bin/renode ]; then + sudo ln -sf /usr/bin/renode /usr/local/bin/renode + echo "Created symlink: /usr/local/bin/renode -> /usr/bin/renode" + fi + + - name: Verify Renode installation + run: | + # Verify Renode is installed and accessible + RENODE_FOUND=false + RENODE_BIN="" + + # Check various possible locations + for path in /opt/renode/renode /opt/renode/bin/renode /usr/local/bin/renode /usr/bin/renode; do + if [ -x "$path" ]; then + echo "Renode found at $path" + "$path" --version || true + RENODE_BIN="$path" + RENODE_FOUND=true + break + fi + done + + if [ "$RENODE_FOUND" != "true" ]; then + echo "ERROR: Renode binary not found or not executable!" + echo "Searching for renode..." + find /opt /usr -name renode -type f 2>/dev/null | head -10 || true + echo "Checking /opt/renode contents:" + ls -la /opt/renode/ 2>/dev/null | head -10 || true + if [ -d /opt/renode ]; then + echo "Checking /opt/renode subdirectories:" + find /opt/renode -type f -name "*renode*" 2>/dev/null | head -10 || true + fi + exit 1 + fi + + + - name: Clone CMSIS Device (if not cached) + if: steps.cache-cmsis-device.outputs.cache-hit != 'true' + run: | + sudo mkdir -p /opt + sudo git clone --depth 1 https://github.com/STMicroelectronics/${{ env.CMSIS_DEVICE_REPO }}.git ${{ env.CMSIS_DEVICE_PATH }} + + - name: Clone CMSIS 5 (if not cached) + if: steps.cache-cmsis-5.outputs.cache-hit != 'true' + run: | + sudo mkdir -p /opt + sudo git clone --depth 1 https://github.com/ARM-software/CMSIS_5.git /opt/CMSIS_5 + + - name: Clone STM32Cube (if not cached) + if: steps.cache-stm32cube.outputs.cache-hit != 'true' + run: | + sudo mkdir -p /opt + sudo git clone --depth 1 --branch ${{ env.STM32CUBE_BRANCH }} --recurse-submodules https://github.com/STMicroelectronics/${{ env.STM32CUBE_REPO }}.git ${{ env.STM32CUBE_PATH }} || \ + (sudo git clone --depth 1 --branch ${{ env.STM32CUBE_BRANCH }} https://github.com/STMicroelectronics/${{ env.STM32CUBE_REPO }}.git ${{ env.STM32CUBE_PATH }} && \ + cd ${{ env.STM32CUBE_PATH }} && sudo git submodule update --init --recursive --depth 1) + + - name: Setup firmware build directory and helper files + run: | + sudo mkdir -p /opt/firmware + # Copy helper files from repository + sudo cp -r ${{ github.workspace }}/${{ env.RENODE_TEST_DIR }}/* /opt/firmware/ + # Copy HAL config to STM32Cube directory + sudo cp /opt/firmware/${{ env.HAL_CONFIG_FILE }} ${{ env.STM32CUBE_PATH }}/Drivers/${{ env.HAL_DRIVER_INC_PATH }}/ 2>/dev/null || true + sudo chmod +x /opt/firmware/entrypoint.sh + # Create .renode-root file so Renode can find platform files + # Try to find Renode installation directory and create .renode-root with proper permissions + if [ -d "/opt/renode/platforms" ]; then + echo "/opt/renode" | sudo tee /opt/firmware/.renode-root > /dev/null + sudo chmod 644 /opt/firmware/.renode-root + elif [ -d "/usr/lib/renode/platforms" ]; then + echo "/usr/lib/renode" | sudo tee /opt/firmware/.renode-root > /dev/null + sudo chmod 644 /opt/firmware/.renode-root + elif [ -d "/usr/share/renode/platforms" ]; then + echo "/usr/share/renode" | sudo tee /opt/firmware/.renode-root > /dev/null + sudo chmod 644 /opt/firmware/.renode-root + fi + + - name: Build wolfSSL firmware (NOT CACHED - rebuilds on every run) + env: + WOLFSSL_ROOT: /opt/wolfssl + run: | + # Copy wolfSSL source (this is NOT cached - fresh checkout each time) + sudo cp -r ${{ github.workspace }} /opt/wolfssl + # Build with CMake + cd /opt/firmware + sudo cmake -G Ninja \ + -DWOLFSSL_USER_SETTINGS=ON \ + -DUSER_SETTINGS_FILE=/opt/firmware/user_settings.h \ + -DCMAKE_TOOLCHAIN_FILE=/opt/firmware/toolchain-arm-none-eabi.cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DWOLFSSL_CRYPT_TESTS=OFF \ + -DWOLFSSL_EXAMPLES=OFF \ + -B /opt/firmware/build \ + -S /opt/firmware + sudo cmake --build /opt/firmware/build + # Verify ELF file was created and copy it to expected location + if [ -f "/opt/firmware/build/wolfcrypt_test.elf" ]; then + sudo cp /opt/firmware/build/wolfcrypt_test.elf /opt/firmware/wolfcrypt_test.elf + echo "ELF file copied to /opt/firmware/wolfcrypt_test.elf" + ls -lh /opt/firmware/wolfcrypt_test.elf + else + echo "ERROR: ELF file not found at /opt/firmware/build/wolfcrypt_test.elf" + echo "Searching for ELF files..." + find /opt/firmware/build -name "*.elf" 2>/dev/null || true + exit 1 + fi + + - name: Run Renode test + run: | + # Ensure PATH includes standard binary locations for sudo + sudo env PATH="$PATH" /opt/firmware/entrypoint.sh +