From d12de2d6b446b04e7e76fd0c644f95eeab4201e7 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Thu, 3 Oct 2024 21:38:18 +0200 Subject: [PATCH] soc: silabs: Add soc_prep_hook() for Series 2 CMSIS SystemInit is not used in Zephyr. Implement the functionality that isn't already done by Zephyr startup using soc_prep_hook(). The reason the lack of TrustZone init did not create immediately obvious issues previously is that SMU faults can only happen if the SMU clock is enabled. Signed-off-by: Aksel Skauge Mellbye --- .../hal_silabs/simplicity_sdk/CMakeLists.txt | 4 -- soc/silabs/silabs_s2/Kconfig | 4 ++ soc/silabs/silabs_s2/efr32mg21/Kconfig | 1 + soc/silabs/silabs_s2/soc.c | 63 +++++++++++++++++++ west.yml | 2 +- 5 files changed, 69 insertions(+), 5 deletions(-) diff --git a/modules/hal_silabs/simplicity_sdk/CMakeLists.txt b/modules/hal_silabs/simplicity_sdk/CMakeLists.txt index e270d75ad17..949bf579447 100644 --- a/modules/hal_silabs/simplicity_sdk/CMakeLists.txt +++ b/modules/hal_silabs/simplicity_sdk/CMakeLists.txt @@ -119,10 +119,6 @@ zephyr_compile_definitions_ifdef(CONFIG_SOC_GECKO_DEV_INIT SL_CATALOG_HFXO_MANAGER_PRESENT ) -zephyr_compile_options( - -mcmse # Cortex-M Security Extensions are needed for startup code -) - zephyr_library_sources( ${DEVICE_DIR}/SiliconLabs/${SILABS_DEVICE_FAMILY}/Source/system_${CONFIG_SOC_SERIES}.c ${EMLIB_DIR}/src/em_system.c diff --git a/soc/silabs/silabs_s2/Kconfig b/soc/silabs/silabs_s2/Kconfig index f105aaf5f49..f25bec21491 100644 --- a/soc/silabs/silabs_s2/Kconfig +++ b/soc/silabs/silabs_s2/Kconfig @@ -6,8 +6,12 @@ if SOC_FAMILY_SILABS_S2 config SOC_FAMILY_SILABS_S2 select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select BUILD_OUTPUT_HEX + select SOC_PREP_HOOK select SOC_EARLY_INIT_HOOK rsource "*/Kconfig" +config ARM_SECURE_FIRMWARE + default y + endif diff --git a/soc/silabs/silabs_s2/efr32mg21/Kconfig b/soc/silabs/silabs_s2/efr32mg21/Kconfig index 0e34a386b14..db3f7e6ae66 100644 --- a/soc/silabs/silabs_s2/efr32mg21/Kconfig +++ b/soc/silabs/silabs_s2/efr32mg21/Kconfig @@ -6,6 +6,7 @@ config SOC_SERIES_EFR32MG21 select CPU_CORTEX_M33 select CPU_CORTEX_M_HAS_DWT select ARMV8_M_DSP + select ARM_TRUSTZONE_M select CPU_HAS_FPU select CPU_HAS_ARM_MPU select CPU_HAS_ARM_SAU diff --git a/soc/silabs/silabs_s2/soc.c b/soc/silabs/silabs_s2/soc.c index 7d503aa27ad..a6ad018bc43 100644 --- a/soc/silabs/silabs_s2/soc.c +++ b/soc/silabs/silabs_s2/soc.c @@ -18,6 +18,18 @@ #include #include +#if defined(CONFIG_PRINTK) || defined(CONFIG_LOG) +#define PR_EXC(...) LOG_ERR(__VA_ARGS__) +#else +#define PR_EXC(...) +#endif /* CONFIG_PRINTK || CONFIG_LOG */ + +#if (CONFIG_FAULT_DUMP == 2) +#define PR_FAULT_INFO(...) PR_EXC(__VA_ARGS__) +#else +#define PR_FAULT_INFO(...) +#endif + LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); void soc_early_init_hook(void) @@ -35,3 +47,54 @@ void soc_early_init_hook(void) sl_hfxo_manager_init(); } } + +#if defined(CONFIG_ARM_SECURE_FIRMWARE) && !defined(CONFIG_ARM_FIRMWARE_HAS_SECURE_ENTRY_FUNCS) +static void smu_fault(void) +{ + PR_FAULT_INFO("***** SMU FAULT *****"); + + if (SMU->IF & SMU_IF_BMPUSEC) { + PR_FAULT_INFO("Bus Manager Fault"); + PR_EXC("SMU.BMPUFS=%d", SMU->BMPUFS); + } + if (SMU->IF & SMU_IF_PPUSEC) { + PR_FAULT_INFO("Peripheral Access Fault"); + PR_EXC("SMU.PPUFS=%d", SMU->PPUFS); + } + + z_fatal_error(K_ERR_CPU_EXCEPTION, NULL); +} +#endif + +void soc_prep_hook(void) +{ + /* Initialize TrustZone state of the device. + * If this is a secure app with no non-secure callable functions, it is a secure-only app. + * Configure all peripherals except the SMU and SEMAILBOX to non-secure aliases, and make + * all bus transactions from the CPU have non-secure attribution. + * This makes the secure-only app behave more like a non-secure app, allowing the use of + * libraries that only expect to use non-secure peripherals, such as the radio subsystem. + */ +#if defined(CONFIG_ARM_SECURE_FIRMWARE) && !defined(CONFIG_ARM_FIRMWARE_HAS_SECURE_ENTRY_FUNCS) +#if defined(CMU_CLKEN1_SMU) + CMU_S->CLKEN1_SET = CMU_CLKEN1_SMU; +#endif + SMU->PPUSATD0_CLR = _SMU_PPUSATD0_MASK; +#if defined(SEMAILBOX_PRESENT) + SMU->PPUSATD1_CLR = (_SMU_PPUSATD1_MASK & (~SMU_PPUSATD1_SMU & ~SMU_PPUSATD1_SEMAILBOX)); +#else + SMU->PPUSATD1_CLR = (_SMU_PPUSATD1_MASK & ~SMU_PPUSATD1_SMU); +#endif + + SAU->CTRL = SAU_CTRL_ALLNS_Msk; + __DSB(); + __ISB(); + + NVIC_ClearPendingIRQ(SMU_SECURE_IRQn); + SMU->IF_CLR = SMU_IF_PPUSEC | SMU_IF_BMPUSEC; + SMU->IEN = SMU_IEN_PPUSEC | SMU_IEN_BMPUSEC; + + IRQ_DIRECT_CONNECT(SMU_SECURE_IRQn, 0, smu_fault, 0); + irq_enable(SMU_SECURE_IRQn); +#endif +} diff --git a/west.yml b/west.yml index e4abd856235..557cea2ff26 100644 --- a/west.yml +++ b/west.yml @@ -223,7 +223,7 @@ manifest: groups: - hal - name: hal_silabs - revision: 5c7a7834a6df7882518a2da127f950d80987dfcb + revision: 69a5fad41aced94dc59d3103edd6ef370851e623 path: modules/hal/silabs groups: - hal