1 /* $OpenBSD: intr.c,v 1.12 2024/10/24 17:37:06 gkoehler Exp $ */ 2 3 /* 4 * Copyright (c) 1997 Per Fogelstrom, Opsycon AB and RTMX Inc, USA. 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 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed under OpenBSD by 17 * Per Fogelstrom, Opsycon AB, Sweden for RTMX Inc, North Carolina USA. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 */ 34 #include <sys/param.h> 35 36 #include <machine/cpu.h> 37 #include <machine/intr.h> 38 39 int ppc_dflt_splraise(int); 40 int ppc_dflt_spllower(int); 41 void ppc_dflt_splx(int); 42 43 /* provide a function for asm code to call */ 44 #undef splraise 45 #undef spllower 46 #undef splx 47 48 int ppc_smask[IPL_NUM]; 49 50 void 51 ppc_smask_init() 52 { 53 int i; 54 55 for (i = IPL_NONE; i <= IPL_HIGH; i++) { 56 ppc_smask[i] = 0; 57 if (i < IPL_SOFTCLOCK) 58 ppc_smask[i] |= SI_TO_IRQBIT(SI_SOFTCLOCK); 59 if (i < IPL_SOFTNET) 60 ppc_smask[i] |= SI_TO_IRQBIT(SI_SOFTNET); 61 if (i < IPL_SOFTTTY) 62 ppc_smask[i] |= SI_TO_IRQBIT(SI_SOFTTTY); 63 } 64 } 65 66 int 67 splraise(int newcpl) 68 { 69 return ppc_intr_func.raise(newcpl); 70 } 71 72 int 73 spllower(int newcpl) 74 { 75 return ppc_intr_func.lower(newcpl); 76 } 77 78 void 79 splx(int newcpl) 80 { 81 ppc_intr_func.x(newcpl); 82 } 83 84 /* 85 * functions with 'default' behavior to use before the real 86 * interrupt controller attaches 87 */ 88 89 int 90 ppc_dflt_splraise(int newcpl) 91 { 92 struct cpu_info *ci = curcpu(); 93 int oldcpl; 94 95 oldcpl = ci->ci_cpl; 96 if (newcpl < oldcpl) 97 newcpl = oldcpl; 98 ci->ci_cpl = newcpl; 99 100 return (oldcpl); 101 } 102 103 int 104 ppc_dflt_spllower(int newcpl) 105 { 106 struct cpu_info *ci = curcpu(); 107 int oldcpl; 108 109 oldcpl = ci->ci_cpl; 110 111 splx(newcpl); 112 113 return (oldcpl); 114 } 115 116 void 117 ppc_dflt_splx(int newcpl) 118 { 119 struct cpu_info *ci = curcpu(); 120 121 ci->ci_cpl = newcpl; 122 123 if (ci->ci_dec_deferred && newcpl < IPL_CLOCK) { 124 ppc_mtdec(0); 125 ppc_mtdec(UINT32_MAX); /* raise DEC exception */ 126 } 127 128 if (ci->ci_ipending & ppc_smask[newcpl]) 129 dosoftint(newcpl); 130 } 131 132 struct ppc_intr_func ppc_intr_func = 133 { 134 ppc_dflt_splraise, 135 ppc_dflt_spllower, 136 ppc_dflt_splx 137 }; 138 139 char * 140 ppc_intr_typename(int type) 141 { 142 switch (type) { 143 case IST_NONE : 144 return ("none"); 145 case IST_PULSE: 146 return ("pulsed"); 147 case IST_EDGE: 148 return ("edge-triggered"); 149 case IST_LEVEL: 150 return ("level-triggered"); 151 default: 152 return ("unknown"); 153 } 154 } 155 156 void 157 intr_barrier(void *ih) 158 { 159 sched_barrier(NULL); 160 } 161 162 #ifdef DIAGNOSTIC 163 void 164 splassert_check(int wantipl, const char *func) 165 { 166 struct cpu_info *ci = curcpu(); 167 168 if (ci->ci_cpl < wantipl) 169 splassert_fail(wantipl, ci->ci_cpl, func); 170 171 if (wantipl == IPL_NONE && ci->ci_idepth != 0) 172 splassert_fail(-1, ci->ci_idepth, func); 173 } 174 #endif 175