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 <aurelien@aurel32.net>
This commit is contained in:
Aurelien Jarno 2019-02-10 11:05:51 +01:00 committed by Andrew Boie
commit 992f29a1bc
8 changed files with 22 additions and 20 deletions

View file

@ -336,6 +336,9 @@ config ARCH_HAS_EXECUTABLE_PAGE_BIT
config ARCH_HAS_NOCACHE_MEMORY_SUPPORT config ARCH_HAS_NOCACHE_MEMORY_SUPPORT
bool bool
config ARCH_HAS_RAMFUNC_SUPPORT
bool
# #
# Other architecture related options # Other architecture related options
# #

View file

@ -23,6 +23,7 @@ config CPU_CORTEX_M
select ARCH_HAS_STACK_PROTECTION if ARM_MPU || CPU_CORTEX_M_HAS_SPLIM select ARCH_HAS_STACK_PROTECTION if ARM_MPU || CPU_CORTEX_M_HAS_SPLIM
select ARCH_HAS_USERSPACE if ARM_MPU 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_NOCACHE_MEMORY_SUPPORT if ARM_MPU && CPU_HAS_ARM_MPU && CPU_CORTEX_M7
select ARCH_HAS_RAMFUNC_SUPPORT
select SWAP_NONATOMIC select SWAP_NONATOMIC
help help
This option signifies the use of a CPU of the Cortex-M family. This option signifies the use of a CPU of the Cortex-M family.

View file

@ -79,13 +79,13 @@ void _arch_configure_static_mpu_regions(void)
.attr = K_MEM_PARTITION_P_RW_U_NA_NOCACHE, .attr = K_MEM_PARTITION_P_RW_U_NA_NOCACHE,
}, },
#endif /* CONFIG_NOCACHE_MEMORY */ #endif /* CONFIG_NOCACHE_MEMORY */
#if defined(CONFIG_RAM_FUNCTION) #if defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT)
{ {
.start = (u32_t)&_ramfunc_ram_start, .start = (u32_t)&_ramfunc_ram_start,
.size = (u32_t)&_ramfunc_ram_size, .size = (u32_t)&_ramfunc_ram_size,
.attr = K_MEM_PARTITION_P_RX_U_RX, .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. /* Configure the static MPU regions within firmware SRAM boundaries.

View file

@ -368,7 +368,7 @@ SECTIONS
_nocache_ram_size = _nocache_ram_end - _nocache_ram_start; _nocache_ram_size = _nocache_ram_end - _nocache_ram_start;
#endif /* CONFIG_NOCACHE_MEMORY */ #endif /* CONFIG_NOCACHE_MEMORY */
#if defined(CONFIG_RAM_FUNCTION) #if defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT)
SECTION_DATA_PROLOGUE(.ramfunc,,) SECTION_DATA_PROLOGUE(.ramfunc,,)
{ {
MPU_ALIGN(_ramfunc_ram_size); MPU_ALIGN(_ramfunc_ram_size);
@ -380,7 +380,7 @@ SECTIONS
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
_ramfunc_ram_size = _ramfunc_ram_end - _ramfunc_ram_start; _ramfunc_ram_size = _ramfunc_ram_end - _ramfunc_ram_start;
_ramfunc_rom_start = LOADADDR(.ramfunc); _ramfunc_rom_start = LOADADDR(.ramfunc);
#endif /* CONFIG_RAM_FUNCTION */ #endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */
#if defined(CONFIG_APP_SHARED_MEM) #if defined(CONFIG_APP_SHARED_MEM)
#define APP_SHARED_ALIGN . = ALIGN(_region_min_align); #define APP_SHARED_ALIGN . = ALIGN(_region_min_align);

View file

@ -243,12 +243,14 @@ extern char _nocache_ram_size[];
* management/protection hardware for the target architecture. * management/protection hardware for the target architecture.
* *
* All the functions with '__ramfunc' keyword will be placed into this * 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_start[];
extern char _ramfunc_ram_end[]; extern char _ramfunc_ram_end[];
extern char _ramfunc_ram_size[]; extern char _ramfunc_ram_size[];
extern char _ramfunc_rom_start[]; extern char _ramfunc_rom_start[];
#endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */
#endif /* ! _ASMLANGUAGE */ #endif /* ! _ASMLANGUAGE */

View file

@ -115,15 +115,18 @@ do { \
#define __in_section_unique(seg) ___in_section(seg, __FILE__, __COUNTER__) #define __in_section_unique(seg) ___in_section(seg, __FILE__, __COUNTER__)
#ifdef CONFIG_RAM_FUNCTION /* When using XIP, using '__ramfunc' places a function into RAM instead
/* Using this places a function into RAM instead of FLASH. * of FLASH. Make sure '__ramfunc' is defined only when
* Make sure '__ramfunc' are defined only when CONFIG_RAM_FUNCTION, * CONFIG_ARCH_HAS_RAMFUNC_SUPPORT is defined, so that the compiler can
* so the compiler can report error if used '__ramfunc' but hadn't * report an error if '__ramfunc' is used but the architecture does not
* enable CONFIG_RAM_FUNCTION in Kconfig. * support it.
*/ */
#if !defined(CONFIG_XIP)
#define __ramfunc
#elif defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT)
#define __ramfunc __attribute__((noinline)) \ #define __ramfunc __attribute__((noinline)) \
__attribute__((long_call, section(".ramfunc"))) __attribute__((long_call, section(".ramfunc")))
#endif #endif /* !CONFIG_XIP */
#ifndef __packed #ifndef __packed
#define __packed __attribute__((__packed__)) #define __packed __attribute__((__packed__))

View file

@ -207,13 +207,6 @@ config ERRNO
symbol. The C library must access the per-thread errno via the symbol. The C library must access the per-thread errno via the
_get_errno() symbol. _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 choice SCHED_ALGORITHM
prompt "Scheduler priority queue algorithm" prompt "Scheduler priority queue algorithm"
default SCHED_DUMB default SCHED_DUMB

View file

@ -173,10 +173,10 @@ void _data_copy(void)
{ {
(void)memcpy(&__data_ram_start, &__data_rom_start, (void)memcpy(&__data_ram_start, &__data_rom_start,
((u32_t) &__data_ram_end - (u32_t) &__data_ram_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, (void)memcpy(&_ramfunc_ram_start, &_ramfunc_rom_start,
((u32_t) &_ramfunc_ram_size)); ((u32_t) &_ramfunc_ram_size));
#endif #endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */
#ifdef DT_CCM_BASE_ADDRESS #ifdef DT_CCM_BASE_ADDRESS
(void)memcpy(&__ccm_data_start, &__ccm_data_rom_start, (void)memcpy(&__ccm_data_start, &__ccm_data_rom_start,
((u32_t) &__ccm_data_end - (u32_t) &__ccm_data_start)); ((u32_t) &__ccm_data_end - (u32_t) &__ccm_data_start));