LCOV - code coverage report
Current view: top level - zephyr/arch/arm - irq.h Coverage Total Hit
Test: new.info Lines: 10.5 % 19 2
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            1 : /*
       2              :  * Copyright (c) 2013-2014 Wind River Systems, Inc.
       3              :  * Copyright (c) 2019 Nordic Semiconductor ASA.
       4              :  *
       5              :  * SPDX-License-Identifier: Apache-2.0
       6              :  */
       7              : 
       8              : /**
       9              :  * @file
      10              :  * @brief ARM AArch32 public interrupt handling
      11              :  *
      12              :  * ARM AArch32-specific kernel interrupt handling interface. Included by
      13              :  * arm/arch.h.
      14              :  */
      15              : 
      16              : #ifndef ZEPHYR_INCLUDE_ARCH_ARM_IRQ_H_
      17              : #define ZEPHYR_INCLUDE_ARCH_ARM_IRQ_H_
      18              : 
      19              : #include <zephyr/sw_isr_table.h>
      20              : #include <stdbool.h>
      21              : 
      22              : #ifdef __cplusplus
      23              : extern "C" {
      24              : #endif
      25              : 
      26              : #ifdef _ASMLANGUAGE
      27              : GTEXT(z_arm_int_exit);
      28              : GTEXT(arch_irq_enable)
      29              : GTEXT(arch_irq_disable)
      30              : GTEXT(arch_irq_is_enabled)
      31              : #if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER)
      32              : GTEXT(z_soc_irq_get_active)
      33              : GTEXT(z_soc_irq_eoi)
      34              : #endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */
      35              : #else
      36              : 
      37              : #if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER)
      38            0 : extern void arm_irq_enable(unsigned int irq);
      39            0 : extern void arm_irq_disable(unsigned int irq);
      40            0 : extern int arm_irq_is_enabled(unsigned int irq);
      41            0 : extern void arm_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags);
      42              : #if !defined(CONFIG_MULTI_LEVEL_INTERRUPTS)
      43            0 : #define arch_irq_enable(irq)                     arm_irq_enable(irq)
      44            0 : #define arch_irq_disable(irq)                    arm_irq_disable(irq)
      45            0 : #define arch_irq_is_enabled(irq)                 arm_irq_is_enabled(irq)
      46              : #define z_arm_irq_priority_set(irq, prio, flags) arm_irq_priority_set(irq, prio, flags)
      47              : #endif
      48              : #endif
      49              : 
      50              : #if defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) || defined(CONFIG_MULTI_LEVEL_INTERRUPTS)
      51              : /*
      52              :  * When a custom interrupt controller or multi-level interrupts is specified,
      53              :  * map the architecture interrupt control functions to the SoC layer interrupt
      54              :  * control functions.
      55              :  */
      56              : 
      57              : void z_soc_irq_init(void);
      58              : void z_soc_irq_enable(unsigned int irq);
      59              : void z_soc_irq_disable(unsigned int irq);
      60              : int z_soc_irq_is_enabled(unsigned int irq);
      61              : 
      62              : void z_soc_irq_priority_set(
      63              :         unsigned int irq, unsigned int prio, unsigned int flags);
      64              : 
      65              : unsigned int z_soc_irq_get_active(void);
      66              : void z_soc_irq_eoi(unsigned int irq);
      67              : 
      68              : #define arch_irq_enable(irq)            z_soc_irq_enable(irq)
      69              : #define arch_irq_disable(irq)           z_soc_irq_disable(irq)
      70              : #define arch_irq_is_enabled(irq)        z_soc_irq_is_enabled(irq)
      71              : 
      72              : #define z_arm_irq_priority_set(irq, prio, flags)        \
      73              :         z_soc_irq_priority_set(irq, prio, flags)
      74              : 
      75              : #endif
      76              : 
      77              : extern void z_arm_int_exit(void);
      78              : 
      79              : extern void z_arm_interrupt_init(void);
      80              : 
      81              : /* Flags for use with IRQ_CONNECT() */
      82              : /**
      83              :  * Set this interrupt up as a zero-latency IRQ. If CONFIG_ZERO_LATENCY_LEVELS
      84              :  * is 1 it has a fixed hardware priority level (discarding what was supplied
      85              :  * in the interrupt's priority argument). If CONFIG_ZERO_LATENCY_LEVELS is
      86              :  * greater 1 it has the priority level assigned by the argument.
      87              :  * The interrupt will run even if irq_lock() is active. Be careful!
      88              :  */
      89            1 : #define IRQ_ZERO_LATENCY        BIT(0)
      90              : 
      91              : #ifdef CONFIG_CPU_CORTEX_M
      92              : 
      93              : #if defined(CONFIG_ZERO_LATENCY_LEVELS)
      94              : #define ZERO_LATENCY_LEVELS CONFIG_ZERO_LATENCY_LEVELS
      95              : #else
      96              : #define ZERO_LATENCY_LEVELS 1
      97              : #endif
      98              : 
      99              : #define _CHECK_PRIO(priority_p, flags_p) \
     100              :         BUILD_ASSERT(((flags_p & IRQ_ZERO_LATENCY) && \
     101              :                       ((ZERO_LATENCY_LEVELS == 1) || \
     102              :                        (priority_p < ZERO_LATENCY_LEVELS))) || \
     103              :                      (priority_p <= IRQ_PRIO_LOWEST), \
     104              :                      "Invalid interrupt priority. Values must not exceed IRQ_PRIO_LOWEST");
     105              : #else
     106              : #define _CHECK_PRIO(priority_p, flags_p)
     107              : #endif
     108              : 
     109              : /* All arguments must be computable by the compiler at build time.
     110              :  *
     111              :  * Z_ISR_DECLARE will populate the .intList section with the interrupt's
     112              :  * parameters, which will then be used by gen_irq_tables.py to create
     113              :  * the vector table and the software ISR table. This is all done at
     114              :  * build-time.
     115              :  *
     116              :  * We additionally set the priority in the interrupt controller at
     117              :  * runtime.
     118              :  */
     119            0 : #define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
     120              : { \
     121              :         BUILD_ASSERT(!(flags_p & IRQ_ZERO_LATENCY), \
     122              :                         "ZLI interrupts must be registered using IRQ_DIRECT_CONNECT()"); \
     123              :         _CHECK_PRIO(priority_p, flags_p) \
     124              :         Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \
     125              :         z_arm_irq_priority_set(irq_p, priority_p, flags_p); \
     126              : }
     127              : 
     128            0 : #define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \
     129              : { \
     130              :         BUILD_ASSERT(IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS) || !(flags_p & IRQ_ZERO_LATENCY), \
     131              :                         "ZLI interrupt registered but feature is disabled"); \
     132              :         _CHECK_PRIO(priority_p, flags_p) \
     133              :         Z_ISR_DECLARE_DIRECT(irq_p, ISR_FLAG_DIRECT, isr_p); \
     134              :         z_arm_irq_priority_set(irq_p, priority_p, flags_p); \
     135              : }
     136              : 
     137              : #ifdef CONFIG_PM
     138              : extern void _arch_isr_direct_pm(void);
     139              : #define ARCH_ISR_DIRECT_PM() _arch_isr_direct_pm()
     140              : #else
     141            0 : #define ARCH_ISR_DIRECT_PM() do { } while (false)
     142              : #endif
     143              : 
     144            0 : #define ARCH_ISR_DIRECT_HEADER() arch_isr_direct_header()
     145            0 : #define ARCH_ISR_DIRECT_FOOTER(swap) arch_isr_direct_footer(swap)
     146              : 
     147              : /* arch/arm/core/exc_exit.S */
     148              : extern void z_arm_int_exit(void);
     149              : 
     150              : #ifdef CONFIG_TRACING_ISR
     151              : extern void sys_trace_isr_enter(void);
     152              : extern void sys_trace_isr_exit(void);
     153              : #endif
     154              : 
     155            0 : static inline void arch_isr_direct_header(void)
     156              : {
     157              : #ifdef CONFIG_TRACING_ISR
     158              :         sys_trace_isr_enter();
     159              : #endif
     160              : }
     161              : 
     162            0 : static inline void arch_isr_direct_footer(int maybe_swap)
     163              : {
     164              : #ifdef CONFIG_TRACING_ISR
     165              :         sys_trace_isr_exit();
     166              : #endif
     167              :         if (maybe_swap != 0) {
     168              :                 z_arm_int_exit();
     169              :         }
     170              : }
     171              : 
     172            0 : #define ARCH_ISR_DIAG_OFF \
     173              :         TOOLCHAIN_DISABLE_CLANG_WARNING(TOOLCHAIN_WARNING_EXTRA) \
     174              :         TOOLCHAIN_DISABLE_GCC_WARNING(TOOLCHAIN_WARNING_ATTRIBUTES) \
     175              :         TOOLCHAIN_DISABLE_IAR_WARNING(TOOLCHAIN_WARNING_ATTRIBUTES)
     176            0 : #define ARCH_ISR_DIAG_ON \
     177              :         TOOLCHAIN_ENABLE_CLANG_WARNING(TOOLCHAIN_WARNING_EXTRA) \
     178              :         TOOLCHAIN_ENABLE_GCC_WARNING(TOOLCHAIN_WARNING_ATTRIBUTES) \
     179              :         TOOLCHAIN_ENABLE_IAR_WARNING(TOOLCHAIN_WARNING_ATTRIBUTES)
     180              : 
     181            0 : #define ARCH_ISR_DIRECT_DECLARE(name) \
     182              :         static inline int name##_body(void); \
     183              :         ARCH_ISR_DIAG_OFF \
     184              :         __attribute__ ((interrupt ("IRQ"))) void name(void) \
     185              :         { \
     186              :                 int check_reschedule; \
     187              :                 ISR_DIRECT_HEADER(); \
     188              :                 check_reschedule = name##_body(); \
     189              :                 ISR_DIRECT_FOOTER(check_reschedule); \
     190              :         } \
     191              :         ARCH_ISR_DIAG_ON \
     192              :         static inline int name##_body(void)
     193              : 
     194              : #if defined(CONFIG_DYNAMIC_DIRECT_INTERRUPTS)
     195              : 
     196              : extern void z_arm_irq_direct_dynamic_dispatch_reschedule(void);
     197              : extern void z_arm_irq_direct_dynamic_dispatch_no_reschedule(void);
     198              : 
     199              : /**
     200              :  * @brief Macro to register an ISR Dispatcher (with or without re-scheduling
     201              :  * request) for dynamic direct interrupts.
     202              :  *
     203              :  * This macro registers the ISR dispatcher function for dynamic direct
     204              :  * interrupts for a particular IRQ line, allowing the use of dynamic
     205              :  * direct ISRs in the kernel for that interrupt source.
     206              :  * The dispatcher function is invoked when the hardware
     207              :  * interrupt occurs and then triggers the (software) Interrupt Service Routine
     208              :  * (ISR) that is registered dynamically (i.e. at run-time) into the software
     209              :  * ISR table stored in SRAM. The ISR must be connected with
     210              :  * irq_connect_dynamic() and enabled via irq_enable() before the dynamic direct
     211              :  * interrupt can be serviced. This ISR dispatcher must be configured by the
     212              :  * user to trigger thread re-secheduling upon return, using the @param resch
     213              :  * parameter.
     214              :  *
     215              :  * These ISRs are designed for performance-critical interrupt handling and do
     216              :  * not go through all of the common interrupt handling code.
     217              :  *
     218              :  * With respect to their declaration, dynamic 'direct' interrupts are regular
     219              :  * Zephyr interrupts; their signature must match void isr(void* parameter), as,
     220              :  * unlike regular direct interrupts, they are not placed directly into the
     221              :  * ROM hardware vector table but instead they are installed in the software
     222              :  * ISR table.
     223              :  *
     224              :  * The major differences with regular Zephyr interrupts are the following:
     225              :  * - Similar to direct interrupts, the call into the OS to exit power
     226              :  *   management idle state is optional. Normal interrupts always do this
     227              :  *   before the ISR is run, but with dynamic direct ones when and if it runs
     228              :  *   is controlled by the placement of
     229              :  *   a ISR_DIRECT_PM() macro, or omitted entirely.
     230              :  * - Similar to direct interrupts, scheduling decisions are optional. Unlike
     231              :  *   direct interrupts, the decisions must be made at build time.
     232              :  *   They are controlled by @param resch to this macro.
     233              :  *
     234              :  * @warning
     235              :  * Just like with regular direct ISRs, any ISRs that serve IRQs configured with
     236              :  * the IRQ_ZERO_LATENCY flag must not use the ISR_DIRECT_PM() macro and must
     237              :  * return 0 (i.e. resch must be no_reschedule).
     238              :  *
     239              :  * @param irq_p IRQ line number.
     240              :  * @param priority_p Interrupt priority.
     241              :  * @param flags_p Architecture-specific IRQ configuration flags.
     242              :  * @param resch Set flag to 'reschedule' to request thread
     243              :  *              re-scheduling upon ISR function. Set flag
     244              :  *              'no_reschedule' to skip thread re-scheduling
     245              :  *              Must be 'no_reschedule' for zero-latency interrupts
     246              :  *
     247              :  * Note: the function is an ARM Cortex-M only API.
     248              :  *
     249              :  * @return Interrupt vector assigned to this interrupt.
     250              :  */
     251              : #define ARM_IRQ_DIRECT_DYNAMIC_CONNECT(irq_p, priority_p, flags_p, resch) \
     252              :         IRQ_DIRECT_CONNECT(irq_p, priority_p, \
     253              :                 _CONCAT(z_arm_irq_direct_dynamic_dispatch_, resch), flags_p)
     254              : 
     255              : #endif /* CONFIG_DYNAMIC_DIRECT_INTERRUPTS */
     256              : 
     257              : #if defined(CONFIG_ARM_SECURE_FIRMWARE)
     258              : /* Architecture-specific definition for the target security
     259              :  * state of an NVIC IRQ line.
     260              :  */
     261              : typedef enum {
     262              :         IRQ_TARGET_STATE_SECURE = 0,
     263              :         IRQ_TARGET_STATE_NON_SECURE
     264              : } irq_target_state_t;
     265              : 
     266              : #endif /* CONFIG_ARM_SECURE_FIRMWARE */
     267              : 
     268              : #endif /* _ASMLANGUAGE */
     269              : 
     270              : #ifdef __cplusplus
     271              : }
     272              : #endif
     273              : 
     274              : #endif /* ZEPHYR_INCLUDE_ARCH_ARM_IRQ_H_ */
        

Generated by: LCOV version 2.0-1