1 /* 2 * Copyright (c) 2016 Cadence Design Systems, Inc. 3 * SPDX-License-Identifier: Apache-2.0 4 */ 5 6 #ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_IRQ_H_ 7 #define ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_IRQ_H_ 8 9 #include <stdint.h> 10 11 #include <zephyr/toolchain.h> 12 #include <xtensa/config/core-isa.h> 13 14 #define CONFIG_GEN_IRQ_START_VECTOR 0 15 16 /** 17 * @cond INTERNAL_HIDDEN 18 */ 19 20 /* 21 * Call this function to enable the specified interrupts. 22 * 23 * mask - Bit mask of interrupts to be enabled. 24 */ z_xt_ints_on(unsigned int mask)25static inline void z_xt_ints_on(unsigned int mask) 26 { 27 int val; 28 29 __asm__ volatile("rsr.intenable %0" : "=r"(val)); 30 val |= mask; 31 __asm__ volatile("wsr.intenable %0; rsync" : : "r"(val)); 32 } 33 34 35 /* 36 * Call this function to disable the specified interrupts. 37 * 38 * mask - Bit mask of interrupts to be disabled. 39 */ z_xt_ints_off(unsigned int mask)40static inline void z_xt_ints_off(unsigned int mask) 41 { 42 int val; 43 44 __asm__ volatile("rsr.intenable %0" : "=r"(val)); 45 val &= ~mask; 46 __asm__ volatile("wsr.intenable %0; rsync" : : "r"(val)); 47 } 48 49 50 /* 51 * Call this function to set the specified (s/w) interrupt. 52 */ z_xt_set_intset(unsigned int arg)53static inline void z_xt_set_intset(unsigned int arg) 54 { 55 #if XCHAL_HAVE_INTERRUPTS 56 __asm__ volatile("wsr.intset %0; rsync" : : "r"(arg)); 57 #else 58 ARG_UNUSED(arg); 59 #endif 60 } 61 62 /** 63 * INTERNAL_HIDDEN @endcond 64 */ 65 66 #ifdef CONFIG_MULTI_LEVEL_INTERRUPTS 67 68 /* for _soc_irq_*() */ 69 #include <soc.h> 70 71 #ifdef CONFIG_2ND_LEVEL_INTERRUPTS 72 #ifdef CONFIG_3RD_LEVEL_INTERRUPTS 73 #define CONFIG_NUM_IRQS (XCHAL_NUM_INTERRUPTS +\ 74 (CONFIG_NUM_2ND_LEVEL_AGGREGATORS +\ 75 CONFIG_NUM_3RD_LEVEL_AGGREGATORS) *\ 76 CONFIG_MAX_IRQ_PER_AGGREGATOR) 77 #else 78 #define CONFIG_NUM_IRQS (XCHAL_NUM_INTERRUPTS +\ 79 CONFIG_NUM_2ND_LEVEL_AGGREGATORS *\ 80 CONFIG_MAX_IRQ_PER_AGGREGATOR) 81 #endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ 82 #else 83 #define CONFIG_NUM_IRQS XCHAL_NUM_INTERRUPTS 84 #endif /* CONFIG_2ND_LEVEL_INTERRUPTS */ 85 86 void z_soc_irq_init(void); 87 void z_soc_irq_enable(unsigned int irq); 88 void z_soc_irq_disable(unsigned int irq); 89 int z_soc_irq_is_enabled(unsigned int irq); 90 91 #define arch_irq_enable(irq) z_soc_irq_enable(irq) 92 #define arch_irq_disable(irq) z_soc_irq_disable(irq) 93 94 #define arch_irq_is_enabled(irq) z_soc_irq_is_enabled(irq) 95 96 #ifdef CONFIG_DYNAMIC_INTERRUPTS 97 extern int z_soc_irq_connect_dynamic(unsigned int irq, unsigned int priority, 98 void (*routine)(const void *parameter), 99 const void *parameter, uint32_t flags); 100 #endif 101 102 #else 103 104 #define CONFIG_NUM_IRQS XCHAL_NUM_INTERRUPTS 105 106 #define arch_irq_enable(irq) xtensa_irq_enable(irq) 107 #define arch_irq_disable(irq) xtensa_irq_disable(irq) 108 109 #define arch_irq_is_enabled(irq) xtensa_irq_is_enabled(irq) 110 111 #endif 112 113 /** 114 * @brief Enable interrupt on Xtensa core. 115 * 116 * @param irq Interrupt to be enabled. 117 */ xtensa_irq_enable(uint32_t irq)118static ALWAYS_INLINE void xtensa_irq_enable(uint32_t irq) 119 { 120 z_xt_ints_on(1 << irq); 121 } 122 123 /** 124 * @brief Disable interrupt on Xtensa core. 125 * 126 * @param irq Interrupt to be disabled. 127 */ xtensa_irq_disable(uint32_t irq)128static ALWAYS_INLINE void xtensa_irq_disable(uint32_t irq) 129 { 130 z_xt_ints_off(1 << irq); 131 } 132 133 /** Implementation of @ref arch_irq_lock. */ arch_irq_lock(void)134static ALWAYS_INLINE unsigned int arch_irq_lock(void) 135 { 136 unsigned int key; 137 138 __asm__ volatile("rsil %0, %1" 139 : "=r"(key) : "i"(XCHAL_EXCM_LEVEL) : "memory"); 140 return key; 141 } 142 143 /** Implementation of @ref arch_irq_unlock. */ arch_irq_unlock(unsigned int key)144static ALWAYS_INLINE void arch_irq_unlock(unsigned int key) 145 { 146 __asm__ volatile("wsr.ps %0; rsync" 147 :: "r"(key) : "memory"); 148 } 149 150 /** Implementation of @ref arch_irq_unlocked. */ arch_irq_unlocked(unsigned int key)151static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key) 152 { 153 return (key & 0xf) == 0; /* INTLEVEL field */ 154 } 155 156 /** 157 * @brief Query if an interrupt is enabled on Xtensa core. 158 * 159 * @param irq Interrupt to be queried. 160 * 161 * @return True if interrupt is enabled, false otherwise. 162 */ 163 int xtensa_irq_is_enabled(unsigned int irq); 164 165 #include <zephyr/irq.h> 166 167 #endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_IRQ_H_ */ 168