From 992f29a1bc04212d3e3b48591e140238b9b0d2b9 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Sun, 10 Feb 2019 11:05:51 +0100 Subject: [PATCH] arch: make __ramfunc support transparent Instead of having to enable ramfunc support manually, just make it transparently available to users, keeping the MPU region disabled if not used to not waste a MPU region. This however wastes 24 bytes of code area when the MPU is disabled and 48 bytes when it is enabled, and probably a dozen of CPU cycles during boot. I believe it is something acceptable. Note that when XIP is used, code is already in RAM, so the __ramfunc keyword does nothing, but does not generate an error. Signed-off-by: Aurelien Jarno --- arch/Kconfig | 3 +++ arch/arm/core/Kconfig | 1 + arch/arm/core/cortex_m/mpu/arm_core_mpu.c | 4 ++-- include/arch/arm/cortex_m/scripts/linker.ld | 4 ++-- include/linker/linker-defs.h | 4 +++- include/toolchain/gcc.h | 15 +++++++++------ kernel/Kconfig | 7 ------- kernel/init.c | 4 ++-- 8 files changed, 22 insertions(+), 20 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 7790fdea051..f30e5839648 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -336,6 +336,9 @@ config ARCH_HAS_EXECUTABLE_PAGE_BIT config ARCH_HAS_NOCACHE_MEMORY_SUPPORT bool +config ARCH_HAS_RAMFUNC_SUPPORT + bool + # # Other architecture related options # diff --git a/arch/arm/core/Kconfig b/arch/arm/core/Kconfig index 75c35d65132..705a3987125 100644 --- a/arch/arm/core/Kconfig +++ b/arch/arm/core/Kconfig @@ -23,6 +23,7 @@ config CPU_CORTEX_M select ARCH_HAS_STACK_PROTECTION if ARM_MPU || CPU_CORTEX_M_HAS_SPLIM select ARCH_HAS_USERSPACE if ARM_MPU select ARCH_HAS_NOCACHE_MEMORY_SUPPORT if ARM_MPU && CPU_HAS_ARM_MPU && CPU_CORTEX_M7 + select ARCH_HAS_RAMFUNC_SUPPORT select SWAP_NONATOMIC help This option signifies the use of a CPU of the Cortex-M family. diff --git a/arch/arm/core/cortex_m/mpu/arm_core_mpu.c b/arch/arm/core/cortex_m/mpu/arm_core_mpu.c index 4a332e8877c..0b53d9e8910 100644 --- a/arch/arm/core/cortex_m/mpu/arm_core_mpu.c +++ b/arch/arm/core/cortex_m/mpu/arm_core_mpu.c @@ -79,13 +79,13 @@ void _arch_configure_static_mpu_regions(void) .attr = K_MEM_PARTITION_P_RW_U_NA_NOCACHE, }, #endif /* CONFIG_NOCACHE_MEMORY */ -#if defined(CONFIG_RAM_FUNCTION) +#if defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT) { .start = (u32_t)&_ramfunc_ram_start, .size = (u32_t)&_ramfunc_ram_size, .attr = K_MEM_PARTITION_P_RX_U_RX, } -#endif /* CONFIG_RAM_FUNCTION */ +#endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */ }; /* Configure the static MPU regions within firmware SRAM boundaries. diff --git a/include/arch/arm/cortex_m/scripts/linker.ld b/include/arch/arm/cortex_m/scripts/linker.ld index 15e50bcec7b..4bbf65f4450 100644 --- a/include/arch/arm/cortex_m/scripts/linker.ld +++ b/include/arch/arm/cortex_m/scripts/linker.ld @@ -368,7 +368,7 @@ SECTIONS _nocache_ram_size = _nocache_ram_end - _nocache_ram_start; #endif /* CONFIG_NOCACHE_MEMORY */ -#if defined(CONFIG_RAM_FUNCTION) +#if defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT) SECTION_DATA_PROLOGUE(.ramfunc,,) { MPU_ALIGN(_ramfunc_ram_size); @@ -380,7 +380,7 @@ SECTIONS } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) _ramfunc_ram_size = _ramfunc_ram_end - _ramfunc_ram_start; _ramfunc_rom_start = LOADADDR(.ramfunc); -#endif /* CONFIG_RAM_FUNCTION */ +#endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */ #if defined(CONFIG_APP_SHARED_MEM) #define APP_SHARED_ALIGN . = ALIGN(_region_min_align); diff --git a/include/linker/linker-defs.h b/include/linker/linker-defs.h index 61ab3af4a51..b732234729c 100644 --- a/include/linker/linker-defs.h +++ b/include/linker/linker-defs.h @@ -243,12 +243,14 @@ extern char _nocache_ram_size[]; * management/protection hardware for the target architecture. * * All the functions with '__ramfunc' keyword will be placed into this - * sections. + * section, stored in RAM instead of FLASH. */ +#ifdef CONFIG_ARCH_HAS_RAMFUNC_SUPPORT extern char _ramfunc_ram_start[]; extern char _ramfunc_ram_end[]; extern char _ramfunc_ram_size[]; extern char _ramfunc_rom_start[]; +#endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */ #endif /* ! _ASMLANGUAGE */ diff --git a/include/toolchain/gcc.h b/include/toolchain/gcc.h index 297ec32af92..aa43c1376c4 100644 --- a/include/toolchain/gcc.h +++ b/include/toolchain/gcc.h @@ -115,15 +115,18 @@ do { \ #define __in_section_unique(seg) ___in_section(seg, __FILE__, __COUNTER__) -#ifdef CONFIG_RAM_FUNCTION -/* Using this places a function into RAM instead of FLASH. - * Make sure '__ramfunc' are defined only when CONFIG_RAM_FUNCTION, - * so the compiler can report error if used '__ramfunc' but hadn't - * enable CONFIG_RAM_FUNCTION in Kconfig. +/* When using XIP, using '__ramfunc' places a function into RAM instead + * of FLASH. Make sure '__ramfunc' is defined only when + * CONFIG_ARCH_HAS_RAMFUNC_SUPPORT is defined, so that the compiler can + * report an error if '__ramfunc' is used but the architecture does not + * support it. */ +#if !defined(CONFIG_XIP) +#define __ramfunc +#elif defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT) #define __ramfunc __attribute__((noinline)) \ __attribute__((long_call, section(".ramfunc"))) -#endif +#endif /* !CONFIG_XIP */ #ifndef __packed #define __packed __attribute__((__packed__)) diff --git a/kernel/Kconfig b/kernel/Kconfig index 6ebe719d05f..d2261067a89 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -207,13 +207,6 @@ config ERRNO symbol. The C library must access the per-thread errno via the _get_errno() symbol. -config RAM_FUNCTION - bool "Enable __ramfunc support" - help - Using '__ramfunc' places a function into RAM instead of Flash. - Code that for example reprograms flash at runtime can't execute - from flash, in that case must placing code into RAM. - choice SCHED_ALGORITHM prompt "Scheduler priority queue algorithm" default SCHED_DUMB diff --git a/kernel/init.c b/kernel/init.c index adc1b9a2dfb..11859835d10 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -173,10 +173,10 @@ void _data_copy(void) { (void)memcpy(&__data_ram_start, &__data_rom_start, ((u32_t) &__data_ram_end - (u32_t) &__data_ram_start)); -#ifdef CONFIG_RAM_FUNCTION +#ifdef CONFIG_ARCH_HAS_RAMFUNC_SUPPORT (void)memcpy(&_ramfunc_ram_start, &_ramfunc_rom_start, ((u32_t) &_ramfunc_ram_size)); -#endif +#endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */ #ifdef DT_CCM_BASE_ADDRESS (void)memcpy(&__ccm_data_start, &__ccm_data_rom_start, ((u32_t) &__ccm_data_end - (u32_t) &__ccm_data_start));