From 2f7688bfd3d3114ff039b5b3d1795a9388d6f355 Mon Sep 17 00:00:00 2001 From: Bobby Noelte Date: Thu, 14 Sep 2017 20:23:53 +0200 Subject: [PATCH] arch: arm: core: fix vector table relocate write to flash Some SOCs (e.g. STM32F0) can map the flash to address 0 and the flash base address at the same time. Prevent writing to duplicate flash address which stops the SOC. Allow Cortex M SOCs to create their own vector table relocation function. Provide a relocation function for STM32F0x SOCs. Fixes #3923 Signed-off-by: Bobby Noelte Signed-off-by: Neil Armstrong --- arch/arm/core/cortex_m/prep_c.c | 2 +- arch/arm/soc/st_stm32/stm32f0/soc.c | 33 +++++++++++++++++++++ include/arch/arm/cortex_m/scripts/linker.ld | 10 +++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/arch/arm/core/cortex_m/prep_c.c b/arch/arm/core/cortex_m/prep_c.c index 138237937a3..40546aca819 100644 --- a/arch/arm/core/cortex_m/prep_c.c +++ b/arch/arm/core/cortex_m/prep_c.c @@ -27,7 +27,7 @@ #ifdef CONFIG_ARMV6_M #define VECTOR_ADDRESS 0 -static inline void relocate_vector_table(void) +void __weak relocate_vector_table(void) { #if defined(CONFIG_XIP) && (CONFIG_FLASH_BASE_ADDRESS != 0) || \ !defined(CONFIG_XIP) && (CONFIG_SRAM_BASE_ADDRESS != 0) diff --git a/arch/arm/soc/st_stm32/stm32f0/soc.c b/arch/arm/soc/st_stm32/stm32f0/soc.c index 727c348365d..4b3db8cae98 100644 --- a/arch/arm/soc/st_stm32/stm32f0/soc.c +++ b/arch/arm/soc/st_stm32/stm32f0/soc.c @@ -15,6 +15,39 @@ #include #include #include +#include +#include + + +/** + * @brief Relocate vector table to SRAM. + * + * On Cortex-M0 platforms, the Vector Base address cannot be changed. + * + * A Zephyr image that is run from the mcuboot bootloader must relocate the + * vector table to SRAM to be able to replace the vectors pointing to the + * bootloader. + * + * A zephyr image that is a bootloader does not have to relocate the + * vector table. + * + * Replaces the default function from prep_c.c. + * + * @note Zephyr applications that will not be loaded by a bootloader should + * pretend to be a bootloader if the SRAM vector table is not needed. + */ +void relocate_vector_table(void) +{ +#ifndef CONFIG_IS_BOOTLOADER + extern char _ram_vector_start[]; + + size_t vector_size = (size_t)_vector_end - (size_t)_vector_start; + + memcpy(_ram_vector_start, _vector_start, vector_size); + LL_SYSCFG_SetRemapMemory(LL_SYSCFG_REMAP_SRAM); +#endif +} + /** * @brief This function configures the source of stm32cube time base. diff --git a/include/arch/arm/cortex_m/scripts/linker.ld b/include/arch/arm/cortex_m/scripts/linker.ld index ba6efff42d8..79953edbf55 100644 --- a/include/arch/arm/cortex_m/scripts/linker.ld +++ b/include/arch/arm/cortex_m/scripts/linker.ld @@ -181,6 +181,16 @@ SECTIONS GROUP_START(RAMABLE_REGION) +#if defined(CONFIG_SOC_SERIES_STM32F0X) && !defined(CONFIG_IS_BOOTLOADER) + /* Must be first in ramable region */ + SECTION_PROLOGUE(.st_stm32f0x_vt,(NOLOAD),) + { + _ram_vector_start = .; + . += _vector_end - _vector_start; + _ram_vector_end = .; + } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) +#endif + #ifdef CONFIG_APPLICATION_MEMORY SECTION_DATA_PROLOGUE(_APP_DATA_SECTION_NAME, (OPTIONAL),) {