zephyr/include/arch/arc/v2/irq.h
Oleg Zhurakivskyy 8739517107 global: Replace BUILD_ASSERT_MSG() with BUILD_ASSERT()
Replace all occurences of BUILD_ASSERT_MSG() with BUILD_ASSERT()
as a result of merging BUILD_ASSERT() and BUILD_ASSERT_MSG().

Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
2020-03-19 15:47:53 +01:00

194 lines
5.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief ARCv2 public interrupt handling
*
* ARCv2 kernel interrupt handling interface. Included by arc/arch.h.
*/
#ifndef ZEPHYR_INCLUDE_ARCH_ARC_V2_IRQ_H_
#define ZEPHYR_INCLUDE_ARCH_ARC_V2_IRQ_H_
#include <arch/arc/v2/aux_regs.h>
#include <toolchain/common.h>
#include <irq.h>
#include <sys/util.h>
#include <sw_isr_table.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _ASMLANGUAGE
GTEXT(_irq_exit);
GTEXT(arch_irq_enable)
GTEXT(arch_irq_disable)
GTEXT(z_arc_firq_stack_set)
#else
extern void z_arc_firq_stack_set(void);
extern void arch_irq_enable(unsigned int irq);
extern void arch_irq_disable(unsigned int irq);
extern int arch_irq_is_enabled(unsigned int irq);
extern void _irq_exit(void);
extern void z_irq_priority_set(unsigned int irq, unsigned int prio,
u32_t flags);
extern void _isr_wrapper(void);
extern void z_irq_spurious(void *unused);
/* Z_ISR_DECLARE will populate the .intList section with the interrupt's
* parameters, which will then be used by gen_irq_tables.py to create
* the vector table and the software ISR table. This is all done at
* build-time.
*
* We additionally set the priority in the interrupt controller at
* runtime.
*/
#define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
({ \
Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \
z_irq_priority_set(irq_p, priority_p, flags_p); \
irq_p; \
})
/**
* Configure a 'direct' static interrupt.
*
* When firq has no separate stack(CONFIG_ARC_FIRQ_STACK=N), it's not safe
* to call C ISR handlers because sp will be switched to bank1's sp which
* is undefined value.
* So for this case, the priority cannot be set to 0 but next level 1
*
* When firq has separate stack (CONFIG_ARC_FIRQ_STACK=y) but at the same
* time stack checking is enabled (CONFIG_ARC_STACK_CHECKING=y)
* the stack checking can raise stack check exception as sp is switched to
* firq's stack (bank1's sp). So for this case, the priority cannot be set
* to 0 but next level 1.
*
* Note that for the above cases, if application still wants to use firq by
* setting priority to 0. Application can call z_irq_priority_set again.
* Then it's left to application to handle the details of firq
*
* 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) \
({ \
Z_ISR_DECLARE(irq_p, ISR_FLAG_DIRECT, isr_p, NULL); \
BUILD_ASSERT(priority_p || !IS_ENABLED(CONFIG_ARC_FIRQ) || \
(IS_ENABLED(CONFIG_ARC_FIRQ_STACK) && \
!IS_ENABLED(CONFIG_ARC_STACK_CHECKING)), \
"irq priority cannot be set to 0 when CONFIG_ARC_FIRQ_STACK" \
"is not configured or CONFIG_ARC_FIRQ_STACK " \
"and CONFIG_ARC_STACK_CHECKING are configured together"); \
z_irq_priority_set(irq_p, priority_p, flags_p); \
irq_p; \
})
static inline void arch_isr_direct_header(void)
{
#ifdef CONFIG_TRACING
z_sys_trace_isr_enter();
#endif
}
static inline void arch_isr_direct_footer(int maybe_swap)
{
/* clear SW generated interrupt */
if (z_arc_v2_aux_reg_read(_ARC_V2_ICAUSE) ==
z_arc_v2_aux_reg_read(_ARC_V2_AUX_IRQ_HINT)) {
z_arc_v2_aux_reg_write(_ARC_V2_AUX_IRQ_HINT, 0);
}
#ifdef CONFIG_TRACING
z_sys_trace_isr_exit();
#endif
}
#define ARCH_ISR_DIRECT_HEADER() arch_isr_direct_header()
extern void arch_isr_direct_header(void);
#define ARCH_ISR_DIRECT_FOOTER(swap) arch_isr_direct_footer(swap)
/*
* Scheduling can not be done in direct isr. If required, please use kernel
* aware interrupt handling
*/
#define ARCH_ISR_DIRECT_DECLARE(name) \
static inline int name##_body(void); \
__attribute__ ((interrupt("ilink")))void name(void) \
{ \
ISR_DIRECT_HEADER(); \
name##_body(); \
ISR_DIRECT_FOOTER(0); \
} \
static inline int name##_body(void)
/**
*
* @brief Disable all interrupts on the local CPU
*
* This routine disables interrupts. It can be called from either interrupt or
* thread level. This routine returns an architecture-dependent
* lock-out key representing the "interrupt disable state" prior to the call;
* this key can be passed to irq_unlock() to re-enable interrupts.
*
* The lock-out key should only be used as the argument to the
* irq_unlock() API. It should never be used to manually re-enable
* interrupts or to inspect or manipulate the contents of the source register.
*
* This function can be called recursively: it will return a key to return the
* state of interrupt locking to the previous level.
*
* WARNINGS
* Invoking a kernel routine with interrupts locked may result in
* interrupts being re-enabled for an unspecified period of time. If the
* called routine blocks, interrupts will be re-enabled while another
* thread executes, or while the system is idle.
*
* The "interrupt disable state" is an attribute of a thread. Thus, if a
* thread disables interrupts and subsequently invokes a kernel
* routine that causes the calling thread to block, the interrupt
* disable state will be restored when the thread is later rescheduled
* for execution.
*
* @return An architecture-dependent lock-out key representing the
* "interrupt disable state" prior to the call.
*/
static ALWAYS_INLINE unsigned int arch_irq_lock(void)
{
unsigned int key;
__asm__ volatile("clri %0" : "=r"(key):: "memory");
return key;
}
static ALWAYS_INLINE void arch_irq_unlock(unsigned int key)
{
__asm__ volatile("seti %0" : : "ir"(key) : "memory");
}
static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key)
{
/* ARC irq lock uses instruction "clri r0",
* r0 == {26d0, 1b1, STATUS32.IE, STATUS32.E[3:0] }
* bit4 is used to record IE (Interrupt Enable) bit
*/
return (key & 0x10) == 0x10;
}
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_ARCH_ARC_V2_IRQ_H_ */