xref: /openbsd-src/sys/arch/powerpc/powerpc/intr.c (revision ab14eefca8bc3dd11e2a50341177d4210555dbfc)
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