Line data Source code
1 0 : /* 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 0 : #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 : */ 25 : static 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 : */ 40 : static 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 : */ 53 : static 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 0 : #define CONFIG_NUM_IRQS XCHAL_NUM_INTERRUPTS 105 : 106 0 : #define arch_irq_enable(irq) xtensa_irq_enable(irq) 107 0 : #define arch_irq_disable(irq) xtensa_irq_disable(irq) 108 : 109 0 : #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 : */ 118 1 : static 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 : */ 128 1 : static 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. */ 134 1 : static 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. */ 144 1 : static 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. */ 151 1 : static 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 1 : int xtensa_irq_is_enabled(unsigned int irq); 164 : 165 : #include <zephyr/irq.h> 166 : 167 : #endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_IRQ_H_ */