1 1.9 andvar /* $NetBSD: intr.h,v 1.9 2024/02/08 20:11:56 andvar Exp $ */ 2 1.1 thorpej 3 1.1 thorpej /*- 4 1.1 thorpej * Copyright (c) 2023, 2024 The NetBSD Foundation, Inc. 5 1.1 thorpej * All rights reserved. 6 1.1 thorpej * 7 1.1 thorpej * This code is derived from software contributed to The NetBSD Foundation 8 1.1 thorpej * by Jason R. Thorpe. 9 1.1 thorpej * 10 1.1 thorpej * Redistribution and use in source and binary forms, with or without 11 1.1 thorpej * modification, are permitted provided that the following conditions 12 1.1 thorpej * are met: 13 1.1 thorpej * 1. Redistributions of source code must retain the above copyright 14 1.1 thorpej * notice, this list of conditions and the following disclaimer. 15 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 17 1.1 thorpej * documentation and/or other materials provided with the distribution. 18 1.1 thorpej * 19 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 thorpej * POSSIBILITY OF SUCH DAMAGE. 30 1.1 thorpej */ 31 1.1 thorpej 32 1.1 thorpej #ifndef _M68k_INTR_H_ 33 1.1 thorpej #define _M68k_INTR_H_ 34 1.1 thorpej 35 1.1 thorpej #include <machine/psl.h> 36 1.1 thorpej 37 1.6 thorpej #if (defined(_KERNEL) && !defined(_LOCORE)) || defined(_KMEMUSER) 38 1.6 thorpej typedef struct { 39 1.6 thorpej uint16_t _psl; /* physical manifestation of logical IPL_* */ 40 1.6 thorpej } ipl_cookie_t; 41 1.6 thorpej #endif 42 1.6 thorpej 43 1.6 thorpej #ifdef _KERNEL 44 1.6 thorpej 45 1.1 thorpej /* 46 1.1 thorpej * Logical interrupt priority levels -- these are distinct from 47 1.1 thorpej * the hardware interrupt priority levels of the m68k. 48 1.1 thorpej */ 49 1.1 thorpej #define IPL_NONE 0 50 1.1 thorpej #define IPL_SOFTCLOCK 1 /* clock software interrupts */ 51 1.1 thorpej #define IPL_SOFTBIO 2 /* block device software interrupts */ 52 1.1 thorpej #define IPL_SOFTNET 3 /* network software interrupts */ 53 1.1 thorpej #define IPL_SOFTSERIAL 4 /* serial device software interrupts */ 54 1.1 thorpej #define IPL_VM 5 /* all interrupts that can allocate memory */ 55 1.1 thorpej #define IPL_SCHED 6 /* scheduler / hard clock interrupts */ 56 1.1 thorpej #define IPL_HIGH 7 /* blocks all interrupts */ 57 1.1 thorpej #define NIPL 8 58 1.1 thorpej 59 1.2 thorpej /* 60 1.2 thorpej * Abstract ISR priorities. These allow sorting of latency-sensitive 61 1.2 thorpej * devices earlier on the shared auto-vectored interrupt lists. 62 1.2 thorpej */ 63 1.2 thorpej #define ISRPRI_BIO 0 /* a block I/O device */ 64 1.2 thorpej #define ISRPRI_MISC 0 /* misc. devices */ 65 1.2 thorpej #define ISRPRI_NET 1 /* a network interface */ 66 1.2 thorpej #define ISRPRI_TTY 2 /* a serial port */ 67 1.2 thorpej #define ISRPRI_DISPLAY 2 /* display devices / framebuffers */ 68 1.2 thorpej #define ISRPRI_TTYNOBUF 3 /* a particularly bad serial port */ 69 1.2 thorpej #define ISRPRI_AUDIO 4 /* audio devices */ 70 1.2 thorpej 71 1.6 thorpej #ifndef _LOCORE 72 1.1 thorpej 73 1.8 thorpej extern volatile unsigned int intr_depth;/* interrupt depth */ 74 1.1 thorpej extern const uint16_t ipl2psl_table[NIPL]; 75 1.1 thorpej 76 1.1 thorpej typedef int ipl_t; /* logical IPL_* value */ 77 1.1 thorpej 78 1.1 thorpej static inline bool 79 1.1 thorpej cpu_intr_p(void) 80 1.1 thorpej { 81 1.7 thorpej return intr_depth != 0; 82 1.1 thorpej } 83 1.1 thorpej 84 1.1 thorpej static inline ipl_cookie_t 85 1.1 thorpej makeiplcookie(ipl_t ipl) 86 1.1 thorpej { 87 1.1 thorpej return (ipl_cookie_t){._psl = ipl2psl_table[ipl]}; 88 1.1 thorpej } 89 1.1 thorpej 90 1.1 thorpej static inline int 91 1.1 thorpej splraiseipl(ipl_cookie_t icookie) 92 1.1 thorpej { 93 1.1 thorpej return _splraise(icookie._psl); 94 1.1 thorpej } 95 1.1 thorpej 96 1.1 thorpej /* 97 1.1 thorpej * These are essentially constant equivalents of what's in 98 1.1 thorpej * ipl2psl_table[] to avoid the memory reference. 99 1.1 thorpej */ 100 1.1 thorpej #define splsoftclock() _splraise(PSL_S | MACHINE_PSL_IPL_SOFTCLOCK) 101 1.1 thorpej #define splsoftbio() _splraise(PSL_S | MACHINE_PSL_IPL_SOFTBIO) 102 1.1 thorpej #define splsoftnet() _splraise(PSL_S | MACHINE_PSL_IPL_SOFTNET) 103 1.1 thorpej #define splsoftserial() _splraise(PSL_S | MACHINE_PSL_IPL_SOFTSERIAL) 104 1.1 thorpej #define splvm() _splraise(PSL_S | MACHINE_PSL_IPL_VM) 105 1.1 thorpej #define splsched() _splraise(PSL_S | MACHINE_PSL_IPL_SCHED) 106 1.1 thorpej #define splhigh() spl7() 107 1.1 thorpej 108 1.1 thorpej /* 109 1.1 thorpej * XXX TODO: Support for hardware-assisted soft interrupts (sun68k) 110 1.1 thorpej * XXX and fast-soft-interrupts (others). 111 1.1 thorpej */ 112 1.1 thorpej #define spl0() _spl0() 113 1.1 thorpej #define splx(s) _splx(s) 114 1.1 thorpej 115 1.1 thorpej #ifdef _M68K_INTR_PRIVATE 116 1.1 thorpej #include <sys/queue.h> 117 1.1 thorpej 118 1.1 thorpej struct m68k_intrhand { 119 1.1 thorpej LIST_ENTRY(m68k_intrhand) ih_link; 120 1.1 thorpej int (*ih_func)(void *); 121 1.1 thorpej void *ih_arg; 122 1.1 thorpej struct evcnt *ih_evcnt; 123 1.1 thorpej int ih_ipl; /* m68k IPL, not IPL_* */ 124 1.1 thorpej int ih_vec; 125 1.2 thorpej int ih_isrpri; 126 1.1 thorpej }; 127 1.1 thorpej LIST_HEAD(m68k_intrhand_list, m68k_intrhand); 128 1.1 thorpej 129 1.1 thorpej struct m68k_ih_allocfuncs { 130 1.1 thorpej struct m68k_intrhand * (*alloc)(int km_flag); 131 1.1 thorpej void (*free)(struct m68k_intrhand *); 132 1.1 thorpej }; 133 1.1 thorpej #else 134 1.1 thorpej struct m68k_ih_allocfuncs; 135 1.1 thorpej #endif /* _M68K_INTR_PRIVATE */ 136 1.1 thorpej 137 1.3 thorpej #include <sys/evcnt.h> 138 1.3 thorpej 139 1.4 thorpej #ifdef __HAVE_LEGACY_INTRCNT 140 1.4 thorpej #define m68k_count_intr(x) \ 141 1.4 thorpej do { \ 142 1.4 thorpej extern u_int intrcnt[]; \ 143 1.4 thorpej intrcnt[(x)]++; \ 144 1.4 thorpej curcpu()->ci_data.cpu_nintr++; \ 145 1.4 thorpej } while (/*CONSTCOND*/0) 146 1.4 thorpej #else 147 1.3 thorpej /* 148 1.3 thorpej * This is exposed here so that platform-specific interrupt handlers 149 1.3 thorpej * can access it. 150 1.3 thorpej */ 151 1.3 thorpej extern struct evcnt m68k_intr_evcnt[]; 152 1.4 thorpej 153 1.4 thorpej #define m68k_count_intr(x) \ 154 1.4 thorpej do { \ 155 1.4 thorpej /* 32-bit counter should be sufficient for m68k. */ \ 156 1.4 thorpej m68k_intr_evcnt[(x)].ev_count32++; \ 157 1.4 thorpej curcpu()->ci_data.cpu_nintr++; \ 158 1.4 thorpej } while (/*CONSTCOND*/0) 159 1.4 thorpej #endif /* __HAVE_LEGACY_INTRCNT */ 160 1.1 thorpej 161 1.1 thorpej /* 162 1.1 thorpej * Common m68k interrupt dispatch: 163 1.1 thorpej * 164 1.1 thorpej * ==> m68k_intr_init(const struct m68k_ih_allocfuncs *allocfuncs) 165 1.1 thorpej * 166 1.1 thorpej * Initialize the interrupt system. If the platform needs to store 167 1.1 thorpej * additional information in the interrupt handle, then it can provide 168 1.1 thorpej * its own alloc/free routines. Otherwise, pass NULL to get the default. 169 1.1 thorpej * If a platform doesn't want the special allocator behavior, calling 170 1.1 thorpej * this function is optional; it will be done for you on the first call 171 1.1 thorpej * to m68k_intr_establish(). 172 1.1 thorpej * 173 1.1 thorpej * ==> m68k_intr_establish(int (*func)(void *), void *arg, 174 1.1 thorpej * struct evcnt *ev, int vec, int ipl, int flags) 175 1.1 thorpej * 176 1.1 thorpej * Establish an interrupt handler. If vec is 0, then the handler is 177 1.1 thorpej * registered in the auto-vector list corresponding to the specified 178 1.1 thorpej * m68k interrupt priroity level (this is NOT an IPL_* value). Otherwise. 179 1.1 thorpej * the handler is registered at the specified vector. 180 1.1 thorpej * 181 1.9 andvar * Vectored interrupts are not shareable. The interrupt vector must be 182 1.1 thorpej * within the platform's "user vector" region, which is generally defined 183 1.1 thorpej * as vectors 64-255, although some platforms may use vectors that start 184 1.1 thorpej * below 64 (in which case, that platform must define MACHINE_USERVEC_START 185 1.1 thorpej * to override the default). 186 1.1 thorpej * 187 1.1 thorpej * Vectored interrupt support is not included by default in order to reduce 188 1.1 thorpej * the memory footprint. If a platform wishes to enable vectored interrupts, 189 1.1 thorpej * then it should define __HAVE_M68K_INTR_VECTORED in its <machine/types.h> 190 1.1 thorpej * and genassym.cf. 191 1.1 thorpej * 192 1.1 thorpej * ==> m68k_intr_disestablish(void *ih) 193 1.1 thorpej * 194 1.1 thorpej * Removes a previously-established interrupt handler. Returns true 195 1.1 thorpej * if there are no more handlers on the list that handler was on. This 196 1.1 thorpej * information can be used to e.g. disable interrupts on a PIC. 197 1.1 thorpej */ 198 1.1 thorpej void m68k_intr_init(const struct m68k_ih_allocfuncs *); 199 1.1 thorpej void *m68k_intr_establish(int (*)(void *), void *, struct evcnt *, 200 1.1 thorpej int/*vec*/, int/*m68k ipl*/, int/*isrpri*/, int/*flags*/); 201 1.1 thorpej bool m68k_intr_disestablish(void *); 202 1.1 thorpej 203 1.5 thorpej #ifdef __HAVE_M68K_INTR_VECTORED 204 1.5 thorpej void *m68k_intrvec_intrhand(int vec); /* XXX */ 205 1.5 thorpej #endif 206 1.5 thorpej 207 1.6 thorpej #endif /* !_LOCORE */ 208 1.6 thorpej 209 1.1 thorpej #endif /* _KERNEL */ 210 1.1 thorpej 211 1.1 thorpej #endif /* _M68k_INTR_H_ */ 212