xref: /openbsd-src/sys/arch/arm64/include/intr.h (revision d93766d5c0c194345cb87d4641a13d3883a0cb49)
1*d93766d5Sjsg /*	$OpenBSD: intr.h,v 1.23 2024/10/14 10:08:13 jsg Exp $ */
2f24071e5Spatrick 
3f24071e5Spatrick /*
4f24071e5Spatrick  * Copyright (c) 2001-2004 Opsycon AB  (www.opsycon.se / www.opsycon.com)
5f24071e5Spatrick  *
6f24071e5Spatrick  * Redistribution and use in source and binary forms, with or without
7f24071e5Spatrick  * modification, are permitted provided that the following conditions
8f24071e5Spatrick  * are met:
9f24071e5Spatrick  * 1. Redistributions of source code must retain the above copyright
10f24071e5Spatrick  *    notice, this list of conditions and the following disclaimer.
11f24071e5Spatrick  * 2. Redistributions in binary form must reproduce the above copyright
12f24071e5Spatrick  *    notice, this list of conditions and the following disclaimer in the
13f24071e5Spatrick  *    documentation and/or other materials provided with the distribution.
14f24071e5Spatrick  *
15f24071e5Spatrick  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16f24071e5Spatrick  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17f24071e5Spatrick  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18f24071e5Spatrick  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19f24071e5Spatrick  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20f24071e5Spatrick  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21f24071e5Spatrick  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22f24071e5Spatrick  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23f24071e5Spatrick  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24f24071e5Spatrick  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25f24071e5Spatrick  * SUCH DAMAGE.
26f24071e5Spatrick  *
27f24071e5Spatrick  */
28f24071e5Spatrick 
29f24071e5Spatrick #ifndef	_MACHINE_INTR_H_
30f24071e5Spatrick #define	_MACHINE_INTR_H_
31f24071e5Spatrick 
32f24071e5Spatrick /*
33f24071e5Spatrick  * The interrupt level ipl is a logical level; per-platform interrupt
34f24071e5Spatrick  * code will turn it into the appropriate hardware interrupt masks
35f24071e5Spatrick  * values.
36f24071e5Spatrick  *
37f24071e5Spatrick  * Interrupt sources on the CPU are kept enabled regardless of the
38f24071e5Spatrick  * current ipl value; individual hardware sources interrupting while
39f24071e5Spatrick  * logically masked are masked on the fly, remembered as pending, and
40f24071e5Spatrick  * unmasked at the first splx() opportunity.
41f24071e5Spatrick  */
42f24071e5Spatrick #ifdef _KERNEL
43f24071e5Spatrick 
44f24071e5Spatrick /* Interrupt priority `levels'; not mutually exclusive. */
45f24071e5Spatrick #define	IPL_NONE	0	/* nothing */
46f24071e5Spatrick #define	IPL_SOFT	1	/* soft interrupts */
47f24071e5Spatrick #define	IPL_SOFTCLOCK	2	/* soft clock interrupts */
48f24071e5Spatrick #define	IPL_SOFTNET	3	/* soft network interrupts */
49f24071e5Spatrick #define	IPL_SOFTTTY	4	/* soft terminal interrupts */
50f24071e5Spatrick #define	IPL_BIO		5	/* block I/O */
51f24071e5Spatrick #define	IPL_NET		6	/* network */
52f24071e5Spatrick #define	IPL_TTY		7	/* terminal */
53f24071e5Spatrick #define	IPL_VM		8	/* memory allocation */
54f24071e5Spatrick #define	IPL_AUDIO	9	/* audio */
55f24071e5Spatrick #define	IPL_CLOCK	10	/* clock */
56f24071e5Spatrick #define	IPL_SCHED	IPL_CLOCK
57f24071e5Spatrick #define	IPL_STATCLOCK	IPL_CLOCK
58f24071e5Spatrick #define	IPL_HIGH	11	/* everything */
59f24071e5Spatrick #define	IPL_IPI		12	/* interprocessor interrupt */
60f24071e5Spatrick #define	NIPL		13	/* number of levels */
61f24071e5Spatrick 
624965d1a4Smpi #define	IPL_MPFLOOR	IPL_TTY
63f24071e5Spatrick /* Interrupt priority 'flags'. */
64d7e3db9cSkettenis #define	IPL_IRQMASK	0xf	/* priority only */
65d7e3db9cSkettenis #define	IPL_FLAGMASK	0xf00	/* flags only*/
66d7e3db9cSkettenis #define	IPL_MPSAFE	0x100	/* 'mpsafe' interrupt, no kernel lock */
673b6109e0Skettenis #define	IPL_WAKEUP	0x200	/* 'wakeup' interrupt */
68f24071e5Spatrick 
69f24071e5Spatrick /* Interrupt sharing types. */
70f24071e5Spatrick #define	IST_NONE	0	/* none */
71f24071e5Spatrick #define	IST_PULSE	1	/* pulsed */
72f24071e5Spatrick #define	IST_EDGE	2	/* edge-triggered */
73f24071e5Spatrick #define	IST_LEVEL	3	/* level-triggered */
74f24071e5Spatrick 
75f24071e5Spatrick #define	IST_LEVEL_LOW		IST_LEVEL
76f24071e5Spatrick #define	IST_LEVEL_HIGH		4
77f24071e5Spatrick #define	IST_EDGE_FALLING	IST_EDGE
78f24071e5Spatrick #define	IST_EDGE_RISING		5
79f24071e5Spatrick #define	IST_EDGE_BOTH		6
80f24071e5Spatrick 
81f24071e5Spatrick #ifndef _LOCORE
82f24071e5Spatrick #include <sys/queue.h>
83f24071e5Spatrick 
84f24071e5Spatrick int	splraise(int);
85f24071e5Spatrick int	spllower(int);
86f24071e5Spatrick void	splx(int);
87f24071e5Spatrick 
88f24071e5Spatrick void	arm_do_pending_intr(int);
89adc7c282Skettenis void	arm_set_intr_handler(int (*)(int), int (*)(int), void (*)(int),
905dee5702Skettenis 	    void (*)(int), void (*)(void *), void (*)(void *),
915dee5702Skettenis 	    void (*)(void), void (*)(void));
92f24071e5Spatrick 
932b0be198Skettenis struct machine_intr_handle {
9472d45bb7Spatrick 	struct interrupt_controller *ih_ic;
9572d45bb7Spatrick 	void *ih_ih;
9672d45bb7Spatrick };
9772d45bb7Spatrick 
98f24071e5Spatrick struct arm_intr_func {
99f24071e5Spatrick 	int (*raise)(int);
100f24071e5Spatrick 	int (*lower)(int);
101f24071e5Spatrick 	void (*x)(int);
102f24071e5Spatrick 	void (*setipl)(int);
1035dee5702Skettenis 	void (*enable_wakeup)(void);
1045dee5702Skettenis 	void (*disable_wakeup)(void);
105f24071e5Spatrick };
106f24071e5Spatrick 
107f24071e5Spatrick extern struct arm_intr_func arm_intr_func;
108f24071e5Spatrick 
109f24071e5Spatrick #define	splraise(cpl)		(arm_intr_func.raise(cpl))
110f24071e5Spatrick #define	_splraise(cpl)		(arm_intr_func.raise(cpl))
111f24071e5Spatrick #define	spllower(cpl)		(arm_intr_func.lower(cpl))
112f24071e5Spatrick #define	splx(cpl)		(arm_intr_func.x(cpl))
113f24071e5Spatrick 
114f24071e5Spatrick #define	splsoft()	splraise(IPL_SOFT)
115f24071e5Spatrick #define	splsoftclock()	splraise(IPL_SOFTCLOCK)
116f24071e5Spatrick #define	splsoftnet()	splraise(IPL_SOFTNET)
117f24071e5Spatrick #define	splsofttty()	splraise(IPL_SOFTTTY)
118f24071e5Spatrick #define	splbio()	splraise(IPL_BIO)
119f24071e5Spatrick #define	splnet()	splraise(IPL_NET)
120f24071e5Spatrick #define	spltty()	splraise(IPL_TTY)
121f24071e5Spatrick #define	splvm()		splraise(IPL_VM)
122f24071e5Spatrick #define	splaudio()	splraise(IPL_AUDIO)
123f24071e5Spatrick #define	splclock()	splraise(IPL_CLOCK)
124f24071e5Spatrick #define	splsched()	splraise(IPL_SCHED)
125f24071e5Spatrick #define	splstatclock()	splraise(IPL_STATCLOCK)
126f24071e5Spatrick #define	splhigh()	splraise(IPL_HIGH)
127f24071e5Spatrick 
128f24071e5Spatrick #define	spl0()		spllower(IPL_NONE)
129f24071e5Spatrick 
130f24071e5Spatrick void	 intr_barrier(void *);
1315dee5702Skettenis void	 intr_set_wakeup(void *);
1325dee5702Skettenis void	 intr_enable_wakeup(void);
1335dee5702Skettenis void	 intr_disable_wakeup(void);
134f24071e5Spatrick 
135f24071e5Spatrick void	 arm_init_smask(void); /* XXX */
136f24071e5Spatrick extern uint32_t arm_smask[NIPL];
137f24071e5Spatrick 
138f24071e5Spatrick #include <machine/softintr.h>
139f24071e5Spatrick 
140f24071e5Spatrick /* XXX - this is probably the wrong location for this */
141f24071e5Spatrick void arm_clock_register(void (*)(void), void (*)(u_int), void (*)(int),
142f24071e5Spatrick     void (*)(void));
143f24071e5Spatrick 
14435efb9b8Skettenis struct cpu_info;
14535efb9b8Skettenis 
146f24071e5Spatrick struct interrupt_controller {
147f24071e5Spatrick 	int	ic_node;
148f24071e5Spatrick 	void	*ic_cookie;
149789e88a4Spatrick 	void	*(*ic_establish)(void *, int *, int, struct cpu_info *,
150bc127a3bSpatrick 		    int (*)(void *), void *, char *);
151789e88a4Spatrick 	void	*(*ic_establish_msi)(void *, uint64_t *, uint64_t *, int,
152789e88a4Spatrick 		    struct cpu_info *, int (*)(void *), void *, char *);
153f24071e5Spatrick 	void	 (*ic_disestablish)(void *);
154575c38b7Spatrick 	void	 (*ic_enable)(void *);
155575c38b7Spatrick 	void	 (*ic_disable)(void *);
15635efb9b8Skettenis 	void	 (*ic_route)(void *, int, struct cpu_info *);
157d7e3db9cSkettenis 	void	 (*ic_cpu_enable)(void);
158452daaedSpatrick 	void	 (*ic_barrier)(void *);
1595dee5702Skettenis 	void	 (*ic_set_wakeup)(void *);
160f24071e5Spatrick 
161f24071e5Spatrick 	LIST_ENTRY(interrupt_controller) ic_list;
162f24071e5Spatrick 	uint32_t ic_phandle;
163f24071e5Spatrick 	uint32_t ic_cells;
164550856c9Sjmatthew 	uint32_t ic_gic_its_id;
165f24071e5Spatrick };
166f24071e5Spatrick 
167f24071e5Spatrick void	 arm_intr_init_fdt(void);
168f24071e5Spatrick void	 arm_intr_register_fdt(struct interrupt_controller *);
169f24071e5Spatrick void	*arm_intr_establish_fdt(int, int, int (*)(void *),
170f24071e5Spatrick 	    void *, char *);
171789e88a4Spatrick void	*arm_intr_establish_fdt_cpu(int, int, struct cpu_info *,
172789e88a4Spatrick 	    int (*)(void *), void *, char *);
173f24071e5Spatrick void	*arm_intr_establish_fdt_idx(int, int, int, int (*)(void *),
174f24071e5Spatrick 	    void *, char *);
175789e88a4Spatrick void	*arm_intr_establish_fdt_idx_cpu(int, int, int, struct cpu_info *,
176789e88a4Spatrick 	    int (*)(void *), void *, char *);
1773dd5c381Skettenis void	*arm_intr_establish_fdt_imap(int, int *, int, int, int (*)(void *),
1781895f9aeSpatrick 	    void *, char *);
179789e88a4Spatrick void	*arm_intr_establish_fdt_imap_cpu(int, int *, int, int,
180789e88a4Spatrick 	    struct cpu_info *, int (*)(void *), void *, char *);
181bc127a3bSpatrick void	*arm_intr_establish_fdt_msi(int, uint64_t *, uint64_t *, int,
182bc127a3bSpatrick 	    int (*)(void *), void *, char *);
183789e88a4Spatrick void	*arm_intr_establish_fdt_msi_cpu(int, uint64_t *, uint64_t *, int,
184789e88a4Spatrick 	    struct cpu_info *, int (*)(void *), void *, char *);
185f24071e5Spatrick void	 arm_intr_disestablish_fdt(void *);
186575c38b7Spatrick void	 arm_intr_enable(void *);
187575c38b7Spatrick void	 arm_intr_disable(void *);
18835efb9b8Skettenis void	 arm_intr_route(void *, int, struct cpu_info *);
189d7e3db9cSkettenis void	 arm_intr_cpu_enable(void);
190f24071e5Spatrick void	*arm_intr_parent_establish_fdt(void *, int *, int,
191789e88a4Spatrick 	    struct cpu_info *ci, int (*)(void *), void *, char *);
192f24071e5Spatrick void	 arm_intr_parent_disestablish_fdt(void *);
193f24071e5Spatrick 
19470943fa6Skettenis void	 arm_send_ipi(struct cpu_info *, int);
19570943fa6Skettenis extern void (*intr_send_ipi_func)(struct cpu_info *, int);
19670943fa6Skettenis 
19770943fa6Skettenis #define ARM_IPI_NOP	0
19870943fa6Skettenis #define ARM_IPI_DDB	1
1994002e08dSkettenis #define ARM_IPI_HALT	2
20070943fa6Skettenis 
201f24071e5Spatrick #ifdef DIAGNOSTIC
202f24071e5Spatrick /*
203f24071e5Spatrick  * Although this function is implemented in MI code, it must be in this MD
204f24071e5Spatrick  * header because we don't want this header to include MI includes.
205f24071e5Spatrick  */
206f24071e5Spatrick void splassert_fail(int, int, const char *);
207f24071e5Spatrick extern int splassert_ctl;
208f24071e5Spatrick void arm_splassert_check(int, const char *);
209f24071e5Spatrick #define splassert(__wantipl) do {				\
210f24071e5Spatrick 	if (splassert_ctl > 0) {				\
211f24071e5Spatrick 		arm_splassert_check(__wantipl, __func__);	\
212f24071e5Spatrick 	}							\
213f24071e5Spatrick } while (0)
214f24071e5Spatrick #define	splsoftassert(wantipl)	splassert(wantipl)
215f24071e5Spatrick #else
216f24071e5Spatrick #define	splassert(wantipl)	do { /* nothing */ } while (0)
217f24071e5Spatrick #define	splsoftassert(wantipl)	do { /* nothing */ } while (0)
218f24071e5Spatrick #endif
219f24071e5Spatrick 
220f24071e5Spatrick #endif /* ! _LOCORE */
221f24071e5Spatrick 
222f24071e5Spatrick #endif /* _KERNEL */
223f24071e5Spatrick 
224f24071e5Spatrick #endif	/* _MACHINE_INTR_H_ */
225f24071e5Spatrick 
226