zephyr/arch/arm/core/isr_wrapper.S

137 lines
3.3 KiB
ArmAsm
Raw Normal View History

/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief ARM Cortex-M wrapper for ISRs with parameter
*
* Wrapper installed in vector table for handling dynamic interrupts that accept
* a parameter.
*/
kernel/arch: consolidate tTCS and TNANO definitions There was a lot of duplication between architectures for the definition of threads and the "nanokernel" guts. These have been consolidated. Now, a common file kernel/unified/include/kernel_structs.h holds the common definitions. Architectures provide two files to complement it: kernel_arch_data.h and kernel_arch_func.h. The first one contains at least the struct _thread_arch and struct _kernel_arch data structures, as well as the struct _callee_saved and struct _caller_saved register layouts. The second file contains anything that needs what is provided by the common stuff in kernel_structs.h. Those two files are only meant to be included in kernel_structs.h in very specific locations. The thread data structure has been separated into three major parts: common struct _thread_base and struct k_thread, and arch-specific struct _thread_arch. The first and third ones are included in the second. The struct s_NANO data structure has been split into two: common struct _kernel and arch-specific struct _kernel_arch. The latter is included in the former. Offsets files have also changed: nano_offsets.h has been renamed kernel_offsets.h and is still included by the arch-specific offsets.c. Also, since the thread and kernel data structures are now made of sub-structures, offsets have to be added to make up the full offset. Some of these additions have been consolidated in shorter symbols, available from kernel/unified/include/offsets_short.h, which includes an arch-specific offsets_arch_short.h. Most of the code include offsets_short.h now instead of offsets.h. Change-Id: I084645cb7e6db8db69aeaaf162963fe157045d5a Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
2016-11-08 23:36:50 +08:00
#include <offsets_short.h>
#include <toolchain.h>
#include <linker/sections.h>
#include <sw_isr_table.h>
kernel/arch: consolidate tTCS and TNANO definitions There was a lot of duplication between architectures for the definition of threads and the "nanokernel" guts. These have been consolidated. Now, a common file kernel/unified/include/kernel_structs.h holds the common definitions. Architectures provide two files to complement it: kernel_arch_data.h and kernel_arch_func.h. The first one contains at least the struct _thread_arch and struct _kernel_arch data structures, as well as the struct _callee_saved and struct _caller_saved register layouts. The second file contains anything that needs what is provided by the common stuff in kernel_structs.h. Those two files are only meant to be included in kernel_structs.h in very specific locations. The thread data structure has been separated into three major parts: common struct _thread_base and struct k_thread, and arch-specific struct _thread_arch. The first and third ones are included in the second. The struct s_NANO data structure has been split into two: common struct _kernel and arch-specific struct _kernel_arch. The latter is included in the former. Offsets files have also changed: nano_offsets.h has been renamed kernel_offsets.h and is still included by the arch-specific offsets.c. Also, since the thread and kernel data structures are now made of sub-structures, offsets have to be added to make up the full offset. Some of these additions have been consolidated in shorter symbols, available from kernel/unified/include/offsets_short.h, which includes an arch-specific offsets_arch_short.h. Most of the code include offsets_short.h now instead of offsets.h. Change-Id: I084645cb7e6db8db69aeaaf162963fe157045d5a Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
2016-11-08 23:36:50 +08:00
#include <kernel_structs.h>
#include <arch/cpu.h>
_ASM_FILE_PROLOGUE
GDATA(_sw_isr_table)
GTEXT(_isr_wrapper)
GTEXT(_IntExit)
/**
*
* @brief Wrapper around ISRs when inserted in software ISR table
*
* When inserted in the vector table, _isr_wrapper() demuxes the ISR table using
* the running interrupt number as the index, and invokes the registered ISR
* with its corresponding argument. When returning from the ISR, it determines
* if a context switch needs to happen (see documentation for __pendsv()) and
* pends the PendSV exception if so: the latter will perform the context switch
* itself.
*
* @return N/A
*/
SECTION_FUNC(TEXT, _isr_wrapper)
push {lr} /* lr is now the first item on the stack */
#ifdef CONFIG_EXECUTION_BENCHMARKING
bl read_timer_start_of_isr
#endif
#ifdef CONFIG_KERNEL_EVENT_LOGGER_INTERRUPT
bl _sys_k_event_logger_interrupt
#endif
#ifdef CONFIG_KERNEL_EVENT_LOGGER_SLEEP
bl _sys_k_event_logger_exit_sleep
#endif
#ifdef CONFIG_SYS_POWER_MANAGEMENT
/*
* All interrupts are disabled when handling idle wakeup. For tickless
* idle, this ensures that the calculation and programming of the device
* for the next timer deadline is not interrupted. For non-tickless idle,
* this ensures that the clearing of the kernel idle state is not
* interrupted. In each case, _sys_power_save_idle_exit is called with
* interrupts disabled.
*/
cpsid i /* PRIMASK = 1 */
/* is this a wakeup from idle ? */
kernel/arch: consolidate tTCS and TNANO definitions There was a lot of duplication between architectures for the definition of threads and the "nanokernel" guts. These have been consolidated. Now, a common file kernel/unified/include/kernel_structs.h holds the common definitions. Architectures provide two files to complement it: kernel_arch_data.h and kernel_arch_func.h. The first one contains at least the struct _thread_arch and struct _kernel_arch data structures, as well as the struct _callee_saved and struct _caller_saved register layouts. The second file contains anything that needs what is provided by the common stuff in kernel_structs.h. Those two files are only meant to be included in kernel_structs.h in very specific locations. The thread data structure has been separated into three major parts: common struct _thread_base and struct k_thread, and arch-specific struct _thread_arch. The first and third ones are included in the second. The struct s_NANO data structure has been split into two: common struct _kernel and arch-specific struct _kernel_arch. The latter is included in the former. Offsets files have also changed: nano_offsets.h has been renamed kernel_offsets.h and is still included by the arch-specific offsets.c. Also, since the thread and kernel data structures are now made of sub-structures, offsets have to be added to make up the full offset. Some of these additions have been consolidated in shorter symbols, available from kernel/unified/include/offsets_short.h, which includes an arch-specific offsets_arch_short.h. Most of the code include offsets_short.h now instead of offsets.h. Change-Id: I084645cb7e6db8db69aeaaf162963fe157045d5a Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
2016-11-08 23:36:50 +08:00
ldr r2, =_kernel
/* requested idle duration, in ticks */
ldr r0, [r2, #_kernel_offset_to_idle]
cmp r0, #0
#if defined(CONFIG_ARMV6_M)
beq _idle_state_cleared
movs.n r1, #0
kernel/arch: consolidate tTCS and TNANO definitions There was a lot of duplication between architectures for the definition of threads and the "nanokernel" guts. These have been consolidated. Now, a common file kernel/unified/include/kernel_structs.h holds the common definitions. Architectures provide two files to complement it: kernel_arch_data.h and kernel_arch_func.h. The first one contains at least the struct _thread_arch and struct _kernel_arch data structures, as well as the struct _callee_saved and struct _caller_saved register layouts. The second file contains anything that needs what is provided by the common stuff in kernel_structs.h. Those two files are only meant to be included in kernel_structs.h in very specific locations. The thread data structure has been separated into three major parts: common struct _thread_base and struct k_thread, and arch-specific struct _thread_arch. The first and third ones are included in the second. The struct s_NANO data structure has been split into two: common struct _kernel and arch-specific struct _kernel_arch. The latter is included in the former. Offsets files have also changed: nano_offsets.h has been renamed kernel_offsets.h and is still included by the arch-specific offsets.c. Also, since the thread and kernel data structures are now made of sub-structures, offsets have to be added to make up the full offset. Some of these additions have been consolidated in shorter symbols, available from kernel/unified/include/offsets_short.h, which includes an arch-specific offsets_arch_short.h. Most of the code include offsets_short.h now instead of offsets.h. Change-Id: I084645cb7e6db8db69aeaaf162963fe157045d5a Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
2016-11-08 23:36:50 +08:00
/* clear kernel idle state */
str r1, [r2, #_kernel_offset_to_idle]
blx _sys_power_save_idle_exit
_idle_state_cleared:
#elif defined(CONFIG_ARMV7_M)
ittt ne
movne r1, #0
kernel/arch: consolidate tTCS and TNANO definitions There was a lot of duplication between architectures for the definition of threads and the "nanokernel" guts. These have been consolidated. Now, a common file kernel/unified/include/kernel_structs.h holds the common definitions. Architectures provide two files to complement it: kernel_arch_data.h and kernel_arch_func.h. The first one contains at least the struct _thread_arch and struct _kernel_arch data structures, as well as the struct _callee_saved and struct _caller_saved register layouts. The second file contains anything that needs what is provided by the common stuff in kernel_structs.h. Those two files are only meant to be included in kernel_structs.h in very specific locations. The thread data structure has been separated into three major parts: common struct _thread_base and struct k_thread, and arch-specific struct _thread_arch. The first and third ones are included in the second. The struct s_NANO data structure has been split into two: common struct _kernel and arch-specific struct _kernel_arch. The latter is included in the former. Offsets files have also changed: nano_offsets.h has been renamed kernel_offsets.h and is still included by the arch-specific offsets.c. Also, since the thread and kernel data structures are now made of sub-structures, offsets have to be added to make up the full offset. Some of these additions have been consolidated in shorter symbols, available from kernel/unified/include/offsets_short.h, which includes an arch-specific offsets_arch_short.h. Most of the code include offsets_short.h now instead of offsets.h. Change-Id: I084645cb7e6db8db69aeaaf162963fe157045d5a Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
2016-11-08 23:36:50 +08:00
/* clear kernel idle state */
strne r1, [r2, #_kernel_offset_to_idle]
blxne _sys_power_save_idle_exit
arm: Restructure ARM cpu related preprocessor conditionals. The ARM code base provides for three mutually exclusive ARM architecture related conditional compilation choices. M0_M0PLUS, M3_M4 and M7. Throughout the code base we have conditional compilation gated around these three choices. Adjust the form of this conditional compilation to adopt a uniform structure. The uniform structure always selects code based on the definition of an appropriate config option rather the the absence of a definition. Removing the extensive use of #else ensures that when support for other ARM architecture versions is added we get hard compilation failures rather than attempting to compile inappropriate code for the added architecture with unexpected runtime consequences. Adopting this uniform structure makes it straight forward to replace the adhoc CPU_CORTEX_M3_M4 and CPU_CORTEX_M0_M0PLUS configuration variables with ones that directly represent the actual underlying ARM architectures we provide support for. This change also paves the way for folding adhoc conditional compilation related to CPU_CORTEX_M7 directly in support for ARMv7-M. This change is mechanical in nature involving two transforms: 1) #if !defined(CONFIG_CPU_CORTEX_M0_M0PLUS) ... is transformed to: #if defined(CONFIG_CPU_CORTEX_M0_M0PLUS) #elif defined(CONFIG_CPU_CORTEX_M3_M4) || defined(CONFIG_CPU_CORTEX_M7) ... 2) #if defined(CONFIG_CPU_CORTEX_M0_M0PLUS) ... #else ... #endif is transformed to: #if defined(CONFIG_CPU_CORTEX_M0_M0PLUS) ... #elif defined(CONFIG_CPU_CORTEX_M3_M4) || defined(CONFIG_CPU_CORTEX_M7) ... #else #error Unknown ARM architecture #endif Change-Id: I7229029b174da3a8b3c6fb2eec63d776f1d11e24 Signed-off-by: Marcus Shawcroft <marcus.shawcroft@arm.com>
2016-12-31 21:18:25 +08:00
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
cpsie i /* re-enable interrupts (PRIMASK = 0) */
#endif
mrs r0, IPSR /* get exception number */
#if defined(CONFIG_ARMV6_M)
ldr r1, =16
subs r0, r1 /* get IRQ number */
lsls r0, #3 /* table is 8-byte wide */
#elif defined(CONFIG_ARMV7_M)
sub r0, r0, #16 /* get IRQ number */
lsl r0, r0, #3 /* table is 8-byte wide */
arm: Restructure ARM cpu related preprocessor conditionals. The ARM code base provides for three mutually exclusive ARM architecture related conditional compilation choices. M0_M0PLUS, M3_M4 and M7. Throughout the code base we have conditional compilation gated around these three choices. Adjust the form of this conditional compilation to adopt a uniform structure. The uniform structure always selects code based on the definition of an appropriate config option rather the the absence of a definition. Removing the extensive use of #else ensures that when support for other ARM architecture versions is added we get hard compilation failures rather than attempting to compile inappropriate code for the added architecture with unexpected runtime consequences. Adopting this uniform structure makes it straight forward to replace the adhoc CPU_CORTEX_M3_M4 and CPU_CORTEX_M0_M0PLUS configuration variables with ones that directly represent the actual underlying ARM architectures we provide support for. This change also paves the way for folding adhoc conditional compilation related to CPU_CORTEX_M7 directly in support for ARMv7-M. This change is mechanical in nature involving two transforms: 1) #if !defined(CONFIG_CPU_CORTEX_M0_M0PLUS) ... is transformed to: #if defined(CONFIG_CPU_CORTEX_M0_M0PLUS) #elif defined(CONFIG_CPU_CORTEX_M3_M4) || defined(CONFIG_CPU_CORTEX_M7) ... 2) #if defined(CONFIG_CPU_CORTEX_M0_M0PLUS) ... #else ... #endif is transformed to: #if defined(CONFIG_CPU_CORTEX_M0_M0PLUS) ... #elif defined(CONFIG_CPU_CORTEX_M3_M4) || defined(CONFIG_CPU_CORTEX_M7) ... #else #error Unknown ARM architecture #endif Change-Id: I7229029b174da3a8b3c6fb2eec63d776f1d11e24 Signed-off-by: Marcus Shawcroft <marcus.shawcroft@arm.com>
2016-12-31 21:18:25 +08:00
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
ldr r1, =_sw_isr_table
add r1, r1, r0 /* table entry: ISRs must have their MSB set to stay
* in thumb mode */
ldm r1!,{r0,r3} /* arg in r0, ISR in r3 */
#ifdef CONFIG_EXECUTION_BENCHMARKING
stm sp!,{r0-r3} /* Save r0 to r4 into stack */
push {lr}
bl read_timer_end_of_isr
#if defined(CONFIG_ARMV6_M)
pop {r3}
mov lr,r3
#else
pop {lr}
#endif
ldm sp!,{r0-r3} /* Restore r0 to r4 regs */
#endif
blx r3 /* call ISR */
#if defined(CONFIG_ARMV6_M)
pop {r3}
mov lr, r3
#elif defined(CONFIG_ARMV7_M)
pop {lr}
arm: Restructure ARM cpu related preprocessor conditionals. The ARM code base provides for three mutually exclusive ARM architecture related conditional compilation choices. M0_M0PLUS, M3_M4 and M7. Throughout the code base we have conditional compilation gated around these three choices. Adjust the form of this conditional compilation to adopt a uniform structure. The uniform structure always selects code based on the definition of an appropriate config option rather the the absence of a definition. Removing the extensive use of #else ensures that when support for other ARM architecture versions is added we get hard compilation failures rather than attempting to compile inappropriate code for the added architecture with unexpected runtime consequences. Adopting this uniform structure makes it straight forward to replace the adhoc CPU_CORTEX_M3_M4 and CPU_CORTEX_M0_M0PLUS configuration variables with ones that directly represent the actual underlying ARM architectures we provide support for. This change also paves the way for folding adhoc conditional compilation related to CPU_CORTEX_M7 directly in support for ARMv7-M. This change is mechanical in nature involving two transforms: 1) #if !defined(CONFIG_CPU_CORTEX_M0_M0PLUS) ... is transformed to: #if defined(CONFIG_CPU_CORTEX_M0_M0PLUS) #elif defined(CONFIG_CPU_CORTEX_M3_M4) || defined(CONFIG_CPU_CORTEX_M7) ... 2) #if defined(CONFIG_CPU_CORTEX_M0_M0PLUS) ... #else ... #endif is transformed to: #if defined(CONFIG_CPU_CORTEX_M0_M0PLUS) ... #elif defined(CONFIG_CPU_CORTEX_M3_M4) || defined(CONFIG_CPU_CORTEX_M7) ... #else #error Unknown ARM architecture #endif Change-Id: I7229029b174da3a8b3c6fb2eec63d776f1d11e24 Signed-off-by: Marcus Shawcroft <marcus.shawcroft@arm.com>
2016-12-31 21:18:25 +08:00
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
/* exception return is done in _IntExit() */
b _IntExit