Annotation of sys/arch/alpha/include/intr.h, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: intr.h,v 1.28 2007/05/16 19:37:06 thib Exp $ */
2: /* $NetBSD: intr.h,v 1.26 2000/06/03 20:47:41 thorpej Exp $ */
3:
4: /*-
5: * Copyright (c) 2000 The NetBSD Foundation, Inc.
6: * All rights reserved.
7: *
8: * This code is derived from software contributed to The NetBSD Foundation
9: * by Jason R. Thorpe.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the NetBSD
22: * Foundation, Inc. and its contributors.
23: * 4. Neither the name of The NetBSD Foundation nor the names of its
24: * contributors may be used to endorse or promote products derived
25: * from this software without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37: * POSSIBILITY OF SUCH DAMAGE.
38: */
39:
40: /*
41: * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved.
42: * Copyright (c) 1996 Carnegie-Mellon University.
43: * All rights reserved.
44: *
45: * Author: Chris G. Demetriou
46: *
47: * Permission to use, copy, modify and distribute this software and
48: * its documentation is hereby granted, provided that both the copyright
49: * notice and this permission notice appear in all copies of the
50: * software, derivative works or modified versions, and any portions
51: * thereof, and that both notices appear in supporting documentation.
52: *
53: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
54: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
55: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
56: *
57: * Carnegie Mellon requests users of this software to return to
58: *
59: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
60: * School of Computer Science
61: * Carnegie Mellon University
62: * Pittsburgh PA 15213-3890
63: *
64: * any improvements or extensions that they make and grant Carnegie the
65: * rights to redistribute these changes.
66: */
67:
68: #ifndef _ALPHA_INTR_H_
69: #define _ALPHA_INTR_H_
70:
71: #include <sys/evcount.h>
72: #include <sys/lock.h>
73: #include <sys/queue.h>
74: #include <machine/atomic.h>
75:
76: /*
77: * The Alpha System Control Block. This is 8k long, and you get
78: * 16 bytes per vector (i.e. the vector numbers are spaced 16
79: * apart).
80: *
81: * This is sort of a "shadow" SCB -- rather than the CPU jumping
82: * to (SCBaddr + (16 * vector)), like it does on the VAX, we get
83: * a vector number in a1. We use the SCB to look up a routine/arg
84: * and jump to it.
85: *
86: * Since we use the SCB only for I/O interrupts, we make it shorter
87: * than normal, starting it at vector 0x800 (the start of the I/O
88: * interrupt vectors).
89: */
90: #define SCB_IOVECBASE 0x0800
91: #define SCB_VECSIZE 0x0010
92: #define SCB_SIZE 0x2000
93:
94: #define SCB_VECTOIDX(x) ((x) >> 4)
95: #define SCB_IDXTOVEC(x) ((x) << 4)
96:
97: #define SCB_NIOVECS SCB_VECTOIDX(SCB_SIZE - SCB_IOVECBASE)
98:
99: struct scbvec {
100: void (*scb_func)(void *, u_long);
101: void *scb_arg;
102: };
103:
104: /*
105: * Alpha interrupts come in at one of 4 levels:
106: *
107: * software interrupt level
108: * i/o level 1
109: * i/o level 2
110: * clock level
111: *
112: * However, since we do not have any way to know which hardware
113: * level a particular i/o interrupt comes in on, we have to
114: * whittle it down to 3.
115: */
116:
117: #define IPL_NONE ALPHA_PSL_IPL_0
118: #define IPL_SOFTINT ALPHA_PSL_IPL_SOFT
119: #define IPL_BIO ALPHA_PSL_IPL_IO
120: #define IPL_NET ALPHA_PSL_IPL_IO
121: #define IPL_TTY ALPHA_PSL_IPL_IO
122: #define IPL_SERIAL ALPHA_PSL_IPL_IO
123: #define IPL_AUDIO ALPHA_PSL_IPL_IO
124: #define IPL_VM ALPHA_PSL_IPL_IO
125: #define IPL_CLOCK ALPHA_PSL_IPL_CLOCK
126: #define IPL_HIGH ALPHA_PSL_IPL_HIGH
127:
128: #define IPL_SOFTSERIAL -1 /* serial software interrupts */
129: #define IPL_SOFTNET -2 /* network software interrupts */
130: #define IPL_SOFTCLOCK -3 /* clock software interrupts */
131: #define IPL_SOFT -4 /* other software interrupts */
132:
133: #define IST_UNUSABLE -1 /* interrupt cannot be used */
134: #define IST_NONE 0 /* none (dummy) */
135: #define IST_PULSE 1 /* pulsed */
136: #define IST_EDGE 2 /* edge-triggered */
137: #define IST_LEVEL 3 /* level-triggered */
138:
139: #define SI_SOFTSERIAL 0
140: #define SI_SOFTNET 1
141: #define SI_SOFTCLOCK 2
142: #define SI_SOFT 3
143: #define SI_NSOFT 4
144:
145: #ifdef _KERNEL
146:
147: /* SPL asserts */
148: #ifdef DIAGNOSTIC
149: /*
150: * Although this function is implemented in MI code, it must be in this MD
151: * header because we don't want this header to include MI includes.
152: */
153: void splassert_fail(int, int, const char *);
154: extern int splassert_ctl;
155: void splassert_check(int, const char *);
156: #define splassert(__wantipl) \
157: do { \
158: if (splassert_ctl > 0) { \
159: splassert_check(__wantipl, __func__); \
160: } \
161: } while (0)
162: #else
163: #define splassert(wantipl) do { /* nothing */ } while (0)
164: #endif
165:
166: /* IPL-lowering/restoring macros */
167: #define splx(s) \
168: ((s) == ALPHA_PSL_IPL_0 ? spl0() : alpha_pal_swpipl(s))
169:
170: /* IPL-raising functions/macros */
171: int _splraise(int);
172:
173: #define splsoft() _splraise(IPL_SOFTINT)
174: #define splsoftserial() splsoft()
175: #define splsoftclock() splsoft()
176: #define splsoftnet() splsoft()
177: #define splnet() _splraise(IPL_NET)
178: #define splbio() _splraise(IPL_BIO)
179: #define spltty() _splraise(IPL_TTY)
180: #define splserial() _splraise(IPL_SERIAL)
181: #define splaudio() _splraise(IPL_AUDIO)
182: #define splvm() _splraise(IPL_VM)
183: #define splclock() _splraise(IPL_CLOCK)
184: #define splstatclock() _splraise(IPL_CLOCK)
185: #define splhigh() _splraise(IPL_HIGH)
186:
187: #define spllpt() spltty()
188: #define spllock() splhigh()
189: #define splsched() splhigh()
190:
191: /*
192: * Interprocessor interrupts. In order how we want them processed.
193: */
194: #define ALPHA_IPI_HALT 0x0000000000000001UL
195: #define ALPHA_IPI_TBIA 0x0000000000000002UL
196: #define ALPHA_IPI_TBIAP 0x0000000000000004UL
197: #define ALPHA_IPI_SHOOTDOWN 0x0000000000000008UL
198: #define ALPHA_IPI_IMB 0x0000000000000010UL
199: #define ALPHA_IPI_AST 0x0000000000000020UL
200: #define ALPHA_IPI_SYNCH_FPU 0x0000000000000040UL
201: #define ALPHA_IPI_DISCARD_FPU 0x0000000000000080UL
202: #define ALPHA_IPI_PAUSE 0x0000000000000100UL
203:
204: #define ALPHA_NIPIS 6 /* must not exceed 64 */
205:
206: typedef void (*ipifunc_t)(void);
207: extern ipifunc_t ipifuncs[ALPHA_NIPIS];
208:
209: void alpha_send_ipi(unsigned long, unsigned long);
210: void alpha_broadcast_ipi(unsigned long);
211: void alpha_multicast_ipi(unsigned long, unsigned long);
212:
213: /*
214: * Alpha shared-interrupt-line common code.
215: */
216:
217: struct alpha_shared_intrhand {
218: TAILQ_ENTRY(alpha_shared_intrhand)
219: ih_q;
220: struct alpha_shared_intr *ih_intrhead;
221: int (*ih_fn)(void *);
222: void *ih_arg;
223: int ih_level;
224: unsigned int ih_num;
225: struct evcount ih_count;
226: };
227:
228: struct alpha_shared_intr {
229: TAILQ_HEAD(,alpha_shared_intrhand)
230: intr_q;
231: void *intr_private;
232: int intr_sharetype;
233: int intr_dfltsharetype;
234: int intr_nstrays;
235: int intr_maxstrays;
236: };
237:
238: #define ALPHA_SHARED_INTR_DISABLE(asi, num) \
239: ((asi)[num].intr_maxstrays != 0 && \
240: (asi)[num].intr_nstrays == (asi)[num].intr_maxstrays)
241:
242: /*
243: * simulated software interrupt register
244: */
245: extern unsigned long ssir;
246:
247: #define setsoft(x) atomic_setbits_ulong(&ssir, 1 << (x))
248:
249: struct alpha_soft_intrhand {
250: TAILQ_ENTRY(alpha_soft_intrhand)
251: sih_q;
252: struct alpha_soft_intr *sih_intrhead;
253: void (*sih_fn)(void *);
254: void *sih_arg;
255: int sih_pending;
256: };
257:
258: struct alpha_soft_intr {
259: TAILQ_HEAD(, alpha_soft_intrhand)
260: softintr_q;
261: struct simplelock softintr_slock;
262: unsigned long softintr_siq;
263: };
264:
265: void *softintr_establish(int, void (*)(void *), void *);
266: void softintr_disestablish(void *);
267: void softintr_init(void);
268: void softintr_dispatch(void);
269:
270: #define softintr_schedule(arg) \
271: do { \
272: struct alpha_soft_intrhand *__sih = (arg); \
273: struct alpha_soft_intr *__si = __sih->sih_intrhead; \
274: int __s; \
275: \
276: __s = splhigh(); \
277: simple_lock(&__si->softintr_slock); \
278: if (__sih->sih_pending == 0) { \
279: TAILQ_INSERT_TAIL(&__si->softintr_q, __sih, sih_q); \
280: __sih->sih_pending = 1; \
281: setsoft(__si->softintr_siq); \
282: } \
283: simple_unlock(&__si->softintr_slock); \
284: splx(__s); \
285: } while (0)
286:
287: /* XXX For legacy software interrupts. */
288: extern struct alpha_soft_intrhand *softnet_intrhand;
289: extern struct alpha_soft_intrhand *softclock_intrhand;
290:
291: #define setsoftnet() softintr_schedule(softnet_intrhand)
292: #define setsoftclock() softintr_schedule(softclock_intrhand)
293:
294: struct alpha_shared_intr *alpha_shared_intr_alloc(unsigned int);
295: int alpha_shared_intr_dispatch(struct alpha_shared_intr *,
296: unsigned int);
297: void *alpha_shared_intr_establish(struct alpha_shared_intr *,
298: unsigned int, int, int, int (*)(void *), void *, const char *);
299: void alpha_shared_intr_disestablish(struct alpha_shared_intr *,
300: void *, const char *);
301: int alpha_shared_intr_get_sharetype(struct alpha_shared_intr *,
302: unsigned int);
303: int alpha_shared_intr_isactive(struct alpha_shared_intr *,
304: unsigned int);
305: int alpha_shared_intr_firstactive(struct alpha_shared_intr *,
306: unsigned int);
307: void alpha_shared_intr_set_dfltsharetype(struct alpha_shared_intr *,
308: unsigned int, int);
309: void alpha_shared_intr_set_maxstrays(struct alpha_shared_intr *,
310: unsigned int, int);
311: void alpha_shared_intr_reset_strays(struct alpha_shared_intr *,
312: unsigned int);
313: void alpha_shared_intr_stray(struct alpha_shared_intr *, unsigned int,
314: const char *);
315: void alpha_shared_intr_set_private(struct alpha_shared_intr *,
316: unsigned int, void *);
317: void *alpha_shared_intr_get_private(struct alpha_shared_intr *,
318: unsigned int);
319:
320: extern struct scbvec scb_iovectab[];
321:
322: void scb_init(void);
323: void scb_set(u_long, void (*)(void *, u_long), void *);
324: u_long scb_alloc(void (*)(void *, u_long), void *);
325: void scb_free(u_long);
326:
327: #define SCB_ALLOC_FAILED ((u_long) -1)
328:
329: #endif /* _KERNEL */
330: #endif /* ! _ALPHA_INTR_H_ */
CVSweb