1/* $OpenBSD: intr.h,v 1.37 2025/11/10 12:34:52 dlg Exp $ */
2/* $NetBSD: intr.h,v 1.2 2003/05/04 22:01:56 fvdl Exp $ */
3
4/*-
5 * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Charles M. Hannum, and 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 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef _MACHINE_INTR_H_
34#define _MACHINE_INTR_H_
35
36#define __USE_MI_SOFTINTR
37
38#include <sys/softintr.h>
39#include <machine/intrdefs.h>
40
41#ifndef _LOCORE
42#include <machine/cpu.h>
43
44#include <sys/evcount.h>
45
46/*
47 * Struct describing an interrupt source for a CPU. struct cpu_info
48 * has an array of MAX_INTR_SOURCES of these. The index in the array
49 * is equal to the stub number of the stubcode as present in vector.s
50 *
51 * The primary CPU's array of interrupt sources has its first 16
52 * entries reserved for legacy ISA irq handlers. This means that
53 * they have a 1:1 mapping for arrayindex:irq_num. This is not
54 * true for interrupts that come in through IO APICs, to find
55 * their source, go through ci->ci_isources[index].is_pic
56 *
57 * It's possible to always maintain a 1:1 mapping, but that means
58 * limiting the total number of interrupt sources to MAX_INTR_SOURCES
59 * (32), instead of 32 per CPU. It also would mean that having multiple
60 * IO APICs which deliver interrupts from an equal pin number would
61 * overlap if they were to be sent to the same CPU.
62 */
63
64struct intrstub {
65 void *ist_entry;
66 void *ist_recurse;
67 void *ist_resume;
68};
69
70struct intrsource {
71 int is_maxlevel; /* max. IPL for this source */
72 int is_pin; /* IRQ for legacy; pin for IO APIC */
73 struct intrhand *is_handlers; /* handler chain */
74 struct pic *is_pic; /* originating PIC */
75 void *is_recurse; /* entry for spllower */
76 void *is_resume; /* entry for doreti */
77 char is_evname[32]; /* event counter name */
78 int is_flags; /* see below */
79 int is_type; /* level, edge */
80 int is_idtvec;
81 int is_minlevel;
82};
83
84#define IS_LEGACY 0x0001 /* legacy ISA irq source */
85#define IS_IPI 0x0002
86#define IS_LOG 0x0004
87
88
89/*
90 * Interrupt handler chains. *_intr_establish() insert a handler into
91 * the list. The handler is called with its (single) argument.
92 */
93
94struct intrhand {
95 int (*ih_fun)(void *);
96 void *ih_arg;
97 int ih_level;
98 int ih_flags;
99 struct intrhand *ih_next;
100 int ih_pin;
101 int ih_slot;
102 struct cpu_info *ih_cpu;
103 int ih_irq;
104 struct evcount ih_count;
105};
106
107#define IMASK(ci,level) (ci)->ci_imask[(level)]
108#define IUNMASK(ci,level) (ci)->ci_iunmask[(level)]
109
110extern void Xspllower(int);
111
112int splraise(int);
113int spllower(int);
114void softintr(int);
115void dosoftint(int);
116
117/*
118 * Convert spl level to local APIC level
119 */
120#define APIC_LEVEL(l) ((l) << 4)
121
122/*
123 * compiler barrier: prevent reordering of instructions.
124 * This prevents the compiler from reordering code around
125 * this "instruction", acting as a sequence point for code generation.
126 */
127
128#define __splbarrier() __asm volatile("":::"memory")
129
130/*
131 * Hardware interrupt masks
132 */
133#define splbio() splraise(IPL_BIO)
134#define splnet() splraise(IPL_NET)
135#define spltty() splraise(IPL_TTY)
136#define splaudio() splraise(IPL_AUDIO)
137#define splclock() splraise(IPL_CLOCK)
138#define splstatclock() splclock()
139#define splipi() splraise(IPL_IPI)
140
141/*
142 * Software interrupt masks
143 */
144#define splsoftclock() splraise(IPL_SOFTCLOCK)
145#define splsoftnet() splraise(IPL_SOFTNET)
146#define splsofttty() splraise(IPL_SOFTTTY)
147
148/*
149 * Miscellaneous
150 */
151#define splvm() splraise(IPL_VM)
152#define splhigh() splraise(IPL_HIGH)
153#define spl0() spllower(IPL_NONE)
154#define splsched() splraise(IPL_SCHED)
155#define splx(x) spllower(x)
156
157/* SPL asserts */
158#ifdef DIAGNOSTIC
159/*
160 * Although this function is implemented in MI code, it must be in this MD
161 * header because we don't want this header to include MI includes.
162 */
163void splassert_fail(int, int, const char *);
164extern int splassert_ctl;
165void splassert_check(int, const char *);
166#define splassert(__wantipl) do { \
167 if (splassert_ctl > 0) { \
168 splassert_check(__wantipl, __func__); \
169 } \
170} while (0)
171#define splsoftassert(wantipl) splassert(wantipl)
172#else
173#define splassert(wantipl) do { /* nada */ } while (0)
174#define splsoftassert(wantipl) do { /* nada */ } while (0)
175#endif
176
177#define IPLSHIFT 4 /* The upper nibble of vectors is the IPL. */
178#define IPL(level) ((level) >> IPLSHIFT) /* Extract the IPL. */
179
180#include <machine/pic.h>
181
182/*
183 * Stub declarations.
184 */
185
186extern void Xsoftclock(void);
187extern void Xsoftnet(void);
188extern void Xsofttty(void);
189
190extern struct intrstub i8259_stubs[];
191extern struct intrstub ioapic_edge_stubs[];
192extern struct intrstub ioapic_level_stubs[];
193
194struct cpu_info;
195
196extern int intr_shared_edge;
197
198extern char idt_allocmap[];
199
200void intr_default_setup(void);
201int x86_nmi(void);
202void intr_calculatemasks(struct cpu_info *);
203int intr_allocate_slot_cpu(struct cpu_info *, struct pic *, int, int *);
204int intr_allocate_slot(struct pic *, int, int, int, struct cpu_info **, int *,
205 int *);
206void *intr_establish(int, struct pic *, int, int, int,
207 struct cpu_info *, int (*)(void *), void *, const char *);
208void intr_disestablish(struct intrhand *);
209int intr_handler(struct intrframe *, struct intrhand *);
210void cpu_intr_init(struct cpu_info *);
211void intr_printconfig(void);
212void intr_barrier(void *);
213void intr_set_wakeup(void *);
214void intr_enable_wakeup(void);
215void intr_disable_wakeup(void);
216
217#ifdef MULTIPROCESSOR
218void x86_send_ipi(struct cpu_info *, int);
219int x86_fast_ipi(struct cpu_info *, int);
220void x86_broadcast_ipi(int);
221void x86_ipi_handler(void);
222void x86_setperf_ipi(struct cpu_info *);
223
224extern void (*ipifunc[X86_NIPI])(struct cpu_info *);
225
226#define cpu_xcall_ipi(_ci) x86_send_ipi((_ci), X86_IPI_XCALL)
227void Xxcallintr(void);
228#endif /* MULTIPROCESSOR */
229
230#endif /* !_LOCORE */
231
232#endif /* !_MACHINE_INTR_H_ */