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
ppc_smask_init()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
splraise(int newcpl)67 splraise(int newcpl)
68 {
69 return ppc_intr_func.raise(newcpl);
70 }
71
72 int
spllower(int newcpl)73 spllower(int newcpl)
74 {
75 return ppc_intr_func.lower(newcpl);
76 }
77
78 void
splx(int newcpl)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
ppc_dflt_splraise(int newcpl)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
ppc_dflt_spllower(int newcpl)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
ppc_dflt_splx(int newcpl)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 *
ppc_intr_typename(int type)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
intr_barrier(void * ih)157 intr_barrier(void *ih)
158 {
159 sched_barrier(NULL);
160 }
161
162 #ifdef DIAGNOSTIC
163 void
splassert_check(int wantipl,const char * func)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