From 43c2e3dd79d2308a683d0c08a2849dfc44b6250a Mon Sep 17 00:00:00 2001 From: David Garske Date: Sat, 23 May 2020 11:11:55 -0700 Subject: [PATCH] Experimental support for STM32L5 --- arch.mk | 16 + config/examples/stm32l5.config | 24 ++ docs/HAL.md | 2 +- docs/Targets.md | 42 ++- hal/stm32l5.c | 539 +++++++++++++++++++++++++++++++++ hal/stm32l5.ld | 19 +- hal/stm32l5_ns.c | 404 ++++++++++++++++++++++++ hal/stm32l5_partition.h | 422 ++++++++++++++++++++++++++ src/boot_arm.c | 182 ++++++++++- test-app/ARM-stm32l5.ld | 47 +++ test-app/Makefile | 12 +- test-app/app_stm32l5.c | 105 +++++++ test-app/startup_arm.c | 116 ++++++- tools/config.mk | 2 +- 14 files changed, 1902 insertions(+), 30 deletions(-) create mode 100644 config/examples/stm32l5.config create mode 100644 hal/stm32l5.c create mode 100644 hal/stm32l5_ns.c create mode 100644 hal/stm32l5_partition.h create mode 100644 test-app/ARM-stm32l5.ld create mode 100644 test-app/app_stm32l5.c diff --git a/arch.mk b/arch.mk index 1a7bc34f..d8098609 100644 --- a/arch.mk +++ b/arch.mk @@ -74,7 +74,22 @@ ifeq ($(ARCH),ARM) SPI_TARGET=stm32 endif + ifeq ($(TARGET),stm32l5) + CORTEX_M33=1 + CFLAGS+=-Ihal + endif + ## Cortex-M CPU + ifeq ($(CORTEX_M33),1) + CFLAGS+=-mcpu=cortex-m33 + LDFLAGS+=-mcpu=cortex-m33 + ifeq ($(TZEN),1) + CFLAGS += -mcmse + endif + ifeq ($(SPMATH),1) + MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o + endif + else ifeq ($(CORTEX_M0),1) CFLAGS+=-mcpu=cortex-m0 LDFLAGS+=-mcpu=cortex-m0 @@ -98,6 +113,7 @@ ifeq ($(ARCH),ARM) endif endif endif +endif ## RISCV ifeq ($(ARCH),RISCV) diff --git a/config/examples/stm32l5.config b/config/examples/stm32l5.config new file mode 100644 index 00000000..0acd743d --- /dev/null +++ b/config/examples/stm32l5.config @@ -0,0 +1,24 @@ +ARCH?=ARM +TARGET?=stm32l5 +SIGN?=ECC256 +HASH?=SHA256 +DEBUG?=0 +VTOR?=1 +CORTEX_M0?=0 +CORTEX_M33?=1 +NO_ASM?=0 +EXT_FLASH?=0 +SPI_FLASH?=0 +ALLOW_DOWNGRADE?=0 +NVM_FLASH_WRITEONCE?=0 +WOLFBOOT_VERSION?=1 +V?=0 +SPMATH?=1 +RAM_CODE?=0 +DUALBANK_SWAP?=0 +IMAGE_HEADER_SIZE?=256 +WOLFBOOT_PARTITION_SIZE?=0xB000 +WOLFBOOT_SECTOR_SIZE?=0x800 +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x8040000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x805F800 +WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x807F800 diff --git a/docs/HAL.md b/docs/HAL.md index 3fe41bab..2c84e90c 100644 --- a/docs/HAL.md +++ b/docs/HAL.md @@ -19,7 +19,7 @@ and RAM boundaries. ## Supported platforms The following platforms are supported in the current version: - - STM32F4 + - STM32F4, STM32L5, STM32L0, STM32F7, STM32H7, STM32G0 - nRF52 - Atmel samR21 - TI cc26x2 diff --git a/docs/Targets.md b/docs/Targets.md index 2146e730..58db7a3f 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -2,7 +2,7 @@ This README describes configuration of supported targets. -## STM32-F407 +## STM32F407 Example 512KB partitioning on STM32-F407 @@ -61,6 +61,46 @@ b main c ``` +## STM32L5 + +### Example Description + +The implementation shows how to switch from secure application to non-secure application +thanks to the system isolation performed to split the internal Flash and internal SRAM memories +into two halves: + - the first half for the secure application + - the second half for the non-secure application + +### Hardware and Software environment + +- This example runs on STM32L562QEIxQ devices with security enabled (TZEN=1). +- This example has been tested with STMicroelectronics STM32L562E-DK (MB1373) +- User Option Bytes requirement (with STM32CubeProgrammer tool - see below for instructions) + +``` +TZEN = 1 System with TrustZone-M enabled +DBANK = 1 Dual bank mode +SECWM1_PSTRT=0x0 SECWM1_PEND=0x7F All 128 pages of internal Flash Bank1 set as secure +SECWM2_PSTRT=0x1 SECWM2_PEND=0x0 No page of internal Flash Bank2 set as secure, hence Bank2 non-secure +``` + +- NOTE: STM32CubeProgrammer V2.3.0 is recommended (v2.4.0 has a known bug for STM32L5) +- typical path: C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin + +### How to use it + +1. `cp ./config/examples/stm32l5.config .config` +2. `make TZEN=1` +3. Prepare board with option bytes configuration reported above + - `STM32_Programmer_CLI.exe -c port=swd mode=hotplug -ob TZEN=1 DBANK=1` + - `STM32_Programmer_CLI.exe -c port=swd mode=hotplug -ob SECWM1_PSTRT=0x0 SECWM1_PEND=0x7F SECWM2_PSTRT=0x1 SECWM2_PEND=0x0` +4. flash wolfBoot.bin to 0xc000 0000 + - STM32_Programmer_CLI.exe -c port=swd -d .\wolfboot.bin 0xC000000 +5. `flash .\test-app\image_v1_signed.bin to 0x8040000` + - `STM32_Programmer_CLI.exe -c port=swd -d .\test-app\image_v1_signed.bin 0x8040000` +6. RED LD9 will be on + + ## STM32L0x3 Example 192KB partitioning on STM32-L073 diff --git a/hal/stm32l5.c b/hal/stm32l5.c new file mode 100644 index 00000000..72566a3e --- /dev/null +++ b/hal/stm32l5.c @@ -0,0 +1,539 @@ +/* stm32l5.c + * + * Copyright (C) 2020 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 + */ + +#include +#include +#include "stm32l5_partition.h" + +/* Assembly helpers */ +#define DMB() __asm__ volatile ("dmb") +#define ISB() __asm__ volatile ("isb") +#define DSB() __asm__ volatile ("dsb") + +/* STM32 L5 register configuration */ +/*!< Memory & Instance aliases and base addresses for Non-Secure/Secure peripherals */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/*Secure */ +#define RCC_BASE (0x50021000) //RM0438 - Table 4 +#else +/*Non-Secure */ +#define RCC_BASE (0x40021000) //RM0438 - Table 4 +#endif + +#define RCC_CR (*(volatile uint32_t *)(RCC_BASE + 0x00)) //RM0438 - Table 77 +#define RCC_CR_PLLRDY (1 << 25) //RM0438 - 9.8.1 +#define RCC_CR_PLLON (1 << 24) //RM0438 - 9.8.1 +#define RCC_CR_HSEBYP (1 << 18) //RM0438 - 9.8.1 +#define RCC_CR_HSERDY (1 << 17) //RM0438 - 9.8.1 +#define RCC_CR_HSEON (1 << 16) //RM0438 - 9.8.1 +#define RCC_CR_HSIRDY (1 << 10) //RM0438 - 9.8.1 +#define RCC_CR_HSION (1 << 8) //RM0438 - 9.8.1 +#define RCC_CR_MSIRANGE_SHIFT (4) //RM0438 - 9.8.1 +#define RCC_CR_MSIRANGE_11 (11) +#define RCC_CR_MSIRGSEL (1 << 3) //RM0438 - 9.8.1 +#define RCC_CR_MSIPLLEN (1 << 2) //RM0438 - 9.8.1 +#define RCC_CR_MSIRDY (1 << 1) //RM0438 - 9.8.1 +#define RCC_CR_MSION (1 << 0) //RM0438 - 9.8.1 + + +#define RCC_CFGR (*(volatile uint32_t *)(RCC_BASE + 0x08)) //RM0438 - Table 77 + +/*** APB1&2 PRESCALER ***/ +#define RCC_APB_PRESCALER_DIV_NONE 0x0 // 0xx: HCLK not divided +#define RCC_APB_PRESCALER_DIV_2 0x4 // 100: HCLK divided by 2 +#define RCC_APB_PRESCALER_DIV_4 0x5 // 101: HCLK divided by 4 +#define RCC_APB_PRESCALER_DIV_8 0x6 // 110: HCLK divided by 8 +#define RCC_APB_PRESCALER_DIV_16 0x7 // 111: HCLK divided by 16 + +/*** AHB PRESCALER ***/ +#define RCC_AHB_PRESCALER_DIV_NONE 0x0 // 0xxx: SYSCLK not divided +#define RCC_AHB_PRESCALER_DIV_2 0x8 // 1000: SYSCLK divided by 2 +#define RCC_AHB_PRESCALER_DIV_4 0x9 // 1001: SYSCLK divided by 4 +#define RCC_AHB_PRESCALER_DIV_8 0xA // 1010: SYSCLK divided by 8 +#define RCC_AHB_PRESCALER_DIV_16 0xB // 1011: SYSCLK divided by 16 +#define RCC_AHB_PRESCALER_DIV_64 0xC // 1100: SYSCLK divided by 64 +#define RCC_AHB_PRESCALER_DIV_128 0xD // 1101: SYSCLK divided by 128 +#define RCC_AHB_PRESCALER_DIV_256 0xE // 1110: SYSCLK divided by 256 +#define RCC_AHB_PRESCALER_DIV_512 0xF // 1111: SYSCLK divided by 512 + +#define RCC_CFGR_HPRE_SHIFT (0x04) +#define RCC_CFGR_PPRE2_SHIFT (0x0B) +#define RCC_CFGR_PPRE1_SHIFT (0x08) + +#define RCC_CFGR_SW_MSI 0x0 +#define RCC_CFGR_SW_HSI16 0x1 +#define RCC_CFGR_SW_HSE 0x2 +#define RCC_CFGR_SW_PLL 0x3 + +#define RCC_PLLCFGR (*(volatile uint32_t *)(RCC_BASE + 0x0C)) //RM0438 - Table 77 +#define RCC_PLLCFGR_PLLP_SHIFT (27) +#define RCC_PLLCFGR_PLLR_SHIFT (25) +#define RCC_PLLCFGR_PLLREN (1 << 24) + +#define RCC_PLLCFGR_PLLQ_SHIFT (21) +#define RCC_PLLCFGR_PLLQEN (1 << 20) + +#define RCC_PLLCFGR_PLLN_SHIFT (8) +#define RCC_PLLCFGR_PLLM_SHIFT (4) + +#define RCC_PLLCFGR_QR_DIV_2 0x0 +#define RCC_PLLCFGR_QR_DIV_4 0x1 +#define RCC_PLLCFGR_QR_DIV_6 0x2 +#define RCC_PLLCFGR_QR_DIV_8 0x3 + +#define RCC_PLLCFGR_P_DIV_7 0x0 +#define RCC_PLLCFGR_P_DIV_17 0x1 + +#define RCC_PLLCKSELR_PLLSRC_NONE 0x0 +#define RCC_PLLCKSELR_PLLSRC_MSI 0x1 +#define RCC_PLLCKSELR_PLLSRC_HSI16 0x2 +#define RCC_PLLCKSELR_PLLSRC_HSE 0x3 + +#define RCC_APB1ENR (*(volatile uint32_t *)(RCC_BASE + 0x58)) +#define RCC_APB1ENR_PWREN (1 << 28) + +#define RCC_APB2ENR (*(volatile uint32_t *)(RCC_BASE + 0x60)) +#define RCC_APB2ENR_SYSCFGEN (1 << 0) + + +/*** PWR ***/ +/*!< Memory & Instance aliases and base addresses for Non-Secure/Secure peripherals */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/*Secure */ +#define PWR_BASE (0x50007000) //RM0438 - Table 4 +#else +/*Non-Secure */ +#define PWR_BASE (0x40007000) //RM0438 - Table 4 +#endif + +#define PWR_CR1 (*(volatile uint32_t *)(PWR_BASE + 0x00)) +#define PWR_CR1_VOS_SHIFT (9) +#define PWR_CR1_VOS_0 (0x0) +#define PWR_CR1_VOS_1 (0x1) +#define PWR_CR1_VOS_2 (0x2) + +#define PWR_CR2 (*(volatile uint32_t *)(PWR_BASE + 0x04)) +#define PWR_CR2_IOSV (1 << 9) +#define PWR_CR3 (*(volatile uint32_t *)(PWR_BASE + 0x08)) +#define PWR_CR3_UCPD_DBDIS (1 << 14) +#define PWR_CR4 (*(volatile uint32_t *)(PWR_BASE + 0x0C)) + +#define PWR_SR1 (*(volatile uint32_t *)(PWR_BASE + 0x10)) +#define PWR_SR2 (*(volatile uint32_t *)(PWR_BASE + 0x14)) +#define PWR_SR2_VOSF (1 << 10) + +#define SYSCFG_BASE (0x50010000) //RM0438 - Table 4 + + + +/*** FLASH ***/ +#define SYSCFG_APB2_CLOCK_ER_VAL (1 << 0) //RM0438 - RCC_APB2ENR - SYSCFGEN + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/*Secure*/ +#define FLASH_BASE (0x50022000) //RM0438 - Table 4 +#define FLASH_KEYR (*(volatile uint32_t *)(FLASH_BASE + 0x0C)) +#define FLASH_SR (*(volatile uint32_t *)(FLASH_BASE + 0x24)) +#define FLASH_CR (*(volatile uint32_t *)(FLASH_BASE + 0x2C)) + +/* Register values */ +#define FLASH_SR_EOP (1 << 0) +#define FLASH_SR_OPERR (1 << 1) +#define FLASH_SR_PROGERR (1 << 3) +#define FLASH_SR_WRPERR (1 << 4) +#define FLASH_SR_PGAERR (1 << 5) +#define FLASH_SR_SIZERR (1 << 6) +#define FLASH_SR_PGSERR (1 << 7) +#define FLASH_SR_BSY (1 << 16) + +#define FLASH_CR_PG (1 << 0) +#define FLASH_CR_PER (1 << 1) +#define FLASH_CR_MER1 (1 << 2) +#define FLASH_CR_PNB_SHIFT 3 +#define FLASH_CR_PNB_MASK 0x7F +#define FLASH_CR_BKER (1 << 11) +#define FLASH_CR_MER2 (1 << 15) +#define FLASH_CR_STRT (1 << 16) +#define FLASH_CR_EOPIE (1 << 24) +#define FLASH_CR_ERRIE (1 << 25) +#define FLASH_CR_INV (1 << 29) +#define FLASH_CR_LOCK (1 << 31) + + +#else +/*Non-Secure*/ +#define FLASH_BASE (0x40022000) //RM0438 - Table 4 +#define FLASH_KEYR (*(volatile uint32_t *)(FLASH_BASE + 0x08)) +#define FLASH_SR (*(volatile uint32_t *)(FLASH_BASE + 0x20)) +#define FLASH_CR (*(volatile uint32_t *)(FLASH_BASE + 0x28)) + +/* Register values */ +#define FLASH_SR_EOP (1 << 0) +#define FLASH_SR_OPERR (1 << 1) +#define FLASH_SR_PROGERR (1 << 3) +#define FLASH_SR_WRPERR (1 << 4) +#define FLASH_SR_PGAERR (1 << 5) +#define FLASH_SR_SIZERR (1 << 6) +#define FLASH_SR_PGSERR (1 << 7) +#define FLASH_SR_OPTWERR (1 << 13) +#define FLASH_SR_BSY (1 << 16) + +#define FLASH_CR_PG (1 << 0) +#define FLASH_CR_PER (1 << 1) +#define FLASH_CR_MER1 (1 << 2) +#define FLASH_CR_PNB_SHIFT 3 +#define FLASH_CR_PNB_MASK 0x7F +#define FLASH_CR_BKER (1 << 11) +#define FLASH_CR_MER2 (1 << 15) +#define FLASH_CR_STRT (1 << 16) +#define FLASH_CR_OPTSTRT (1 << 17) +#define FLASH_CR_EOPIE (1 << 24) +#define FLASH_CR_ERRIE (1 << 25) +#define FLASH_CR_OBL_LAUNCH (1 << 27) +#define FLASH_CR_OPTLOCK (1 << 30) +#define FLASH_CR_LOCK (1 << 31) +#endif + +#define FLASH_ACR (*(volatile uint32_t *)(FLASH_BASE + 0x00)) +#define FLASH_ACR_LATENCY_MASK (0x0F) + +#define FLASHMEM_ADDRESS_SPACE (0x08000000) +#define FLASH_PAGE_SIZE (0x800) /* 2KB */ +#define FLASH_BANK2_BASE (0x08040000) /*!< Base address of Flash Bank2 */ +#define FLASH_TOP (0x0807FFFF) /*!< FLASH end address */ + +#define FLASH_KEY1 (0x45670123) +#define FLASH_KEY2 (0xCDEF89AB) + +/* GPIO*/ +#define GPIOD_BASE 0x52020C00 +#define GPIOG_BASE 0x52021800 + +#define GPIOD_SECCFGR (*(volatile uint32_t *)(GPIOD_BASE + 0x30)) +#define GPIOG_SECCFGR (*(volatile uint32_t *)(GPIOG_BASE + 0x30)) + +#define LED_BOOT_PIN (12) //PG12 - Discovery - Green Led +#define LED_USR_PIN (3) //PD3 - Discovery - Red Led + +#define RCC_AHB2_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0x4C )) +#define GPIOG_AHB2_CLOCK_ER (1 << 6) +#define GPIOD_AHB2_CLOCK_ER (1 << 3) + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +#define SCS_BASE (0xE000E000UL) +#define SCB_BASE (SCS_BASE + 0x0D00UL) +#define SCB_SHCSR (*(volatile uint32_t *)(SCB_BASE + 0x24)) +#define SCB_SHCSR_SECUREFAULT_EN (1<<19) + +#endif + +static void RAMFUNCTION flash_set_waitstates(unsigned int waitstates) +{ + uint32_t reg = FLASH_ACR; + if ((reg & FLASH_ACR_LATENCY_MASK) != waitstates) + FLASH_ACR = (reg & ~FLASH_ACR_LATENCY_MASK) | waitstates ; +} + +static RAMFUNCTION void flash_wait_complete(uint8_t bank) +{ + while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY); + +} + +static void RAMFUNCTION flash_clear_errors(uint8_t bank) +{ + + FLASH_SR |= ( FLASH_SR_OPERR | FLASH_SR_PROGERR | FLASH_SR_WRPERR |FLASH_SR_PGAERR | FLASH_SR_SIZERR | FLASH_SR_PGSERR +#if !(defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) + | + FLASH_SR_OPTWERR +#endif + ) ; + +} + + +int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len) +{ + int i = 0; + uint32_t *src, *dst; + + flash_clear_errors(0); + + src = (uint32_t *)data; + dst = (uint32_t *)(address + FLASHMEM_ADDRESS_SPACE); + + while (i < len) { + FLASH_CR |= FLASH_CR_PG; + dst[i >> 2] = src[i >> 2]; + dst[(i >> 2) + 1] = src[(i >> 2) + 1]; + flash_wait_complete(0); + FLASH_CR &= ~FLASH_CR_PG; + i+=8; + } + + return 0; +} + +void RAMFUNCTION hal_flash_unlock(void) +{ + flash_wait_complete(0); + if ((FLASH_CR & FLASH_CR_LOCK) != 0) { + FLASH_KEYR = FLASH_KEY1; + DMB(); + FLASH_KEYR = FLASH_KEY2; + DMB(); + while ((FLASH_CR & FLASH_CR_LOCK) != 0) + ; + } + +} + +void RAMFUNCTION hal_flash_lock(void) +{ + flash_wait_complete(0); + if ((FLASH_CR & FLASH_CR_LOCK) == 0) + FLASH_CR |= FLASH_CR_LOCK; +} + +int RAMFUNCTION hal_flash_erase(uint32_t address, int len) +{ + uint32_t end_address; + uint32_t p; + + flash_clear_errors(0); + + if (len == 0) + return -1; + end_address = address + len - 1; + for (p = address; p < end_address; p += FLASH_PAGE_SIZE) { + // considering DBANK = 1 + if (p < (FLASH_BANK2_BASE -FLASHMEM_ADDRESS_SPACE) ) + { + FLASH_CR &= ~FLASH_CR_BKER; + } + if(p>=(FLASH_BANK2_BASE -FLASHMEM_ADDRESS_SPACE) && (p <= (FLASH_TOP -FLASHMEM_ADDRESS_SPACE) )) + { + FLASH_CR |= FLASH_CR_BKER; + } + + uint32_t reg = FLASH_CR & (~((FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT)| FLASH_CR_PER)); + FLASH_CR = reg | (((p >> 11) << FLASH_CR_PNB_SHIFT) | FLASH_CR_PER ); + DMB(); + FLASH_CR |= FLASH_CR_STRT; + flash_wait_complete(0); + } + + /* If the erase operation is completed, disable the associated bits */ + FLASH_CR &= ~FLASH_CR_PER ; + + return 0; +} + +static void clock_pll_off(void) +{ + uint32_t reg32; + + /* Select MSI as SYSCLK source. */ + reg32 = RCC_CFGR; + reg32 &= ~((1 << 1) | (1 << 0)); + RCC_CFGR = (reg32 | RCC_CFGR_SW_MSI); + DMB(); + + /* Wait for MSI clock to be selected. */ + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SW_MSI) {}; + + /* Turn off PLL */ + RCC_CR &= ~RCC_CR_PLLON; + DMB(); +} + +/*This implementation will setup MSI 48 MHz as PLL Source Mux, PLLCLK as System Clock Source*/ + +static void clock_pll_on(int powersave) +{ + uint32_t reg32; + uint32_t plln, pllm, pllq, pllp, pllr, hpre, apb1pre, apb2pre , flash_waitstates; + + RCC_APB2ENR |= RCC_APB2ENR_SYSCFGEN; + RCC_APB1ENR |= RCC_APB1ENR_PWREN; + PWR_CR3 |= PWR_CR3_UCPD_DBDIS; + + PWR_CR1 &= ~((1 << 10) | (1 << 9)); + PWR_CR1 |= (PWR_CR1_VOS_0 << PWR_CR1_VOS_SHIFT); + /* Delay after setting the voltage scaling */ + reg32 = PWR_CR1; + while ((PWR_SR2 & PWR_SR2_VOSF)) {}; + + while ((RCC_CR & RCC_CR_MSIRDY) == 0) {}; + flash_waitstates = 2; + flash_set_waitstates(flash_waitstates); + + RCC_CR |= RCC_CR_MSIRGSEL; + + reg32 = RCC_CR; + reg32 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4)); + reg32 |= (RCC_CR_MSIRANGE_11 << RCC_CR_MSIRANGE_SHIFT); + RCC_CR = reg32; + reg32 = RCC_CR; + DMB(); + + + /* Select clock parameters (CPU Speed = 110 MHz) */ + pllm = 12; + plln = 55; + pllp = 7; + pllq = RCC_PLLCFGR_QR_DIV_2; + pllr = RCC_PLLCFGR_QR_DIV_2; + hpre = RCC_AHB_PRESCALER_DIV_NONE; + apb1pre = RCC_APB_PRESCALER_DIV_NONE; + apb2pre = RCC_APB_PRESCALER_DIV_NONE; + flash_waitstates = 5; + + RCC_CR &= ~RCC_CR_PLLON; + while ((RCC_CR & RCC_CR_PLLRDY) != 0) {}; + + /*PLL Clock source selection*/ + reg32 = RCC_PLLCFGR ; + reg32 |= RCC_PLLCKSELR_PLLSRC_MSI; + reg32 |= ((pllm-1) << RCC_PLLCFGR_PLLM_SHIFT); + reg32 |= ((plln) << RCC_PLLCFGR_PLLN_SHIFT); + reg32 |= ((pllp) << RCC_PLLCFGR_PLLP_SHIFT); + reg32 |= ((pllq) << RCC_PLLCFGR_PLLQ_SHIFT); + reg32 |= ((pllr) << RCC_PLLCFGR_PLLR_SHIFT); + RCC_PLLCFGR = reg32; + DMB(); + + RCC_CR |= RCC_CR_PLLON; + while ((RCC_CR & RCC_CR_PLLRDY) == 0) {}; + + RCC_PLLCFGR |= RCC_PLLCFGR_PLLREN; + + flash_set_waitstates(flash_waitstates); + + /*step down HPRE before going to >80MHz*/ + reg32 = RCC_CFGR ; + reg32 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4)); + reg32 |= ((RCC_AHB_PRESCALER_DIV_2) << RCC_CFGR_HPRE_SHIFT) ; + RCC_CFGR = reg32; + DMB(); + + /* Select PLL as SYSCLK source. */ + reg32 = RCC_CFGR; + reg32 &= ~((1 << 1) | (1 << 0)); + RCC_CFGR = (reg32 | RCC_CFGR_SW_PLL); + DMB(); + + /* Wait for PLL clock to be selected. */ + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SW_PLL) {}; + + /*step-up HPRE to go > 80MHz*/ + reg32 = RCC_CFGR ; + reg32 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4)); + reg32 |= ((hpre) << RCC_CFGR_HPRE_SHIFT) ; + RCC_CFGR = reg32; + DMB(); + + /*PRE1 and PRE2 conf*/ + reg32 = RCC_CFGR ; + reg32 &= ~((1 << 10) | (1 << 9) | (1 << 8)); + reg32 |= ((apb1pre) << RCC_CFGR_PPRE1_SHIFT) ; + reg32 &= ~((1 << 13) | (1 << 12) | (1 << 11)); + reg32 |= ((apb2pre) << RCC_CFGR_PPRE2_SHIFT) ; + RCC_CFGR = reg32; + DMB(); + +} +static void gtzc_init(void) +{ + /*configure SRAM1 */ + SET_GTZC_MPCBBx_S_VCTR(1,0); + SET_GTZC_MPCBBx_S_VCTR(1,1); + SET_GTZC_MPCBBx_S_VCTR(1,2); + SET_GTZC_MPCBBx_S_VCTR(1,3); + SET_GTZC_MPCBBx_S_VCTR(1,4); + SET_GTZC_MPCBBx_S_VCTR(1,5); + SET_GTZC_MPCBBx_S_VCTR(1,6); + SET_GTZC_MPCBBx_S_VCTR(1,7); + SET_GTZC_MPCBBx_S_VCTR(1,8); + SET_GTZC_MPCBBx_S_VCTR(1,9); + SET_GTZC_MPCBBx_S_VCTR(1,10); + SET_GTZC_MPCBBx_S_VCTR(1,11); + SET_GTZC_MPCBBx_S_VCTR(1,12); + SET_GTZC_MPCBBx_S_VCTR(1,13); + SET_GTZC_MPCBBx_S_VCTR(1,14); + SET_GTZC_MPCBBx_S_VCTR(1,15); + SET_GTZC_MPCBBx_S_VCTR(1,16); + SET_GTZC_MPCBBx_S_VCTR(1,17); + SET_GTZC_MPCBBx_S_VCTR(1,18); + SET_GTZC_MPCBBx_S_VCTR(1,19); + SET_GTZC_MPCBBx_S_VCTR(1,20); + SET_GTZC_MPCBBx_S_VCTR(1,21); + SET_GTZC_MPCBBx_S_VCTR(1,22); + SET_GTZC_MPCBBx_S_VCTR(1,23); + + /*configure SRAM2 */ + SET_GTZC_MPCBBx_S_VCTR(2,0); + SET_GTZC_MPCBBx_S_VCTR(2,1); + SET_GTZC_MPCBBx_S_VCTR(2,2); + SET_GTZC_MPCBBx_S_VCTR(2,3); + SET_GTZC_MPCBBx_S_VCTR(2,4); + SET_GTZC_MPCBBx_S_VCTR(2,5); + SET_GTZC_MPCBBx_S_VCTR(2,6); + SET_GTZC_MPCBBx_S_VCTR(2,7); + +} + +static void led_unsecure() +{ + uint32_t pin; + + /*Enable clock for User LED GPIOs */ + RCC_AHB2_CLOCK_ER|= GPIOD_AHB2_CLOCK_ER; + RCC_AHB2_CLOCK_ER|= GPIOG_AHB2_CLOCK_ER; + PWR_CR2 |= PWR_CR2_IOSV; + + /*Un-secure User LED GPIO pins */ + GPIOD_SECCFGR&=~(1< FLASH + } > FLASH _stored_data = .; .data : AT (_stored_data) { _start_data = .; KEEP(*(.data*)) - . = ALIGN(4); + . = ALIGN(8); KEEP(*(.ramcode)) - . = ALIGN(4); + . = ALIGN(8); _end_data = .; } > RAM @@ -33,12 +33,13 @@ SECTIONS __bss_start__ = .; *(.bss*) *(COMMON) - . = ALIGN(4); + . = ALIGN(8); _end_bss = .; __bss_end__ = .; _end = .; } > RAM - . = ALIGN(4); + . = ALIGN(8); + } END_STACK = ORIGIN(RAM) + LENGTH(RAM); diff --git a/hal/stm32l5_ns.c b/hal/stm32l5_ns.c new file mode 100644 index 00000000..c387d6eb --- /dev/null +++ b/hal/stm32l5_ns.c @@ -0,0 +1,404 @@ +/* stm32l5.c + * + * Copyright (C) 2020 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 + */ + +#include +#include + +/* Assembly helpers */ +#define DMB() __asm__ volatile ("dmb") +#define ISB() __asm__ volatile ("isb") +#define DSB() __asm__ volatile ("dsb") + +/* STM32 L5 register configuration */ +/*!< Memory & Instance aliases and base addresses for Non-Secure/Secure peripherals */ +/*Non-Secure */ +#define RCC_BASE (0x40021000) //RM0438 - Table 4 + +#define RCC_CR (*(volatile uint32_t *)(RCC_BASE + 0x00)) //RM0438 - Table 77 +#define RCC_CR_PLLRDY (1 << 25) //RM0438 - 9.8.1 +#define RCC_CR_PLLON (1 << 24) //RM0438 - 9.8.1 +#define RCC_CR_HSEBYP (1 << 18) //RM0438 - 9.8.1 +#define RCC_CR_HSERDY (1 << 17) //RM0438 - 9.8.1 +#define RCC_CR_HSEON (1 << 16) //RM0438 - 9.8.1 +#define RCC_CR_HSIRDY (1 << 10) //RM0438 - 9.8.1 +#define RCC_CR_HSION (1 << 8) //RM0438 - 9.8.1 +#define RCC_CR_MSIRANGE_SHIFT (4) //RM0438 - 9.8.1 +#define RCC_CR_MSIRANGE_11 (11) +#define RCC_CR_MSIRGSEL (1 << 3) //RM0438 - 9.8.1 +#define RCC_CR_MSIPLLEN (1 << 2) //RM0438 - 9.8.1 +#define RCC_CR_MSIRDY (1 << 1) //RM0438 - 9.8.1 +#define RCC_CR_MSION (1 << 0) //RM0438 - 9.8.1 + + +#define RCC_CFGR (*(volatile uint32_t *)(RCC_BASE + 0x08)) //RM0438 - Table 77 + +/*** APB1&2 PRESCALER ***/ +#define RCC_APB_PRESCALER_DIV_NONE 0x0 // 0xx: HCLK not divided +#define RCC_APB_PRESCALER_DIV_2 0x4 // 100: HCLK divided by 2 +#define RCC_APB_PRESCALER_DIV_4 0x5 // 101: HCLK divided by 4 +#define RCC_APB_PRESCALER_DIV_8 0x6 // 110: HCLK divided by 8 +#define RCC_APB_PRESCALER_DIV_16 0x7 // 111: HCLK divided by 16 + +/*** AHB PRESCALER ***/ +#define RCC_AHB_PRESCALER_DIV_NONE 0x0 // 0xxx: SYSCLK not divided +#define RCC_AHB_PRESCALER_DIV_2 0x8 // 1000: SYSCLK divided by 2 +#define RCC_AHB_PRESCALER_DIV_4 0x9 // 1001: SYSCLK divided by 4 +#define RCC_AHB_PRESCALER_DIV_8 0xA // 1010: SYSCLK divided by 8 +#define RCC_AHB_PRESCALER_DIV_16 0xB // 1011: SYSCLK divided by 16 +#define RCC_AHB_PRESCALER_DIV_64 0xC // 1100: SYSCLK divided by 64 +#define RCC_AHB_PRESCALER_DIV_128 0xD // 1101: SYSCLK divided by 128 +#define RCC_AHB_PRESCALER_DIV_256 0xE // 1110: SYSCLK divided by 256 +#define RCC_AHB_PRESCALER_DIV_512 0xF // 1111: SYSCLK divided by 512 + +#define RCC_CFGR_HPRE_SHIFT (0x04) +#define RCC_CFGR_PPRE2_SHIFT (0x0B) +#define RCC_CFGR_PPRE1_SHIFT (0x08) + +#define RCC_CFGR_SW_MSI 0x0 +#define RCC_CFGR_SW_HSI16 0x1 +#define RCC_CFGR_SW_HSE 0x2 +#define RCC_CFGR_SW_PLL 0x3 + +#define RCC_PLLCFGR (*(volatile uint32_t *)(RCC_BASE + 0x0C)) //RM0438 - Table 77 +#define RCC_PLLCFGR_PLLP_SHIFT (27) +#define RCC_PLLCFGR_PLLR_SHIFT (25) +#define RCC_PLLCFGR_PLLREN (1 << 24) + +#define RCC_PLLCFGR_PLLQ_SHIFT (21) +#define RCC_PLLCFGR_PLLQEN (1 << 20) + +#define RCC_PLLCFGR_PLLN_SHIFT (8) +#define RCC_PLLCFGR_PLLM_SHIFT (4) + +#define RCC_PLLCFGR_QR_DIV_2 0x0 +#define RCC_PLLCFGR_QR_DIV_4 0x1 +#define RCC_PLLCFGR_QR_DIV_6 0x2 +#define RCC_PLLCFGR_QR_DIV_8 0x3 + +#define RCC_PLLCFGR_P_DIV_7 0x0 +#define RCC_PLLCFGR_P_DIV_17 0x1 + +#define RCC_PLLCKSELR_PLLSRC_NONE 0x0 +#define RCC_PLLCKSELR_PLLSRC_MSI 0x1 +#define RCC_PLLCKSELR_PLLSRC_HSI16 0x2 +#define RCC_PLLCKSELR_PLLSRC_HSE 0x3 + +#define RCC_APB1ENR (*(volatile uint32_t *)(RCC_BASE + 0x58)) +#define RCC_APB1ENR_PWREN (1 << 28) + +#define RCC_APB2ENR (*(volatile uint32_t *)(RCC_BASE + 0x60)) +#define RCC_APB2ENR_SYSCFGEN (1 << 0) + + +/*** PWR ***/ +/*!< Memory & Instance aliases and base addresses for Non-Secure/Secure peripherals */ +/*Non-Secure */ +#define PWR_BASE (0x40007000) //RM0438 - Table 4 + +#define PWR_CR1 (*(volatile uint32_t *)(PWR_BASE + 0x00)) +#define PWR_CR1_VOS_SHIFT (9) +#define PWR_CR1_VOS_0 (0x0) +#define PWR_CR1_VOS_1 (0x1) +#define PWR_CR1_VOS_2 (0x2) + +#define PWR_CR2 (*(volatile uint32_t *)(PWR_BASE + 0x04)) +#define PWR_CR2_IOSV (1 << 9) +#define PWR_CR3 (*(volatile uint32_t *)(PWR_BASE + 0x08)) +#define PWR_CR3_UCPD_DBDIS (1 << 14) +#define PWR_CR4 (*(volatile uint32_t *)(PWR_BASE + 0x0C)) + +#define PWR_SR1 (*(volatile uint32_t *)(PWR_BASE + 0x10)) +#define PWR_SR2 (*(volatile uint32_t *)(PWR_BASE + 0x14)) +#define PWR_SR2_VOSF (1 << 10) + +#define SYSCFG_BASE (0x50010000) //RM0438 - Table 4 + + + +/*** FLASH ***/ +#define SYSCFG_APB2_CLOCK_ER_VAL (1 << 0) //RM0438 - RCC_APB2ENR - SYSCFGEN + +/*Non-Secure*/ +#define FLASH_BASE (0x40022000) //RM0438 - Table 4 +#define FLASH_KEYR (*(volatile uint32_t *)(FLASH_BASE + 0x08)) +#define FLASH_SR (*(volatile uint32_t *)(FLASH_BASE + 0x20)) +#define FLASH_CR (*(volatile uint32_t *)(FLASH_BASE + 0x28)) + +/* Register values */ +#define FLASH_SR_EOP (1 << 0) +#define FLASH_SR_OPERR (1 << 1) +#define FLASH_SR_PROGERR (1 << 3) +#define FLASH_SR_WRPERR (1 << 4) +#define FLASH_SR_PGAERR (1 << 5) +#define FLASH_SR_SIZERR (1 << 6) +#define FLASH_SR_PGSERR (1 << 7) +#define FLASH_SR_OPTWERR (1 << 13) +#define FLASH_SR_BSY (1 << 16) + +#define FLASH_CR_PG (1 << 0) +#define FLASH_CR_PER (1 << 1) +#define FLASH_CR_MER1 (1 << 2) +#define FLASH_CR_PNB_SHIFT 3 +#define FLASH_CR_PNB_MASK 0x7F +#define FLASH_CR_BKER (1 << 11) +#define FLASH_CR_MER2 (1 << 15) +#define FLASH_CR_STRT (1 << 16) +#define FLASH_CR_OPTSTRT (1 << 17) +#define FLASH_CR_EOPIE (1 << 24) +#define FLASH_CR_ERRIE (1 << 25) +#define FLASH_CR_OBL_LAUNCH (1 << 27) +#define FLASH_CR_OPTLOCK (1 << 30) +#define FLASH_CR_LOCK (1 << 31) + +#define FLASH_ACR (*(volatile uint32_t *)(FLASH_BASE + 0x00)) +#define FLASH_ACR_LATENCY_MASK (0x0F) + +#define FLASHMEM_ADDRESS_SPACE (0x08000000) +#define FLASH_PAGE_SIZE (0x800) /* 2KB */ +#define FLASH_BANK2_BASE (0x08040000) /*!< Base address of Flash Bank2 */ +#define FLASH_TOP (0x0807FFFF) /*!< FLASH end address */ + +#define FLASH_KEY1 (0x45670123) +#define FLASH_KEY2 (0xCDEF89AB) + + +static void RAMFUNCTION flash_set_waitstates(unsigned int waitstates) +{ + uint32_t reg = FLASH_ACR; + if ((reg & FLASH_ACR_LATENCY_MASK) != waitstates) + FLASH_ACR = (reg & ~FLASH_ACR_LATENCY_MASK) | waitstates ; +} + +static RAMFUNCTION void flash_wait_complete(uint8_t bank) +{ + while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY); + +} + +static void RAMFUNCTION flash_clear_errors(uint8_t bank) +{ + + FLASH_SR |= ( FLASH_SR_OPERR | FLASH_SR_PROGERR | FLASH_SR_WRPERR |FLASH_SR_PGAERR | FLASH_SR_SIZERR | FLASH_SR_PGSERR | FLASH_SR_OPTWERR ) ; + +} + + +int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len) +{ + int i = 0; + uint32_t *src, *dst; + + flash_clear_errors(0); + + src = (uint32_t *)data; + dst = (uint32_t *)(address + FLASHMEM_ADDRESS_SPACE); + + while (i < len) { + FLASH_CR |= FLASH_CR_PG; + dst[i >> 2] = src[i >> 2]; + dst[(i >> 2) + 1] = src[(i >> 2) + 1]; + flash_wait_complete(0); + FLASH_CR &= ~FLASH_CR_PG; + i+=8; + } + + return 0; +} + +void RAMFUNCTION hal_flash_unlock(void) +{ + flash_wait_complete(0); + if ((FLASH_CR & FLASH_CR_LOCK) != 0) { + FLASH_KEYR = FLASH_KEY1; + DMB(); + FLASH_KEYR = FLASH_KEY2; + DMB(); + while ((FLASH_CR & FLASH_CR_LOCK) != 0) + ; + } + +} + +void RAMFUNCTION hal_flash_lock(void) +{ + flash_wait_complete(0); + if ((FLASH_CR & FLASH_CR_LOCK) == 0) + FLASH_CR |= FLASH_CR_LOCK; +} + +int RAMFUNCTION hal_flash_erase(uint32_t address, int len) +{ + uint32_t end_address; + uint32_t p; + + flash_clear_errors(0); + + if (len == 0) + return -1; + end_address = address + len - 1; + for (p = address; p < end_address; p += FLASH_PAGE_SIZE) { + // considering DBANK = 1 + if (p < (FLASH_BANK2_BASE -FLASHMEM_ADDRESS_SPACE) ) + { + FLASH_CR &= ~FLASH_CR_BKER; + } + if(p>=(FLASH_BANK2_BASE -FLASHMEM_ADDRESS_SPACE) && (p <= (FLASH_TOP -FLASHMEM_ADDRESS_SPACE) )) + { + FLASH_CR |= FLASH_CR_BKER; + } + + uint32_t reg = FLASH_CR & (~((FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT)| FLASH_CR_PER)); + FLASH_CR = reg | (((p >> 11) << FLASH_CR_PNB_SHIFT) | FLASH_CR_PER ); + DMB(); + FLASH_CR |= FLASH_CR_STRT; + flash_wait_complete(0); + } + + /* If the erase operation is completed, disable the associated bits */ + FLASH_CR &= ~FLASH_CR_PER ; + + return 0; +} + +static void clock_pll_off(void) +{ + uint32_t reg32; + + /* Select MSI as SYSCLK source. */ + reg32 = RCC_CFGR; + reg32 &= ~((1 << 1) | (1 << 0)); + RCC_CFGR = (reg32 | RCC_CFGR_SW_MSI); + DMB(); + + /* Wait for MSI clock to be selected. */ + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SW_MSI) {}; + + /* Turn off PLL */ + RCC_CR &= ~RCC_CR_PLLON; + DMB(); +} + +/*This implementation will setup MSI 48 MHz as PLL Source Mux, PLLCLK as System Clock Source*/ + +static void clock_pll_on(int powersave) +{ + uint32_t reg32; + uint32_t plln, pllm, pllq, pllp, pllr, hpre, apb1pre, apb2pre , flash_waitstates; + + RCC_APB2ENR |= RCC_APB2ENR_SYSCFGEN; + RCC_APB1ENR |= RCC_APB1ENR_PWREN; + PWR_CR3 |= PWR_CR3_UCPD_DBDIS; + + PWR_CR1 &= ~((1 << 10) | (1 << 9)); + PWR_CR1 |= (PWR_CR1_VOS_0 << PWR_CR1_VOS_SHIFT); + /* Delay after setting the voltage scaling */ + reg32 = PWR_CR1; + while ((PWR_SR2 & PWR_SR2_VOSF) == 1) {}; + + while ((RCC_CR & RCC_CR_MSIRDY) == 0) {}; + flash_waitstates = 2; + flash_set_waitstates(flash_waitstates); + + RCC_CR |= RCC_CR_MSIRGSEL; + + reg32 = RCC_CR; + reg32 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4)); + reg32 |= (RCC_CR_MSIRANGE_11 << RCC_CR_MSIRANGE_SHIFT); + RCC_CR = reg32; + reg32 = RCC_CR; + DMB(); + + + /* Select clock parameters (CPU Speed = 110 MHz) */ + pllm = 12; + plln = 55; + pllp = 7; + pllq = RCC_PLLCFGR_QR_DIV_2; + pllr = RCC_PLLCFGR_QR_DIV_2; + hpre = RCC_AHB_PRESCALER_DIV_NONE; + apb1pre = RCC_APB_PRESCALER_DIV_NONE; + apb2pre = RCC_APB_PRESCALER_DIV_NONE; + flash_waitstates = 5; + + RCC_CR &= ~RCC_CR_PLLON; + while ((RCC_CR & RCC_CR_PLLRDY) != 0) {}; + + /*PLL Clock source selection*/ + reg32 = RCC_PLLCFGR ; + reg32 |= RCC_PLLCKSELR_PLLSRC_MSI; + reg32 |= ((pllm-1) << RCC_PLLCFGR_PLLM_SHIFT); + reg32 |= ((plln) << RCC_PLLCFGR_PLLN_SHIFT); + reg32 |= ((pllp) << RCC_PLLCFGR_PLLP_SHIFT); + reg32 |= ((pllq) << RCC_PLLCFGR_PLLQ_SHIFT); + reg32 |= ((pllr) << RCC_PLLCFGR_PLLR_SHIFT); + RCC_PLLCFGR = reg32; + DMB(); + + RCC_CR |= RCC_CR_PLLON; + while ((RCC_CR & RCC_CR_PLLRDY) == 0) {}; + + RCC_PLLCFGR |= RCC_PLLCFGR_PLLREN; + + flash_set_waitstates(flash_waitstates); + + /*step down HPRE before going to >80MHz*/ + reg32 = RCC_CFGR ; + reg32 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4)); + reg32 |= ((RCC_AHB_PRESCALER_DIV_2) << RCC_CFGR_HPRE_SHIFT) ; + RCC_CFGR = reg32; + DMB(); + + /* Select PLL as SYSCLK source. */ + reg32 = RCC_CFGR; + reg32 &= ~((1 << 1) | (1 << 0)); + RCC_CFGR = (reg32 | RCC_CFGR_SW_PLL); + DMB(); + + /* Wait for PLL clock to be selected. */ + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SW_PLL) {}; + + /*step-up HPRE to go > 80MHz*/ + reg32 = RCC_CFGR ; + reg32 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4)); + reg32 |= ((hpre) << RCC_CFGR_HPRE_SHIFT) ; + RCC_CFGR = reg32; + DMB(); + + /*PRE1 and PRE2 conf*/ + reg32 = RCC_CFGR ; + reg32 &= ~((1 << 10) | (1 << 9) | (1 << 8)); + reg32 |= ((apb1pre) << RCC_CFGR_PPRE1_SHIFT) ; + reg32 &= ~((1 << 13) | (1 << 12) | (1 << 11)); + reg32 |= ((apb2pre) << RCC_CFGR_PPRE2_SHIFT) ; + RCC_CFGR = reg32; + DMB(); + +} + +void hal_init(void) +{ + clock_pll_on(0); +} + +void hal_prepare_boot(void) +{ + clock_pll_off(); +} diff --git a/hal/stm32l5_partition.h b/hal/stm32l5_partition.h new file mode 100644 index 00000000..397122f6 --- /dev/null +++ b/hal/stm32l5_partition.h @@ -0,0 +1,422 @@ +#ifndef STM32L5_PARTITION_H +#define STM32L5_PARTITION_H + +#define SCS_BASE (0xE000E000UL) +#define SCB_BASE (SCS_BASE + 0x0D00UL) +#define SAU_BASE (SCS_BASE + 0x0DD0UL) +#define FPU_BASE (SCS_BASE + 0x0F30UL) +#define NVIC_BASE (SCS_BASE + 0x0100UL) + +#define SAU_CTRL (*(volatile uint32_t *)(SAU_BASE + 0x00)) +#define SAU_RNR (*(volatile uint32_t *)(SAU_BASE + 0x08)) +#define SAU_RBAR (*(volatile uint32_t *)(SAU_BASE + 0x0C)) +#define SAU_RLAR (*(volatile uint32_t *)(SAU_BASE + 0x10)) +#define SCB_NSACR (*(volatile uint32_t *)(SCB_BASE + 0x8C)) +#define FPU_FPCCR (*(volatile uint32_t *)(FPU_BASE + 0x04)) + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) + +/* +// Enable SAU +// Value for SAU_CTRL register bit ENABLE +*/ +#define SAU_INIT_CTRL_ENABLE 1 + +/* +// When SAU is disabled +// <0=> All Memory is Secure +// <1=> All Memory is Non-Secure +// Value for SAU_CTRL register bit ALLNS +// When all Memory is Non-Secure (ALLNS is 1), IDAU can override memory map configuration. +*/ +#define SAU_INIT_CTRL_ALLNS 0 + +/* +// Initialize Security Attribution Unit (SAU) Address Regions +// SAU configuration specifies regions to be one of: +// - Secure and Non-Secure Callable +// - Non-Secure +// Note: All memory regions not configured by SAU are Secure +*/ +#define SAU_REGIONS_MAX 8 /* Max. number of SAU regions */ + +/* +// Initialize SAU Region 0 +// Setup SAU Region 0 memory attributes +*/ +#define SAU_INIT_REGION0 1 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START0 0x0C03E000 /* start address of SAU region 0 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END0 0x0C03FFFF /* end address of SAU region 0 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC0 1 + +/* +// Initialize SAU Region 1 +// Setup SAU Region 1 memory attributes +*/ +#define SAU_INIT_REGION1 1 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START1 0x08040000 /* start address of SAU region 1 */ +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END1 0x0807FFFF /* end address of SAU region 1 */ +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC1 0 + +/* +// Initialize SAU Region 2 +// Setup SAU Region 2 memory attributes +*/ +#define SAU_INIT_REGION2 1 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START2 0x20018000 /* start address of SAU region 2 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END2 0x2003FFFF /* end address of SAU region 2 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC2 0 + +/* +// Initialize SAU Region 3 +// Setup SAU Region 3 memory attributes +*/ +#define SAU_INIT_REGION3 1 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START3 0x40000000 /* start address of SAU region 3 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END3 0x4FFFFFFF /* end address of SAU region 3 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC3 0 + +/* +// Initialize SAU Region 4 +// Setup SAU Region 4 memory attributes +*/ +#define SAU_INIT_REGION4 1 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START4 0x60000000 /* start address of SAU region 4 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END4 0x9FFFFFFF /* end address of SAU region 4 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC4 0 + +/* +// Initialize SAU Region 5 +// Setup SAU Region 5 memory attributes +*/ +#define SAU_INIT_REGION5 1 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START5 0x0BF90000 /* start address of SAU region 5 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END5 0x0BFA8FFF /* end address of SAU region 5 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC5 0 + +/* +// Initialize SAU Region 6 +// Setup SAU Region 6 memory attributes +*/ +#define SAU_INIT_REGION6 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START6 0x00000000 /* start address of SAU region 6 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END6 0x00000000 /* end address of SAU region 6 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC6 0 + +/* +// Initialize SAU Region 7 +// Setup SAU Region 7 memory attributes +*/ +#define SAU_INIT_REGION7 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START7 0x00000000 /* start address of SAU region 7 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END7 0x00000000 /* end address of SAU region 7 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC7 0 + +// Setup behaviour of Floating Point Unit + +#define TZ_FPU_NS_USAGE 1 + +/* +// Floating Point Unit usage +// <0=> Secure state only +// <3=> Secure and Non-Secure state +// Value for SCB_NSACR register bits CP10, CP11 +*/ +#define SCB_NSACR_CP10_11_VAL 3 + +/* +// Treat floating-point registers as Secure +// <0=> Disabled +// <1=> Enabled +// Value for FPU_FPCCR register bit TS +*/ +#define FPU_FPCCR_TS_VAL 0 + +/* +// Clear on return (CLRONRET) accessibility +// <0=> Secure and Non-Secure state +// <1=> Secure state only +// Value for FPU_FPCCR register bit CLRONRETS +*/ +#define FPU_FPCCR_CLRONRETS_VAL 0 + +/* +// Clear floating-point caller saved registers on exception return +// <0=> Disabled +// <1=> Enabled +// Value for FPU_FPCCR register bit CLRONRET +*/ +#define FPU_FPCCR_CLRONRET_VAL 1 + + +#define SAU_INIT_REGION(n) \ + SAU_RNR = (n & SAU_RNR_REGION_Msk); \ + SAU_RBAR = (SAU_INIT_START##n & SAU_RBAR_BADDR_Msk); \ + SAU_RLAR = (SAU_INIT_END##n & SAU_RLAR_LADDR_Msk) | \ + ((SAU_INIT_NSC##n << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1U + + +#define GTZC_MPCBB1_S_BASE (0x50032C00) +#define GTZC_MPCBB1_S_CR (*(volatile uint32_t *)(GTZC_MPCBB1_S_BASE + 0x00)) +#define GTZC_MPCBB1_S_LCKVTR1 (*(volatile uint32_t *)(GTZC_MPCBB1_S_BASE + 0x10)) +#define GTZC_MPCBB1_S_LCKVTR2 (*(volatile uint32_t *)(GTZC_MPCBB1_S_BASE + 0x14)) +#define GTZC_MPCBB1_S_VCTR_BASE (GTZC_MPCBB1_S_BASE + 0x100) + +#define GTZC_MPCBB2_S_BASE (0x50033000) +#define GTZC_MPCBB2_S_CR (*(volatile uint32_t *)(GTZC_MPCBB2_S_BASE + 0x00)) +#define GTZC_MPCBB2_S_LCKVTR1 (*(volatile uint32_t *)(GTZC_MPCBB2_S_BASE + 0x10)) +#define GTZC_MPCBB2_S_LCKVTR2 (*(volatile uint32_t *)(GTZC_MPCBB2_S_BASE + 0x14)) +#define GTZC_MPCBB2_S_VCTR_BASE (GTZC_MPCBB2_S_BASE + 0x100) + +#define SET_GTZC_MPCBBx_S_VCTR(x,n) \ + (*((volatile uint32_t *)(GTZC_MPCBB##x##_S_VCTR_BASE ) + n ))= GTZC_MPCBB##x##_S_VCTR##n##_VAL + +/*SRAM1*/ +#define GTZC_MPCBB1_S_VCTR0_VAL (0xFFFFFFFF) +#define GTZC_MPCBB1_S_VCTR1_VAL (0xFFFFFFFF) +#define GTZC_MPCBB1_S_VCTR2_VAL (0xFFFFFFFF) +#define GTZC_MPCBB1_S_VCTR3_VAL (0xFFFFFFFF) +#define GTZC_MPCBB1_S_VCTR4_VAL (0xFFFFFFFF) +#define GTZC_MPCBB1_S_VCTR5_VAL (0xFFFFFFFF) +#define GTZC_MPCBB1_S_VCTR6_VAL (0xFFFFFFFF) +#define GTZC_MPCBB1_S_VCTR7_VAL (0xFFFFFFFF) +#define GTZC_MPCBB1_S_VCTR8_VAL (0xFFFFFFFF) +#define GTZC_MPCBB1_S_VCTR9_VAL (0xFFFFFFFF) +#define GTZC_MPCBB1_S_VCTR10_VAL (0xFFFFFFFF) +#define GTZC_MPCBB1_S_VCTR11_VAL (0xFFFFFFFF) +#define GTZC_MPCBB1_S_VCTR12_VAL (0xFFFFFFFF) +#define GTZC_MPCBB1_S_VCTR13_VAL (0x00000000) +#define GTZC_MPCBB1_S_VCTR14_VAL (0x00000000) +#define GTZC_MPCBB1_S_VCTR15_VAL (0x00000000) +#define GTZC_MPCBB1_S_VCTR16_VAL (0x00000000) +#define GTZC_MPCBB1_S_VCTR17_VAL (0x00000000) +#define GTZC_MPCBB1_S_VCTR18_VAL (0x00000000) +#define GTZC_MPCBB1_S_VCTR19_VAL (0x00000000) +#define GTZC_MPCBB1_S_VCTR20_VAL (0x00000000) +#define GTZC_MPCBB1_S_VCTR21_VAL (0x00000000) +#define GTZC_MPCBB1_S_VCTR22_VAL (0x00000000) +#define GTZC_MPCBB1_S_VCTR23_VAL (0x00000000) + +/*SRAM2*/ +#define GTZC_MPCBB2_S_VCTR0_VAL (0x00000000) +#define GTZC_MPCBB2_S_VCTR1_VAL (0x00000000) +#define GTZC_MPCBB2_S_VCTR2_VAL (0x00000000) +#define GTZC_MPCBB2_S_VCTR3_VAL (0x00000000) +#define GTZC_MPCBB2_S_VCTR4_VAL (0x00000000) +#define GTZC_MPCBB2_S_VCTR5_VAL (0x00000000) +#define GTZC_MPCBB2_S_VCTR6_VAL (0x00000000) +#define GTZC_MPCBB2_S_VCTR7_VAL (0x00000000) + +/** + \brief Setup a SAU Region + \details Writes the region information contained in SAU_Region to the + registers SAU_RNR, SAU_RBAR, and SAU_RLAR + */ +static __inline void TZ_SAU_Setup (void) +{ + + #if defined (SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U) + SAU_INIT_REGION(0); + #endif + + #if defined (SAU_INIT_REGION1) && (SAU_INIT_REGION1 == 1U) + SAU_INIT_REGION(1); + #endif + + #if defined (SAU_INIT_REGION2) && (SAU_INIT_REGION2 == 1U) + SAU_INIT_REGION(2); + #endif + + #if defined (SAU_INIT_REGION3) && (SAU_INIT_REGION3 == 1U) + SAU_INIT_REGION(3); + #endif + + #if defined (SAU_INIT_REGION4) && (SAU_INIT_REGION4 == 1U) + SAU_INIT_REGION(4); + #endif + + #if defined (SAU_INIT_REGION5) && (SAU_INIT_REGION5 == 1U) + SAU_INIT_REGION(5); + #endif + + #if defined (SAU_INIT_REGION6) && (SAU_INIT_REGION6 == 1U) + SAU_INIT_REGION(6); + #endif + + #if defined (SAU_INIT_REGION7) && (SAU_INIT_REGION7 == 1U) + SAU_INIT_REGION(7); + #endif + + SAU_CTRL = ((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) | + ((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk) ; + + #if defined (TZ_FPU_NS_USAGE) && (TZ_FPU_NS_USAGE == 1U) + + SCB_NSACR = (SCB_NSACR & ~(SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)) | + ((SCB_NSACR_CP10_11_VAL << SCB_NSACR_CP10_Pos) & (SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)); + + FPU_FPCCR = (FPU_FPCCR & ~(FPU_FPCCR_TS_Msk | FPU_FPCCR_CLRONRETS_Msk | FPU_FPCCR_CLRONRET_Msk)) | + ((FPU_FPCCR_TS_VAL << FPU_FPCCR_TS_Pos ) & FPU_FPCCR_TS_Msk ) | + ((FPU_FPCCR_CLRONRETS_VAL << FPU_FPCCR_CLRONRETS_Pos) & FPU_FPCCR_CLRONRETS_Msk) | + ((FPU_FPCCR_CLRONRET_VAL << FPU_FPCCR_CLRONRET_Pos ) & FPU_FPCCR_CLRONRET_Msk ); + #endif + +} + +#endif /* STM32L5_PARTITION_H */ diff --git a/src/boot_arm.c b/src/boot_arm.c index 8bd234ba..f982115a 100644 --- a/src/boot_arm.c +++ b/src/boot_arm.c @@ -24,6 +24,9 @@ #include "image.h" #include "loader.h" #include "wolfboot/wolfboot.h" +#if defined(PLATFORM_stm32l5) && (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#include "stm32l5_partition.h" +#endif extern unsigned int _start_text; extern unsigned int _stored_data; @@ -187,7 +190,12 @@ void isr_reset(void) { dst++; } +#if defined(PLATFORM_stm32l5) && (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + TZ_SAU_Setup(); +#else mpu_init(); +#endif + /* Run the program! */ main(); } @@ -202,6 +210,15 @@ void isr_empty(void) /* Ignore unmapped event and continue */ } +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +void isr_securefault(void) +{ + /* Panic. */ + while(1) ;; +} + +#endif + /* This is the main loop for the bootloader. * @@ -213,7 +230,11 @@ void isr_empty(void) * - Call the application entry point * */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define VTOR (*(volatile uint32_t *)(0xE002ED08)) // SCB_NS -> VTOR +#else #define VTOR (*(volatile uint32_t *)(0xE000ED08)) +#endif static void *app_entry; static uint32_t app_end_stack; @@ -233,12 +254,25 @@ void RAMFUNCTION do_boot(const uint32_t *app_offset) app_entry = (void *)(*((uint32_t *)(app_offset + 1))); /* Update stack pointer */ - asm volatile("msr msp, %0" ::"r"(app_end_stack)); +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + asm volatile("msr msplim, %0" ::"r"(0)); + asm volatile("msr msp_ns, %0" ::"r"(app_end_stack)); +#else + asm volatile("msr msp, %0" ::"r"(app_end_stack)); +#endif #ifndef NO_VTOR asm volatile("cpsie i"); #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + asm volatile("mov r7, %0" ::"r"(app_entry)); + asm volatile("bic.w r7, r7, #1"); + asm volatile("blxns r7" );/* Jump to non secure app_entry */ +#else /* Unconditionally jump to app_entry */ asm volatile("mov pc, %0" ::"r"(app_entry)); +#endif + } #ifdef PLATFORM_psoc6 @@ -251,20 +285,137 @@ typedef void(*NMIHANDLER)(void); __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 - 0, 0, 0, 0, // 4x reserved - isr_empty, // SVC - isr_empty, // DebugMonitor - 0, // reserved - isr_empty, // PendSV - isr_empty, // SysTick - + (void (*)(void))(&END_STACK), + isr_reset, // Reset + isr_NMI, // NMI + isr_fault, // HardFault + isr_fault, // MemFault + isr_fault, // BusFault + isr_fault, // UsageFault +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + isr_securefault, // SecureFault +#else + 0, // reserved +#endif + 0, // reserved + 0, // reserved + 0, // reserved + isr_empty, // SVC + isr_empty, // DebugMonitor + 0, // reserved + isr_empty, // PendSV + isr_empty, // SysTick +#ifdef PLATFORM_stm32l5 + isr_empty, // WWDG_IRQHandler + isr_empty, // PVD_PVM_IRQHandler + isr_empty, // RTC_IRQHandler + isr_empty, // RTC_S_IRQHandler + isr_empty, // TAMP_IRQHandler + isr_empty, // TAMP_S_IRQHandler + isr_empty, // FLASH_IRQHandler + isr_empty, // FLASH_S_IRQHandler + isr_empty, // GTZC_IRQHandler + isr_empty, // RCC_IRQHandler + isr_empty, // RCC_S_IRQHandler + isr_empty, // EXTI0_IRQHandler + isr_empty, // EXTI1_IRQHandler + isr_empty, // EXTI2_IRQHandler + isr_empty, // EXTI3_IRQHandler + isr_empty, // EXTI4_IRQHandler + isr_empty, // EXTI5_IRQHandler + isr_empty, // EXTI6_IRQHandler + isr_empty, // EXTI7_IRQHandler + isr_empty, // EXTI8_IRQHandler + isr_empty, // EXTI9_IRQHandler + isr_empty, // EXTI10_IRQHandler + isr_empty, // EXTI11_IRQHandler + isr_empty, // EXTI12_IRQHandler + isr_empty, // EXTI13_IRQHandler + isr_empty, // EXTI14_IRQHandler + isr_empty, // EXTI15_IRQHandler + isr_empty, // DMAMUX1_IRQHandler + isr_empty, // DMAMUX1_S_IRQHandler + isr_empty, // DMA1_Channel1_IRQHandler + isr_empty, // DMA1_Channel2_IRQHandler + isr_empty, // DMA1_Channel3_IRQHandler + isr_empty, // DMA1_Channel4_IRQHandler + isr_empty, // DMA1_Channel5_IRQHandler + isr_empty, // DMA1_Channel6_IRQHandler + isr_empty, // DMA1_Channel7_IRQHandler + isr_empty, // DMA1_Channel8_IRQHandler + isr_empty, // ADC1_2_IRQHandler + isr_empty, // DAC_IRQHandler + isr_empty, // FDCAN1_IT0_IRQHandler + isr_empty, // FDCAN1_IT1_IRQHandler + isr_empty, // TIM1_BRK_IRQHandler + isr_empty, // TIM1_UP_IRQHandler + isr_empty, // TIM1_TRG_COM_IRQHandler + isr_empty, // TIM1_CC_IRQHandler + isr_empty, // TIM2_IRQHandler + isr_empty, // TIM3_IRQHandler + isr_empty, // TIM4_IRQHandler + isr_empty, // TIM5_IRQHandler + isr_empty, // TIM6_IRQHandler + isr_empty, // TIM7_IRQHandler + isr_empty, // TIM8_BRK_IRQHandler + isr_empty, // TIM8_UP_IRQHandler + isr_empty, // TIM8_TRG_COM_IRQHandler + isr_empty, // TIM8_CC_IRQHandler + isr_empty, // I2C1_EV_IRQHandler + isr_empty, // I2C1_ER_IRQHandler + isr_empty, // I2C2_EV_IRQHandler + isr_empty, // I2C2_ER_IRQHandler + isr_empty, // SPI1_IRQHandler + isr_empty, // SPI2_IRQHandler + isr_empty, // USART1_IRQHandler + isr_empty, // USART2_IRQHandler + isr_empty, // USART3_IRQHandler + isr_empty, // UART4_IRQHandler + isr_empty, // UART5_IRQHandler + isr_empty, // LPUART1_IRQHandler + isr_empty, // LPTIM1_IRQHandler + isr_empty, // LPTIM2_IRQHandler + isr_empty, // TIM15_IRQHandler + isr_empty, // TIM16_IRQHandler + isr_empty, // TIM17_IRQHandler + isr_empty, // COMP_IRQHandler + isr_empty, // USB_FS_IRQHandler + isr_empty, // CRS_IRQHandler + isr_empty, // FMC_IRQHandler + isr_empty, // OCTOSPI1_IRQHandler + isr_empty, // 0 + isr_empty, // SDMMC1_IRQHandler + isr_empty, // 0 + isr_empty, // DMA2_Channel1_IRQHandler + isr_empty, // DMA2_Channel2_IRQHandler + isr_empty, // DMA2_Channel3_IRQHandler + isr_empty, // DMA2_Channel4_IRQHandler + isr_empty, // DMA2_Channel5_IRQHandler + isr_empty, // DMA2_Channel6_IRQHandler + isr_empty, // DMA2_Channel7_IRQHandler + isr_empty, // DMA2_Channel8_IRQHandler + isr_empty, // I2C3_EV_IRQHandler + isr_empty, // I2C3_ER_IRQHandler + isr_empty, // SAI1_IRQHandler + isr_empty, // SAI2_IRQHandler + isr_empty, // TSC_IRQHandler + isr_empty, // AES_IRQHandler + isr_empty, // RNG_IRQHandler + isr_empty, // FPU_IRQHandler + isr_empty, // HASH_IRQHandler + isr_empty, // PKA_IRQHandler + isr_empty, // LPTIM3_IRQHandler + isr_empty, // SPI3_IRQHandler + isr_empty, // I2C4_ER_IRQHandler + isr_empty, // I2C4_EV_IRQHandler + isr_empty, // DFSDM1_FLT0_IRQHandler + isr_empty, // DFSDM1_FLT1_IRQHandler + isr_empty, // DFSDM1_FLT2_IRQHandler + isr_empty, // DFSDM1_FLT3_IRQHandler + isr_empty, // UCPD1_IRQHandler + isr_empty, // ICACHE_IRQHandler + isr_empty, // OTFDEC1_IRQHandler +#else isr_empty, isr_empty, isr_empty, @@ -309,6 +460,7 @@ void (* const IV[])(void) = isr_empty, isr_empty, isr_empty, +#endif }; #ifdef RAM_CODE diff --git a/test-app/ARM-stm32l5.ld b/test-app/ARM-stm32l5.ld new file mode 100644 index 00000000..b509fc7f --- /dev/null +++ b/test-app/ARM-stm32l5.ld @@ -0,0 +1,47 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = ##WOLFBOOT_TEST_APP_ADDRESS##, LENGTH = ##WOLFBOOT_TEST_APP_SIZE## + RAM (rwx) : ORIGIN = 0x20018000, LENGTH = 16K /* Run in lowmem */ +} + +SECTIONS +{ + .text : + { + _start_text = .; + . = ALIGN(8); + KEEP(*(.isr_vector)) + . = ALIGN(8); + *(.init) + *(.fini) + *(.text*) + *(.rodata*) + . = ALIGN(8); + _end_text = .; + } > FLASH + + _stored_data = .; + + .data : AT (_stored_data) + { + _start_data = .; + KEEP(*(.data*)) + . = ALIGN(8); + KEEP(*(.ramcode)) + . = ALIGN(8); + _end_data = .; + } > RAM + + .bss : + { + _start_bss = .; + *(.bss*) + *(COMMON) + . = ALIGN(8); + _end_bss = .; + _end = .; + } > RAM +} + +PROVIDE(_start_heap = _end); +PROVIDE(_end_stack = ORIGIN(RAM) + LENGTH(RAM)); diff --git a/test-app/Makefile b/test-app/Makefile index c2a0893a..fd9201ee 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -28,9 +28,15 @@ endif CFLAGS+=-g -ggdb -Wall -Wstack-usage=1024 -ffreestanding -Wno-unused -DPLATFORM_$(TARGET) -I../include -nostartfiles -APP_OBJS:=app_$(TARGET).o led.o system.o timer.o ../hal/$(TARGET).o ../src/libwolfboot.o +APP_OBJS:=app_$(TARGET).o led.o system.o timer.o ../src/libwolfboot.o include ../arch.mk +ifeq ($(TZEN),1) + APP_OBJS+=../hal/$(TARGET)_ns.o +else + APP_OBJS+=../hal/$(TARGET).o +endif + ifeq ($(ARCH),RISCV) APP_OBJS+=startup_riscv.o vector_riscv.o endif @@ -54,6 +60,10 @@ ifeq ($(TARGET),stm32f7) LSCRIPT_TEMPLATE=ARM-stm32f7.ld CFLAGS+=-DDUALBANK_SWAP endif +ifeq ($(TARGET),stm32l5) + LSCRIPT_TEMPLATE=ARM-stm32l5.ld + CFLAGS+=-mcpu=cortex-m33 +endif LDFLAGS:=$(CFLAGS) -T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=image.map ifeq ($(EXT_FLASH),1) diff --git a/test-app/app_stm32l5.c b/test-app/app_stm32l5.c new file mode 100644 index 00000000..3a147938 --- /dev/null +++ b/test-app/app_stm32l5.c @@ -0,0 +1,105 @@ +/* stm32l5.c + * + * Test bare-metal application. + * + * Copyright (C) 2020 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 + */ + +#include +#include +#include +#include +#include "system.h" +#include "hal.h" + +#define LED_BOOT_PIN (12) //PG12 - Discovery - Green Led +#define LED_USR_PIN (3) //PD3 - Discovery - Red Led + +/*Non-Secure */ +#define RCC_BASE (0x40021000) //RM0438 - Table 4 +#define PWR_BASE (0x40007000) //RM0438 - Table 4 +#define GPIOD_BASE 0x42020C00 +#define GPIOG_BASE 0x42021800 + + +#define GPIOG_MODER (*(volatile uint32_t *)(GPIOG_BASE + 0x00)) +#define GPIOG_PUPDR (*(volatile uint32_t *)(GPIOG_BASE + 0x0C)) +#define GPIOG_BSRR (*(volatile uint32_t *)(GPIOG_BASE + 0x18)) + +#define GPIOD_MODER (*(volatile uint32_t *)(GPIOD_BASE + 0x00)) +#define GPIOD_PUPDR (*(volatile uint32_t *)(GPIOD_BASE + 0x0C)) +#define GPIOD_BSRR (*(volatile uint32_t *)(GPIOD_BASE + 0x18)) + +#define RCC_AHB2_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0x4C )) +#define GPIOG_AHB2_CLOCK_ER (1 << 6) +#define GPIOD_AHB2_CLOCK_ER (1 << 3) + +#define PWR_CR2 (*(volatile uint32_t *)(PWR_BASE + 0x04)) +#define PWR_CR2_IOSV (1 << 9) + +static void boot_led_on(void) +{ + uint32_t reg; + uint32_t pin = LED_BOOT_PIN; + + RCC_AHB2_CLOCK_ER|= GPIOG_AHB2_CLOCK_ER; + /* Delay after an RCC peripheral clock enabling */ + reg = RCC_AHB2_CLOCK_ER; + PWR_CR2 |= PWR_CR2_IOSV; + + reg = GPIOG_MODER & ~(0x03 << (pin * 2)); + GPIOG_MODER = reg | (1 << (pin * 2)); + GPIOG_PUPDR &= ~(0x03 << (pin * 2)); + GPIOG_BSRR |= (1 << (pin + 16)); +} + +static void boot_led_off(void) +{ + GPIOG_BSRR |= (1 << (LED_BOOT_PIN)); +} + +void usr_led_on(void) +{ + uint32_t reg; + uint32_t pin = LED_USR_PIN; + + RCC_AHB2_CLOCK_ER|= GPIOD_AHB2_CLOCK_ER; + /* Delay after an RCC peripheral clock enabling */ + reg = RCC_AHB2_CLOCK_ER; + + reg = GPIOD_MODER & ~(0x03 << (pin * 2)); + GPIOD_MODER = reg | (1 << (pin * 2)); + GPIOD_PUPDR &= ~(0x03 << (pin * 2)); + GPIOD_BSRR |= (1 << (pin + 16)); +} + +void usr_led_off(void) +{ + GPIOD_BSRR |= (1 << (LED_USR_PIN)); +} + +void main(void) +{ + hal_init(); + boot_led_on(); + usr_led_on(); + boot_led_off(); + while(1) + ; +} diff --git a/test-app/startup_arm.c b/test-app/startup_arm.c index 72013cfa..c34501c8 100644 --- a/test-app/startup_arm.c +++ b/test-app/startup_arm.c @@ -116,7 +116,10 @@ void (* const IV[])(void) = isr_memfault, // MemFault isr_busfault, // BusFault isr_usagefault, // UsageFault - 0, 0, 0, 0, // 4x reserved + 0, // SecureFault + 0, // reserved + 0, // reserved + 0, // reserved isr_empty, // SVC isr_empty, // DebugMonitor 0, // reserved @@ -170,7 +173,116 @@ void (* const IV[])(void) = isr_empty, // CAN2 isr_empty, // Ethernet isr_empty, // Hibernate - +#elif PLATFORM_stm32l5 + isr_empty, // WWDG_IRQHandler + isr_empty, // PVD_PVM_IRQHandler + isr_empty, // RTC_IRQHandler + isr_empty, // RTC_S_IRQHandler + isr_empty, // TAMP_IRQHandler + isr_empty, // TAMP_S_IRQHandler + isr_empty, // FLASH_IRQHandler + isr_empty, // FLASH_S_IRQHandler + isr_empty, // GTZC_IRQHandler + isr_empty, // RCC_IRQHandler + isr_empty, // RCC_S_IRQHandler + isr_empty, // EXTI0_IRQHandler + isr_empty, // EXTI1_IRQHandler + isr_empty, // EXTI2_IRQHandler + isr_empty, // EXTI3_IRQHandler + isr_empty, // EXTI4_IRQHandler + isr_empty, // EXTI5_IRQHandler + isr_empty, // EXTI6_IRQHandler + isr_empty, // EXTI7_IRQHandler + isr_empty, // EXTI8_IRQHandler + isr_empty, // EXTI9_IRQHandler + isr_empty, // EXTI10_IRQHandler + isr_empty, // EXTI11_IRQHandler + isr_empty, // EXTI12_IRQHandler + isr_empty, // EXTI13_IRQHandler + isr_empty, // EXTI14_IRQHandler + isr_empty, // EXTI15_IRQHandler + isr_empty, // DMAMUX1_IRQHandler + isr_empty, // DMAMUX1_S_IRQHandler + isr_empty, // DMA1_Channel1_IRQHandler + isr_empty, // DMA1_Channel2_IRQHandler + isr_empty, // DMA1_Channel3_IRQHandler + isr_empty, // DMA1_Channel4_IRQHandler + isr_empty, // DMA1_Channel5_IRQHandler + isr_empty, // DMA1_Channel6_IRQHandler + isr_empty, // DMA1_Channel7_IRQHandler + isr_empty, // DMA1_Channel8_IRQHandler + isr_empty, // ADC1_2_IRQHandler + isr_empty, // DAC_IRQHandler + isr_empty, // FDCAN1_IT0_IRQHandler + isr_empty, // FDCAN1_IT1_IRQHandler + isr_empty, // TIM1_BRK_IRQHandler + isr_empty, // TIM1_UP_IRQHandler + isr_empty, // TIM1_TRG_COM_IRQHandler + isr_empty, // TIM1_CC_IRQHandler + isr_empty, // TIM2_IRQHandler + isr_empty, // TIM3_IRQHandler + isr_empty, // TIM4_IRQHandler + isr_empty, // TIM5_IRQHandler + isr_empty, // TIM6_IRQHandler + isr_empty, // TIM7_IRQHandler + isr_empty, // TIM8_BRK_IRQHandler + isr_empty, // TIM8_UP_IRQHandler + isr_empty, // TIM8_TRG_COM_IRQHandler + isr_empty, // TIM8_CC_IRQHandler + isr_empty, // I2C1_EV_IRQHandler + isr_empty, // I2C1_ER_IRQHandler + isr_empty, // I2C2_EV_IRQHandler + isr_empty, // I2C2_ER_IRQHandler + isr_empty, // SPI1_IRQHandler + isr_empty, // SPI2_IRQHandler + isr_empty, // USART1_IRQHandler + isr_empty, // USART2_IRQHandler + isr_empty, // USART3_IRQHandler + isr_empty, // UART4_IRQHandler + isr_empty, // UART5_IRQHandler + isr_empty, // LPUART1_IRQHandler + isr_empty, // LPTIM1_IRQHandler + isr_empty, // LPTIM2_IRQHandler + isr_empty, // TIM15_IRQHandler + isr_empty, // TIM16_IRQHandler + isr_empty, // TIM17_IRQHandler + isr_empty, // COMP_IRQHandler + isr_empty, // USB_FS_IRQHandler + isr_empty, // CRS_IRQHandler + isr_empty, // FMC_IRQHandler + isr_empty, // OCTOSPI1_IRQHandler + isr_empty, // 0 + isr_empty, // SDMMC1_IRQHandler + isr_empty, // 0 + isr_empty, // DMA2_Channel1_IRQHandler + isr_empty, // DMA2_Channel2_IRQHandler + isr_empty, // DMA2_Channel3_IRQHandler + isr_empty, // DMA2_Channel4_IRQHandler + isr_empty, // DMA2_Channel5_IRQHandler + isr_empty, // DMA2_Channel6_IRQHandler + isr_empty, // DMA2_Channel7_IRQHandler + isr_empty, // DMA2_Channel8_IRQHandler + isr_empty, // I2C3_EV_IRQHandler + isr_empty, // I2C3_ER_IRQHandler + isr_empty, // SAI1_IRQHandler + isr_empty, // SAI2_IRQHandler + isr_empty, // TSC_IRQHandler + isr_empty, // AES_IRQHandler + isr_empty, // RNG_IRQHandler + isr_empty, // FPU_IRQHandler + isr_empty, // HASH_IRQHandler + isr_empty, // PKA_IRQHandler + isr_empty, // LPTIM3_IRQHandler + isr_empty, // SPI3_IRQHandler + isr_empty, // I2C4_ER_IRQHandler + isr_empty, // I2C4_EV_IRQHandler + isr_empty, // DFSDM1_FLT0_IRQHandler + isr_empty, // DFSDM1_FLT1_IRQHandler + isr_empty, // DFSDM1_FLT2_IRQHandler + isr_empty, // DFSDM1_FLT3_IRQHandler + isr_empty, // UCPD1_IRQHandler + isr_empty, // ICACHE_IRQHandler + isr_empty, // OTFDEC1_IRQHandler #else /* For STM32F4 */ isr_empty, // NVIC_WWDG_IRQ 0 isr_empty, // PVD_IRQ 1 diff --git a/tools/config.mk b/tools/config.mk index a7d485e7..f9147bf9 100644 --- a/tools/config.mk +++ b/tools/config.mk @@ -47,7 +47,7 @@ endif CONFIG_VARS:= ARCH TARGET SIGN HASH MCUXPRESSO MCUXPRESSO_CPU MCUXPRESSO_DRIVERS \ MCUXPRESSO_CMSIS FREEDOM_E_SDK STM32CUBE CYPRESS_PDL CYPRESS_CORE_LIB CYPRESS_TARGET_LIB DEBUG VTOR \ - CORTEX_M0 NO_ASM EXT_FLASH SPI_FLASH NO_XIP UART_FLASH ALLOW_DOWNGRADE NVM_FLASH_WRITEONCE \ + CORTEX_M0 CORTEX_M33 NO_ASM EXT_FLASH SPI_FLASH NO_XIP UART_FLASH ALLOW_DOWNGRADE NVM_FLASH_WRITEONCE \ WOLFBOOT_VERSION V NO_MPU \ SPMATH RAM_CODE DUALBANK_SWAP IMAGE_HEADER_SIZE PKA PSOC6_CRYPTO WOLFTPM \ WOLFBOOT_PARTITION_SIZE WOLFBOOT_SECTOR_SIZE \