1 /* $OpenBSD: intr.h,v 1.22 2023/09/12 08:29:28 jmatthew Exp $ */ 2 3 /* 4 * Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com) 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29 #ifndef _MACHINE_INTR_H_ 30 #define _MACHINE_INTR_H_ 31 32 /* 33 * The interrupt level ipl is a logical level; per-platform interrupt 34 * code will turn it into the appropriate hardware interrupt masks 35 * values. 36 * 37 * Interrupt sources on the CPU are kept enabled regardless of the 38 * current ipl value; individual hardware sources interrupting while 39 * logically masked are masked on the fly, remembered as pending, and 40 * unmasked at the first splx() opportunity. 41 */ 42 #ifdef _KERNEL 43 44 /* Interrupt priority `levels'; not mutually exclusive. */ 45 #define IPL_NONE 0 /* nothing */ 46 #define IPL_SOFT 1 /* soft interrupts */ 47 #define IPL_SOFTCLOCK 2 /* soft clock interrupts */ 48 #define IPL_SOFTNET 3 /* soft network interrupts */ 49 #define IPL_SOFTTTY 4 /* soft terminal interrupts */ 50 #define IPL_BIO 5 /* block I/O */ 51 #define IPL_NET 6 /* network */ 52 #define IPL_TTY 7 /* terminal */ 53 #define IPL_VM 8 /* memory allocation */ 54 #define IPL_AUDIO 9 /* audio */ 55 #define IPL_CLOCK 10 /* clock */ 56 #define IPL_SCHED IPL_CLOCK 57 #define IPL_STATCLOCK IPL_CLOCK 58 #define IPL_HIGH 11 /* everything */ 59 #define IPL_IPI 12 /* interprocessor interrupt */ 60 #define NIPL 13 /* number of levels */ 61 62 #define IPL_MPFLOOR IPL_TTY 63 /* Interrupt priority 'flags'. */ 64 #define IPL_IRQMASK 0xf /* priority only */ 65 #define IPL_FLAGMASK 0xf00 /* flags only*/ 66 #define IPL_MPSAFE 0x100 /* 'mpsafe' interrupt, no kernel lock */ 67 #define IPL_WAKEUP 0x200 /* 'wakeup' interrupt */ 68 69 /* Interrupt sharing types. */ 70 #define IST_NONE 0 /* none */ 71 #define IST_PULSE 1 /* pulsed */ 72 #define IST_EDGE 2 /* edge-triggered */ 73 #define IST_LEVEL 3 /* level-triggered */ 74 75 #define IST_LEVEL_LOW IST_LEVEL 76 #define IST_LEVEL_HIGH 4 77 #define IST_EDGE_FALLING IST_EDGE 78 #define IST_EDGE_RISING 5 79 #define IST_EDGE_BOTH 6 80 81 #ifndef _LOCORE 82 #include <sys/device.h> 83 #include <sys/queue.h> 84 85 int splraise(int); 86 int spllower(int); 87 void splx(int); 88 89 void arm_do_pending_intr(int); 90 void arm_set_intr_handler(int (*)(int), int (*)(int), void (*)(int), 91 void (*)(int), void (*)(void *), void (*)(void *), 92 void (*)(void), void (*)(void)); 93 94 struct machine_intr_handle { 95 struct interrupt_controller *ih_ic; 96 void *ih_ih; 97 }; 98 99 struct arm_intr_func { 100 int (*raise)(int); 101 int (*lower)(int); 102 void (*x)(int); 103 void (*setipl)(int); 104 void (*enable_wakeup)(void); 105 void (*disable_wakeup)(void); 106 }; 107 108 extern struct arm_intr_func arm_intr_func; 109 110 #define splraise(cpl) (arm_intr_func.raise(cpl)) 111 #define _splraise(cpl) (arm_intr_func.raise(cpl)) 112 #define spllower(cpl) (arm_intr_func.lower(cpl)) 113 #define splx(cpl) (arm_intr_func.x(cpl)) 114 115 #define splsoft() splraise(IPL_SOFT) 116 #define splsoftclock() splraise(IPL_SOFTCLOCK) 117 #define splsoftnet() splraise(IPL_SOFTNET) 118 #define splsofttty() splraise(IPL_SOFTTTY) 119 #define splbio() splraise(IPL_BIO) 120 #define splnet() splraise(IPL_NET) 121 #define spltty() splraise(IPL_TTY) 122 #define splvm() splraise(IPL_VM) 123 #define splaudio() splraise(IPL_AUDIO) 124 #define splclock() splraise(IPL_CLOCK) 125 #define splsched() splraise(IPL_SCHED) 126 #define splstatclock() splraise(IPL_STATCLOCK) 127 #define splhigh() splraise(IPL_HIGH) 128 129 #define spl0() spllower(IPL_NONE) 130 131 void intr_barrier(void *); 132 void intr_set_wakeup(void *); 133 void intr_enable_wakeup(void); 134 void intr_disable_wakeup(void); 135 136 void arm_init_smask(void); /* XXX */ 137 extern uint32_t arm_smask[NIPL]; 138 139 #include <machine/softintr.h> 140 141 /* XXX - this is probably the wrong location for this */ 142 void arm_clock_register(void (*)(void), void (*)(u_int), void (*)(int), 143 void (*)(void)); 144 145 struct cpu_info; 146 147 struct interrupt_controller { 148 int ic_node; 149 void *ic_cookie; 150 void *(*ic_establish)(void *, int *, int, struct cpu_info *, 151 int (*)(void *), void *, char *); 152 void *(*ic_establish_msi)(void *, uint64_t *, uint64_t *, int, 153 struct cpu_info *, int (*)(void *), void *, char *); 154 void (*ic_disestablish)(void *); 155 void (*ic_enable)(void *); 156 void (*ic_disable)(void *); 157 void (*ic_route)(void *, int, struct cpu_info *); 158 void (*ic_cpu_enable)(void); 159 void (*ic_barrier)(void *); 160 void (*ic_set_wakeup)(void *); 161 162 LIST_ENTRY(interrupt_controller) ic_list; 163 uint32_t ic_phandle; 164 uint32_t ic_cells; 165 uint32_t ic_gic_its_id; 166 }; 167 168 void arm_intr_init_fdt(void); 169 void arm_intr_register_fdt(struct interrupt_controller *); 170 void *arm_intr_establish_fdt(int, int, int (*)(void *), 171 void *, char *); 172 void *arm_intr_establish_fdt_cpu(int, int, struct cpu_info *, 173 int (*)(void *), void *, char *); 174 void *arm_intr_establish_fdt_idx(int, int, int, int (*)(void *), 175 void *, char *); 176 void *arm_intr_establish_fdt_idx_cpu(int, int, int, struct cpu_info *, 177 int (*)(void *), void *, char *); 178 void *arm_intr_establish_fdt_imap(int, int *, int, int, int (*)(void *), 179 void *, char *); 180 void *arm_intr_establish_fdt_imap_cpu(int, int *, int, int, 181 struct cpu_info *, int (*)(void *), void *, char *); 182 void *arm_intr_establish_fdt_msi(int, uint64_t *, uint64_t *, int, 183 int (*)(void *), void *, char *); 184 void *arm_intr_establish_fdt_msi_cpu(int, uint64_t *, uint64_t *, int, 185 struct cpu_info *, int (*)(void *), void *, char *); 186 void arm_intr_disestablish_fdt(void *); 187 void arm_intr_enable(void *); 188 void arm_intr_disable(void *); 189 void arm_intr_route(void *, int, struct cpu_info *); 190 void arm_intr_cpu_enable(void); 191 void *arm_intr_parent_establish_fdt(void *, int *, int, 192 struct cpu_info *ci, int (*)(void *), void *, char *); 193 void arm_intr_parent_disestablish_fdt(void *); 194 195 void arm_send_ipi(struct cpu_info *, int); 196 extern void (*intr_send_ipi_func)(struct cpu_info *, int); 197 198 #define ARM_IPI_NOP 0 199 #define ARM_IPI_DDB 1 200 #define ARM_IPI_HALT 2 201 202 #ifdef DIAGNOSTIC 203 /* 204 * Although this function is implemented in MI code, it must be in this MD 205 * header because we don't want this header to include MI includes. 206 */ 207 void splassert_fail(int, int, const char *); 208 extern int splassert_ctl; 209 void arm_splassert_check(int, const char *); 210 #define splassert(__wantipl) do { \ 211 if (splassert_ctl > 0) { \ 212 arm_splassert_check(__wantipl, __func__); \ 213 } \ 214 } while (0) 215 #define splsoftassert(wantipl) splassert(wantipl) 216 #else 217 #define splassert(wantipl) do { /* nothing */ } while (0) 218 #define splsoftassert(wantipl) do { /* nothing */ } while (0) 219 #endif 220 221 #endif /* ! _LOCORE */ 222 223 #endif /* _KERNEL */ 224 225 #endif /* _MACHINE_INTR_H_ */ 226 227