1 /* $NetBSD: intr.h,v 1.15 2007/11/07 15:56:13 ad Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Matt Fredette. 5 * Copyright (c) 1998 Matt Thomas. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the company nor the names of the authors may be used to 17 * endorse or promote products derived from this software without specific 18 * prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #ifndef _SUN68K_INTR_H_ 34 #define _SUN68K_INTR_H_ 35 36 #include <sys/queue.h> 37 #include <m68k/psl.h> 38 39 /* 40 * Interrupt levels. 41 */ 42 #define IPL_NONE 0 43 #define IPL_SOFTCLOCK 1 44 #define IPL_SOFTNET 2 45 #define IPL_BIO 3 46 #define IPL_NET 4 47 #define IPL_SOFTSERIAL 5 48 #define IPL_TTY 6 49 #define IPL_LPT 7 50 #define IPL_VM 8 51 #if 0 52 #define IPL_AUDIO 9 53 #endif 54 #define IPL_CLOCK 10 55 #define IPL_STATCLOCK 11 56 #define IPL_SERIAL 12 57 #define IPL_SCHED 13 58 #define IPL_HIGH 14 59 #define IPL_LOCK 15 60 #if 0 61 #define IPL_IPI 16 62 #endif 63 64 #define _IPL_SOFT_LEVEL1 1 65 #define _IPL_SOFT_LEVEL2 2 66 #define _IPL_SOFT_LEVEL3 3 67 #define _IPL_SOFT_LEVEL_MIN 1 68 #define _IPL_SOFT_LEVEL_MAX 3 69 70 #ifdef _KERNEL 71 72 typedef int ipl_t; 73 typedef struct { 74 uint16_t _psl; 75 } ipl_cookie_t; 76 77 ipl_cookie_t makeiplcookie(ipl_t ipl); 78 79 static inline int 80 splraiseipl(ipl_cookie_t icookie) 81 { 82 83 return _splraise(icookie._psl); 84 } 85 86 LIST_HEAD(sh_head, softintr_handler); 87 88 struct softintr_head { 89 int shd_ipl; 90 struct sh_head shd_intrs; 91 }; 92 93 struct softintr_handler { 94 struct softintr_head *sh_head; 95 LIST_ENTRY(softintr_handler) sh_link; 96 void (*sh_func)(void *); 97 void *sh_arg; 98 volatile int sh_pending; 99 }; 100 101 void softintr_init(void); 102 void *softintr_establish(int, void (*)(void *), void *); 103 void softintr_disestablish(void *); 104 105 /* These control the software interrupt register. */ 106 void isr_soft_request(int); 107 void isr_soft_clear(int); 108 109 static __inline void 110 softintr_schedule(void *arg) 111 { 112 struct softintr_handler * const sh = arg; 113 114 sh->sh_pending = 1; 115 isr_soft_request(sh->sh_head->shd_ipl); 116 } 117 118 extern void *softnet_cookie; 119 #define setsoftnet() softintr_schedule(softnet_cookie) 120 121 /* These connect interrupt handlers. */ 122 typedef int (*isr_func_t)(void *); 123 void isr_add_autovect(isr_func_t, void *, int); 124 void isr_add_vectored(isr_func_t, void *, int, int); 125 void isr_add_custom(int, void *); 126 127 /* 128 * Define inline functions for PSL manipulation. 129 * These are as close to macros as one can get. 130 * When not optimizing gcc will call the locore.s 131 * functions by the same names, so breakpoints on 132 * these functions will work normally, etc. 133 * (See the GCC extensions info document.) 134 */ 135 136 static __inline int _getsr(void); 137 138 /* Get current sr value. */ 139 static __inline int 140 _getsr(void) 141 { 142 int rv; 143 144 __asm volatile ("clrl %0; movew %%sr,%0" : "=&d" (rv)); 145 return (rv); 146 } 147 148 /* 149 * The rest of this is sun68k specific, because other ports may 150 * need to do special things in spl0() (i.e. simulate SIR). 151 * Suns have a REAL interrupt register, so spl0() and splx(s) 152 * have no need to check for any simulated interrupts, etc. 153 */ 154 155 #define spl0() _spl0() /* we have real software interrupts */ 156 #define splx(x) _spl(x) 157 158 /* IPL used by soft interrupts: netintr(), softclock() */ 159 #define splsoftclock() splraise1() 160 #define splsoftnet() splraise1() 161 #define splsoftserial() splraise3() 162 163 /* Highest block device (strategy) IPL. */ 164 #define splbio() splraise2() 165 166 /* Highest network interface IPL. */ 167 #define splnet() splraise3() 168 169 /* Highest tty device IPL. */ 170 #define spltty() splraise4() 171 172 /* 173 * Requirement: imp >= (highest network, tty, or disk IPL) 174 * This is used mostly in the VM code. 175 * Note that the VM code runs at spl7 during kernel 176 * initialization, and later at spl0, so we have to 177 * use splraise to avoid enabling interrupts early. 178 */ 179 #define splvm() splraise4() 180 181 /* Intersil or Am9513 clock hardware interrupts (hard-wired at 5) */ 182 #define splclock() splraise5() 183 #define splstatclock() splclock() 184 185 /* Zilog Serial hardware interrupts (hard-wired at 6) */ 186 #define splzs() splraise6() 187 #define splserial() splraise6() 188 #define IPL_ZS IPL_SERIAL 189 190 /* Block out all interrupts (except NMI of course). */ 191 #define splhigh() spl7() 192 #define splsched() spl7() 193 #define spllock() spl7() 194 195 /* This returns true iff the spl given is spl0. */ 196 #define is_spl0(s) (((s) & PSL_IPL7) == 0) 197 198 #endif /* _KERNEL */ 199 200 #endif /* _SUN68K_INTR_H */ 201