1 /* $NetBSD: intr.h,v 1.85 2021/07/16 19:02:22 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2000, 2001, 2002 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved. 34 * Copyright (c) 1996 Carnegie-Mellon University. 35 * All rights reserved. 36 * 37 * Author: Chris G. Demetriou 38 * 39 * Permission to use, copy, modify and distribute this software and 40 * its documentation is hereby granted, provided that both the copyright 41 * notice and this permission notice appear in all copies of the 42 * software, derivative works or modified versions, and any portions 43 * thereof, and that both notices appear in supporting documentation. 44 * 45 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 46 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 47 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 48 * 49 * Carnegie Mellon requests users of this software to return to 50 * 51 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU 52 * School of Computer Science 53 * Carnegie Mellon University 54 * Pittsburgh PA 15213-3890 55 * 56 * any improvements or extensions that they make and grant Carnegie the 57 * rights to redistribute these changes. 58 */ 59 60 #ifndef _ALPHA_INTR_H_ 61 #define _ALPHA_INTR_H_ 62 63 #include <sys/evcnt.h> 64 #include <machine/alpha_cpu.h> 65 66 /* 67 * The Alpha System Control Block. This is 8k long, and you get 68 * 16 bytes per vector (i.e. the vector numbers are spaced 16 69 * apart). 70 * 71 * This is sort of a "shadow" SCB -- rather than the CPU jumping 72 * to (SCBaddr + (16 * vector)), like it does on the VAX, we get 73 * a vector number in a1. We use the SCB to look up a routine/arg 74 * and jump to it. 75 * 76 * Since we use the SCB only for I/O interrupts, we make it shorter 77 * than normal, starting it at vector 0x800 (the start of the I/O 78 * interrupt vectors). 79 */ 80 #define SCB_IOVECBASE 0x0800 81 #define SCB_VECSIZE 0x0010 82 #define SCB_SIZE 0x2000 83 84 #define SCB_VECTOIDX(x) ((x) >> 4) 85 #define SCB_IDXTOVEC(x) ((x) << 4) 86 87 #define SCB_NIOVECS SCB_VECTOIDX(SCB_SIZE - SCB_IOVECBASE) 88 89 struct scbvec { 90 void (*scb_func)(void *, u_long); 91 void *scb_arg; 92 }; 93 94 /* 95 * Alpha interrupts come in at one of 3 levels: 96 * 97 * i/o level 1 98 * i/o level 2 99 * clock level 100 * 101 * However, since we do not have any way to know which hardware 102 * level a particular i/o interrupt comes in on, we have to 103 * whittle it down to 2. In addition, there are 2 software interrupt 104 * levels available to system software. 105 */ 106 107 #define IPL_NONE ALPHA_PSL_IPL_0 108 #define IPL_SOFTCLOCK ALPHA_PSL_IPL_SOFT_LO 109 #define IPL_SOFTBIO ALPHA_PSL_IPL_SOFT_LO 110 #ifdef __HAVE_FAST_SOFTINTS 111 #define IPL_SOFTNET ALPHA_PSL_IPL_SOFT_HI 112 #define IPL_SOFTSERIAL ALPHA_PSL_IPL_SOFT_HI 113 #else 114 #define IPL_SOFTNET ALPHA_PSL_IPL_SOFT_LO 115 #define IPL_SOFTSERIAL ALPHA_PSL_IPL_SOFT_LO 116 #endif /* __HAVE_FAST_SOFTINTS */ 117 #define IPL_VM ALPHA_PSL_IPL_IO_HI 118 #define IPL_SCHED ALPHA_PSL_IPL_CLOCK 119 #define IPL_HIGH ALPHA_PSL_IPL_HIGH 120 121 #define SOFTINT_CLOCK_MASK __BIT(SOFTINT_CLOCK) 122 #define SOFTINT_BIO_MASK __BIT(SOFTINT_BIO) 123 #define SOFTINT_NET_MASK __BIT(SOFTINT_NET) 124 #define SOFTINT_SERIAL_MASK __BIT(SOFTINT_SERIAL) 125 126 #define ALPHA_IPL1_SOFTINTS (SOFTINT_CLOCK_MASK | SOFTINT_BIO_MASK) 127 #define ALPHA_IPL2_SOFTINTS (SOFTINT_NET_MASK | SOFTINT_SERIAL_MASK) 128 129 #define ALPHA_ALL_SOFTINTS (ALPHA_IPL1_SOFTINTS | ALPHA_IPL2_SOFTINTS) 130 131 typedef int ipl_t; 132 typedef struct { 133 uint8_t _psl; 134 } ipl_cookie_t; 135 136 static inline ipl_cookie_t 137 makeiplcookie(ipl_t ipl) 138 { 139 return (ipl_cookie_t){._psl = (uint8_t)ipl}; 140 } 141 142 #define IST_UNUSABLE -1 /* interrupt cannot be used */ 143 #define IST_NONE 0 /* none (dummy) */ 144 #define IST_PULSE 1 /* pulsed */ 145 #define IST_EDGE 2 /* edge-triggered */ 146 #define IST_LEVEL 3 /* level-triggered */ 147 148 #ifdef _KERNEL 149 150 /* IPL-lowering/restoring macros */ 151 void spllower(int); 152 153 #define splx(s) spllower(s) 154 #define spl0() spllower(ALPHA_PSL_IPL_0) 155 156 /* IPL-raising functions/macros */ 157 static __inline int 158 _splraise(int s) 159 { 160 int cur = (int)alpha_pal_rdps(); 161 return (s > cur ? (int)alpha_pal_swpipl(s) : cur); 162 } 163 164 #define splraiseipl(icookie) _splraise((icookie)._psl) 165 166 #include <sys/spl.h> 167 168 /* Fast soft interrupt dispatch. */ 169 void alpha_softint_dispatch(int); 170 void alpha_softint_switchto(struct lwp *, int, struct lwp *); 171 172 /* 173 * Interprocessor interrupts. In order how we want them processed. 174 */ 175 #define ALPHA_IPI_HALT (1UL << 0) 176 #define ALPHA_IPI_PRIMARY_CC (1UL << 1) 177 #define ALPHA_IPI_SHOOTDOWN (1UL << 2) 178 #define ALPHA_IPI_AST (1UL << 3) 179 #define ALPHA_IPI_PAUSE (1UL << 4) 180 #define ALPHA_IPI_XCALL (1UL << 5) 181 #define ALPHA_IPI_GENERIC (1UL << 6) 182 183 #define ALPHA_NIPIS 7 /* must not exceed 64 */ 184 185 struct cpu_info; 186 struct trapframe; 187 188 void alpha_ipi_init(struct cpu_info *); 189 void alpha_ipi_process(struct cpu_info *, struct trapframe *); 190 void alpha_send_ipi(unsigned long, unsigned long); 191 void alpha_broadcast_ipi(unsigned long); 192 void alpha_multicast_ipi(unsigned long, unsigned long); 193 194 /* 195 * Alpha shared-interrupt-line common code. 196 */ 197 198 #define ALPHA_INTR_MPSAFE 0x01 199 200 struct alpha_shared_intrhand { 201 TAILQ_ENTRY(alpha_shared_intrhand) 202 ih_q; 203 struct alpha_shared_intr *ih_intrhead; 204 int (*ih_fn)(void *); 205 void *ih_arg; 206 int (*ih_real_fn)(void *); 207 void *ih_real_arg; 208 int ih_level; 209 int ih_type; 210 unsigned int ih_num; 211 }; 212 213 struct alpha_shared_intr { 214 TAILQ_HEAD(,alpha_shared_intrhand) 215 intr_q; 216 struct evcnt intr_evcnt; 217 char *intr_string; 218 void *intr_private; 219 struct cpu_info *intr_cpu; 220 int intr_sharetype; 221 int intr_dfltsharetype; 222 int intr_nstrays; 223 int intr_maxstrays; 224 }; 225 226 #define ALPHA_SHARED_INTR_DISABLE(asi, num) \ 227 ((asi)[num].intr_maxstrays != 0 && \ 228 (asi)[num].intr_nstrays == (asi)[num].intr_maxstrays) 229 230 struct alpha_shared_intr *alpha_shared_intr_alloc(unsigned int); 231 int alpha_shared_intr_dispatch(struct alpha_shared_intr *, 232 unsigned int); 233 struct alpha_shared_intrhand * 234 alpha_shared_intr_alloc_intrhand(struct alpha_shared_intr *, 235 unsigned int, int, int, int, int (*)(void *), void *, 236 const char *); 237 void alpha_shared_intr_free_intrhand(struct alpha_shared_intrhand *); 238 bool alpha_shared_intr_link(struct alpha_shared_intr *, 239 struct alpha_shared_intrhand *, const char *); 240 void alpha_shared_intr_unlink(struct alpha_shared_intr *, 241 struct alpha_shared_intrhand *, const char *); 242 int alpha_shared_intr_get_sharetype(struct alpha_shared_intr *, 243 unsigned int); 244 int alpha_shared_intr_isactive(struct alpha_shared_intr *, 245 unsigned int); 246 int alpha_shared_intr_firstactive(struct alpha_shared_intr *, 247 unsigned int); 248 void alpha_shared_intr_set_dfltsharetype(struct alpha_shared_intr *, 249 unsigned int, int); 250 void alpha_shared_intr_set_maxstrays(struct alpha_shared_intr *, 251 unsigned int, int); 252 void alpha_shared_intr_reset_strays(struct alpha_shared_intr *, 253 unsigned int); 254 void alpha_shared_intr_stray(struct alpha_shared_intr *, unsigned int, 255 const char *); 256 void alpha_shared_intr_set_private(struct alpha_shared_intr *, 257 unsigned int, void *); 258 void *alpha_shared_intr_get_private(struct alpha_shared_intr *, 259 unsigned int); 260 void alpha_shared_intr_set_cpu(struct alpha_shared_intr *, 261 unsigned int, struct cpu_info *ci); 262 struct cpu_info * 263 alpha_shared_intr_get_cpu(struct alpha_shared_intr *, 264 unsigned int); 265 void alpha_shared_intr_set_string(struct alpha_shared_intr *, 266 unsigned int, char *); 267 const char *alpha_shared_intr_string(struct alpha_shared_intr *, 268 unsigned int); 269 struct evcnt *alpha_shared_intr_evcnt(struct alpha_shared_intr *, 270 unsigned int); 271 272 extern struct scbvec scb_iovectab[]; 273 extern void (*alpha_intr_redistribute)(void); 274 275 void scb_init(void); 276 void scb_set(u_long, void (*)(void *, u_long), void *); 277 u_long scb_alloc(void (*)(void *, u_long), void *); 278 void scb_free(u_long); 279 280 #define SCB_ALLOC_FAILED ((u_long) -1) 281 282 #endif /* _KERNEL */ 283 #endif /* ! _ALPHA_INTR_H_ */ 284