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 * Call this function to enable the specified interrupts. 18 * 19 * mask - Bit mask of interrupts to be enabled. 20 */ z_xt_ints_on(unsigned int mask)21static inline void z_xt_ints_on(unsigned int mask) 22 { 23 int val; 24 25 __asm__ volatile("rsr.intenable %0" : "=r"(val)); 26 val |= mask; 27 __asm__ volatile("wsr.intenable %0; rsync" : : "r"(val)); 28 } 29 30 31 /* 32 * Call this function to disable the specified interrupts. 33 * 34 * mask - Bit mask of interrupts to be disabled. 35 */ z_xt_ints_off(unsigned int mask)36static inline void z_xt_ints_off(unsigned int mask) 37 { 38 int val; 39 40 __asm__ volatile("rsr.intenable %0" : "=r"(val)); 41 val &= ~mask; 42 __asm__ volatile("wsr.intenable %0; rsync" : : "r"(val)); 43 } 44 45 /* 46 * Call this function to set the specified (s/w) interrupt. 47 */ z_xt_set_intset(unsigned int arg)48static inline void z_xt_set_intset(unsigned int arg) 49 { 50 #if XCHAL_HAVE_INTERRUPTS 51 __asm__ volatile("wsr.intset %0; rsync" : : "r"(arg)); 52 #else 53 ARG_UNUSED(arg); 54 #endif 55 } 56 57 #ifdef CONFIG_MULTI_LEVEL_INTERRUPTS 58 59 /* for _soc_irq_*() */ 60 #include <soc.h> 61 62 #ifdef CONFIG_2ND_LEVEL_INTERRUPTS 63 #ifdef CONFIG_3RD_LEVEL_INTERRUPTS 64 #define CONFIG_NUM_IRQS (XCHAL_NUM_INTERRUPTS +\ 65 (CONFIG_NUM_2ND_LEVEL_AGGREGATORS +\ 66 CONFIG_NUM_3RD_LEVEL_AGGREGATORS) *\ 67 CONFIG_MAX_IRQ_PER_AGGREGATOR) 68 #else 69 #define CONFIG_NUM_IRQS (XCHAL_NUM_INTERRUPTS +\ 70 CONFIG_NUM_2ND_LEVEL_AGGREGATORS *\ 71 CONFIG_MAX_IRQ_PER_AGGREGATOR) 72 #endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ 73 #else 74 #define CONFIG_NUM_IRQS XCHAL_NUM_INTERRUPTS 75 #endif /* CONFIG_2ND_LEVEL_INTERRUPTS */ 76 77 void z_soc_irq_init(void); 78 void z_soc_irq_enable(unsigned int irq); 79 void z_soc_irq_disable(unsigned int irq); 80 int z_soc_irq_is_enabled(unsigned int irq); 81 82 #define arch_irq_enable(irq) z_soc_irq_enable(irq) 83 #define arch_irq_disable(irq) z_soc_irq_disable(irq) 84 85 #define arch_irq_is_enabled(irq) z_soc_irq_is_enabled(irq) 86 87 #ifdef CONFIG_DYNAMIC_INTERRUPTS 88 extern int z_soc_irq_connect_dynamic(unsigned int irq, unsigned int priority, 89 void (*routine)(const void *parameter), 90 const void *parameter, uint32_t flags); 91 #endif 92 93 #else 94 95 #define CONFIG_NUM_IRQS XCHAL_NUM_INTERRUPTS 96 97 #define arch_irq_enable(irq) z_xtensa_irq_enable(irq) 98 #define arch_irq_disable(irq) z_xtensa_irq_disable(irq) 99 100 #define arch_irq_is_enabled(irq) z_xtensa_irq_is_enabled(irq) 101 102 #endif 103 z_xtensa_irq_enable(uint32_t irq)104static ALWAYS_INLINE void z_xtensa_irq_enable(uint32_t irq) 105 { 106 z_xt_ints_on(1 << irq); 107 } 108 z_xtensa_irq_disable(uint32_t irq)109static ALWAYS_INLINE void z_xtensa_irq_disable(uint32_t irq) 110 { 111 z_xt_ints_off(1 << irq); 112 } 113 arch_irq_lock(void)114static ALWAYS_INLINE unsigned int arch_irq_lock(void) 115 { 116 unsigned int key; 117 118 __asm__ volatile("rsil %0, %1" 119 : "=r"(key) : "i"(XCHAL_EXCM_LEVEL) : "memory"); 120 return key; 121 } 122 arch_irq_unlock(unsigned int key)123static ALWAYS_INLINE void arch_irq_unlock(unsigned int key) 124 { 125 __asm__ volatile("wsr.ps %0; rsync" 126 :: "r"(key) : "memory"); 127 } 128 arch_irq_unlocked(unsigned int key)129static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key) 130 { 131 return (key & 0xf) == 0; /* INTLEVEL field */ 132 } 133 134 extern int z_xtensa_irq_is_enabled(unsigned int irq); 135 136 #include <zephyr/irq.h> 137 138 #endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_IRQ_H_ */ 139