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:
parent
e7acd3224c
commit
2752357922
2 changed files with 110 additions and 0 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue