arch/arm/aarch32: add IRQ relay mechanism to ARMv7/8-M

This patch allows the `SW_VECTOR_RELAY` and
`SW_VECTOR_RELAY_CLIENT` pair to be
enabled on the ARMv7-M and ARMv8-M architectures
and covers all additional interrupt vectors.

Signed-off-by: Rafał Kuźnia <rafal.kuznia@nordicsemi.no>
Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
This commit is contained in:
Rafał Kuźnia 2020-05-13 14:01:55 +02:00 committed by Ioannis Glaropoulos
commit 89bf746ebe
5 changed files with 36 additions and 54 deletions

View file

@ -21,7 +21,7 @@ zephyr_library_sources(
zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S) zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S)
zephyr_library_sources_ifdef(CONFIG_CPLUSPLUS __aeabi_atexit.c) zephyr_library_sources_ifdef(CONFIG_CPLUSPLUS __aeabi_atexit.c)
zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c)
zephyr_library_sources_ifdef(CONFIG_CPU_CORTEX_M0 irq_relay.S) zephyr_library_sources_ifdef(CONFIG_SW_VECTOR_RELAY irq_relay.S)
zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.S) zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.S)
add_subdirectory_ifdef(CONFIG_CPU_CORTEX_M cortex_m) add_subdirectory_ifdef(CONFIG_CPU_CORTEX_M cortex_m)

View file

@ -267,21 +267,16 @@ config DYNAMIC_DIRECT_INTERRUPTS
config SW_VECTOR_RELAY config SW_VECTOR_RELAY
bool "Enable Software Vector Relay" bool "Enable Software Vector Relay"
depends on ARMV6_M_ARMV8_M_BASELINE && !(CPU_CORTEX_M0_HAS_VECTOR_TABLE_REMAP || CPU_CORTEX_M_HAS_VTOR)
help help
When building bootloader firmware this option adds a When building a bootloader firmware this option adds a
Vector Table relay handler and relay vector table, to vector table relay handler and a vector relay table, to
relay interrupts based on a vector table pointer. relay interrupts based on a vector table pointer.
This is only This is only required but not limited to Cortex-M Baseline CPUs
required for Cortex-M0 (or an Armv8-M baseline core) with no hardware with no hardware vector table relocation mechanisms (e.g. VTOR).
vector table relocation mechanisms or for Cortex-M0+
(or an Armv8-M baseline core) with no VTOR and no other hardware
relocation table mechanisms.
config SW_VECTOR_RELAY_CLIENT config SW_VECTOR_RELAY_CLIENT
bool "Enable Software Vector Relay (client)" bool "Enable Software Vector Relay (client)"
default y if BOOTLOADER_MCUBOOT default y if BOOTLOADER_MCUBOOT && !(CPU_CORTEX_M0_HAS_VECTOR_TABLE_REMAP || CPU_CORTEX_M_HAS_VTOR)
depends on ARMV6_M_ARMV8_M_BASELINE && !(CPU_CORTEX_M0_HAS_VECTOR_TABLE_REMAP || CPU_CORTEX_M_HAS_VTOR)
help help
Another image has enabled SW_VECTOR_RELAY, and will relay interrupts Another image has enabled SW_VECTOR_RELAY, and will relay interrupts
to this image. Enable this to make sure the vector table pointer in to this image. Enable this to make sure the vector table pointer in

View file

@ -75,37 +75,10 @@ SECTION_FUNC(vector_relay_table, __vector_relay_table)
.word __vector_relay_handler .word __vector_relay_handler
/* End of system exception */ /* End of system exception */
.rept CONFIG_NUM_IRQS
.word __vector_relay_handler .word __vector_relay_handler
.word __vector_relay_handler .endr
.word __vector_relay_handler
.word __vector_relay_handler GTEXT(__vector_relay_table)
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
.word __vector_relay_handler
#endif #endif

View file

