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