arm: enable direct interrupts feature

Issue: ZEP-1038
Change-Id: I5417e516cc994e2bbe6bb987d9ed95e912941aa0
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2017-02-09 12:40:08 -08:00 committed by Anas Nashif
commit 2752357922
2 changed files with 110 additions and 0 deletions

View file

@ -22,6 +22,8 @@
#include <sections.h> #include <sections.h>
#include <sw_isr_table.h> #include <sw_isr_table.h>
#include <irq.h> #include <irq.h>
#include <kernel_structs.h>
#include <logging/kernel_event_logger.h>
extern void __reserved(void); extern void __reserved(void);
@ -131,3 +133,58 @@ void _irq_spurious(void *unused)
__reserved(); __reserved();
} }
/* FIXME: IRQ direct inline functions have to be placed here and not in
* arch/cpu.h as inline functions due to nasty circular dependency between
* arch/cpu.h and kernel_structs.h; the inline functions typically need to
* perform operations on _kernel. For now, leave as regular functions, a
* future iteration will resolve this.
* We have a similar issue with the k_event_logger functions.
*
* See https://jira.zephyrproject.org/browse/ZEP-1595
*/
#ifdef CONFIG_SYS_POWER_MANAGEMENT
void _arch_isr_direct_pm(void)
{
#if defined(CONFIG_ARMV6_M)
int key;
/* irq_lock() does what we wan for this CPU */
key = irq_lock();
#elif defined(CONFIG_ARMV7_M)
/* Lock all interrupts. irq_lock() will on this CPU only disable those
* lower than BASEPRI, which is not what we want. See comments in
* arch/arm/core/isr_wrapper.S
*/
__asm__ volatile("cpsid i" : : : "memory");
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
if (_kernel.idle) {
int32_t idle_val = _kernel.idle;
_kernel.idle = 0;
_sys_power_save_idle_exit(idle_val);
}
#if defined(CONFIG_ARMV6_M)
irq_unlock(key);
#elif defined(CONFIG_ARMV7_M)
__asm__ volatile("cpsie i" : : : "memory");
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
}
#endif
#if defined(CONFIG_KERNEL_EVENT_LOGGER_SLEEP) || \
defined(CONFIG_KERNEL_EVENT_LOGGER_INTERRUPT)
void _arch_isr_direct_header(void)
{
_sys_k_event_logger_interrupt();
_sys_k_event_logger_exit_sleep();
}
#endif

View file

@ -85,6 +85,59 @@ extern void _irq_priority_set(unsigned int irq, unsigned int prio,
irq_p; \ irq_p; \
}) })
/**
* Configure a 'direct' static interrupt.
*
* See include/irq.h for details.
* All arguments must be computable at build time.
*/
#define _ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \
({ \
_ISR_DECLARE(irq_p, ISR_FLAG_DIRECT, isr_p, NULL); \
_irq_priority_set(irq_p, priority_p, flags_p); \
irq_p; \
})
/* FIXME prefer these inline, but see ZEP-1595 */
#ifdef CONFIG_SYS_POWER_MANAGEMENT
extern void _arch_isr_direct_pm(void);
#define _ARCH_ISR_DIRECT_PM() _arch_isr_direct_pm()
#else
#define _ARCH_ISR_DIRECT_PM() do { } while (0)
#endif
#if defined(CONFIG_KERNEL_EVENT_LOGGER_SLEEP) || \
defined(CONFIG_KERNEL_EVENT_LOGGER_INTERRUPT)
#define _ARCH_ISR_DIRECT_HEADER() _arch_isr_direct_header()
extern void _arch_isr_direct_header(void);
#else
#define _ARCH_ISR_DIRECT_HEADER() do { } while (0)
#endif
#define _ARCH_ISR_DIRECT_FOOTER(swap) _arch_isr_direct_footer(swap)
/* arch/arm/core/exc_exit.S */
extern void _IntExit(void);
static inline void _arch_isr_direct_footer(int maybe_swap)
{
if (maybe_swap) {
_IntExit();
}
}
#define _ARCH_ISR_DIRECT_DECLARE(name) \
static inline int name##_body(void); \
__attribute__ ((interrupt ("IRQ"))) void name(void) \
{ \
int check_reschedule; \
ISR_DIRECT_HEADER(); \
check_reschedule = name##_body(); \
ISR_DIRECT_FOOTER(check_reschedule); \
} \
static inline int name##_body(void)
/* Spurious interrupt handler. Throws an error if called */ /* Spurious interrupt handler. Throws an error if called */
extern void _irq_spurious(void *unused); extern void _irq_spurious(void *unused);