@ -40,28 +40,39 @@
#ifdef CONFIG_CPU_CORTEX_M_HAS_VTOR #ifdef CONFIG_CPU_CORTEX_M_HAS_VTOR
#ifdef CONFIG_XIP #ifdef CONFIG_XIP
#ifdef CONFIG_SW_VECTOR_RELAY
#define VECTOR_ADDRESS ((uintptr_t)__vector_relay_table)
#else
#define VECTOR_ADDRESS ((uintptr_t)_vector_start) #define VECTOR_ADDRESS ((uintptr_t)_vector_start)
#else
#define VECTOR_ADDRESS CONFIG_SRAM_BASE_ADDRESS
#endif #endif
static inline void relocate_vector_table(void) #else /* CONFIG_XIP */
{ #define VECTOR_ADDRESS CONFIG_SRAM_BASE_ADDRESS
SCB->VTOR = VECTOR_ADDRESS & SCB_VTOR_TBLOFF_Msk; #endif /* CONFIG_XIP */
__DSB();
__ISB();
}
#else #else /* CONFIG_CPU_CORTEX_M_HAS_VTOR */
#define VECTOR_ADDRESS 0
#endif /* CONFIG_CPU_CORTEX_M_HAS_VTOR */
#if defined(CONFIG_SW_VECTOR_RELAY) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT) #if defined(CONFIG_SW_VECTOR_RELAY) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT)
Z_GENERIC_SECTION(.vt_pointer_section) __attribute__((used)) Z_GENERIC_SECTION(.vt_pointer_section) __attribute__((used))
void *_vector_table_pointer; void *_vector_table_pointer;
#endif #endif
#define VECTOR_ADDRESS 0
#ifdef CONFIG_CPU_CORTEX_M_HAS_VTOR
static inline void relocate_vector_table(void)
#else
void __weak relocate_vector_table(void) void __weak relocate_vector_table(void)
#endif
{ {
#if defined(CONFIG_CPU_CORTEX_M_HAS_VTOR) && !defined(CONFIG_SW_VECTOR_RELAY_CLIENT)
SCB->VTOR = VECTOR_ADDRESS & SCB_VTOR_TBLOFF_Msk;
__DSB();
__ISB();
#endif
#if !defined(CONFIG_CPU_CORTEX_M_HAS_VTOR) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT)
#if defined(CONFIG_XIP) && (CONFIG_FLASH_BASE_ADDRESS != 0) || \ #if defined(CONFIG_XIP) && (CONFIG_FLASH_BASE_ADDRESS != 0) || \
!defined(CONFIG_XIP) && (CONFIG_SRAM_BASE_ADDRESS != 0) !defined(CONFIG_XIP) && (CONFIG_SRAM_BASE_ADDRESS != 0)
size_t vector_size = (size_t)_vector_end - (size_t)_vector_start; size_t vector_size = (size_t)_vector_end - (size_t)_vector_start;
@ -69,14 +80,13 @@ void __weak relocate_vector_table(void)
#elif defined(CONFIG_SW_VECTOR_RELAY) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT) #elif defined(CONFIG_SW_VECTOR_RELAY) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT)
_vector_table_pointer = _vector_start; _vector_table_pointer = _vector_start;
#endif #endif
#endif /* !defined(CONFIG_CPU_CORTEX_M_HAS_VTOR) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT) */
} }
#if defined(__GNUC__) #if defined(__GNUC__)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
#endif /* CONFIG_CPU_CORTEX_M_HAS_VTOR */
#if defined(CONFIG_CPU_HAS_FPU) #if defined(CONFIG_CPU_HAS_FPU)
static inline void z_arm_floating_point_init(void) static inline void z_arm_floating_point_init(void)
{ {

View file

@ -163,6 +163,10 @@ extern char _image_rodata_size[];
extern char _vector_start[]; extern char _vector_start[];
extern char _vector_end[]; extern char _vector_end[];
#ifdef CONFIG_SW_VECTOR_RELAY
extern char __vector_relay_table[];
#endif
#ifdef CONFIG_COVERAGE_GCOV #ifdef CONFIG_COVERAGE_GCOV
extern char __gcov_bss_start[]; extern char __gcov_bss_start[];
extern char __gcov_bss_end[]; extern char __gcov_bss_end[];