KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
irq.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 include/kos/irq.h
4 Copyright (C) 2000, 2001 Megan Potter
5 Copyright (C) 2024, 2025 Paul Cercueil
6 Copyright (C) 2024, 2025 Falco Girgis
7*/
8
9/** \file kos/irq.h
10 \brief Timer functionality.
11 \ingroup interrupts
12
13 This file contains functions for enabling/disabling interrupts, and
14 setting interrupt handlers.
15
16 \author Megan Potter
17 \author Paul Cercueil
18 \author Falco Girgis
19*/
20#ifndef __KOS_IRQ_H
21#define __KOS_IRQ_H
22
23#include <sys/cdefs.h>
24__BEGIN_DECLS
25
26#include <stdbool.h>
27#include <stdint.h>
28
29/** \cond INTERNAL */
30struct irq_context;
31#ifdef __cplusplus
32enum irq_exception: unsigned int;
33#else
34enum irq_exception;
35#endif
36/** \endcond */
37
38/** Architecture-specific structure for holding the processor state.
39
40 This structure should hold register values and other important parts of the
41 processor state.
42*/
43typedef struct irq_context irq_context_t;
44
45/** Architecture-specific interrupt exception codes
46
47 Used to identify the source or type of an interrupt.
48*/
49typedef enum irq_exception irq_t;
50
51/** Type representing an interrupt mask state. */
52typedef uint32_t irq_mask_t;
53
54/** The type of an IRQ handler.
55
56 \param code The IRQ that caused the handler to be called.
57 \param context The CPU's context.
58 \param data Arbitrary userdata associated with the handler.
59*/
60typedef void (*irq_hdl_t)(irq_t code, irq_context_t *context, void *data);
61
62
63/** The type of a full callback of an IRQ handler and userdata.
64
65 This type is used to set or get IRQ handlers and their data.
66*/
67typedef struct irq_cb {
68 irq_hdl_t hdl; /**< A pointer to a procedure to handle an exception. */
69 void *data; /**< A pointer that will be passed along to the callback. */
70} irq_cb_t;
71
72/* Keep this include after the type declarations */
73#include <arch/irq.h>
74
75/** \defgroup irq_state IRQ state handling
76 \brief API for handling IRQ state
77
78 The following functions can be used to disable or enable interrupts, restore
79 a previously saved interrupt state, or query whether or not the calling
80 function is running in an interrupt context.
81
82 @{
83*/
84
85/** Enable all interrupts.
86
87 This function will enable ALL interrupts, including external ones.
88
89 \sa irq_disable()
90*/
91static inline void irq_enable(void) {
92 arch_irq_enable();
93}
94
95/** Disable interrupts.
96
97 This function will disable interrupts (not exceptions).
98
99 \return An opaque token containing the interrupt state.
100 It should be passed to irq_restore() in order to
101 restore the previous interrupt state.
102
103 \sa irq_restore(), irq_enable()
104*/
105static inline irq_mask_t irq_disable(void) {
106 return arch_irq_disable();
107}
108
109/** Restore interrupt state.
110
111 This function will restore the interrupt state to the value specified. This
112 should correspond to a value returned by irq_disable().
113
114 \param state The IRQ state to restore. This should be a value
115 returned by irq_disable().
116
117 \sa irq_disable()
118*/
119static inline void irq_restore(irq_mask_t state) {
120 arch_irq_restore(state);
121}
122
123/** \brief Disable interrupts with scope management.
124
125 This macro will disable interrupts, similarly to irq_disable(), with the
126 difference that the interrupt state will automatically be restored once the
127 execution exits the functional block in which the macro was called.
128*/
129#define irq_disable_scoped() __irq_disable_scoped(__LINE__)
130
131/** Returns whether inside of an interrupt context.
132
133 \retval non-zero If inside an interrupt handler.
134 \retval 0 If normal processing is in progress.
135
136*/
137static inline bool irq_inside_int(void) {
138 return arch_irq_inside_int();
139}
140
141/** @} */
142
143/** \defgroup irq_context IRQ context handling
144 \brief API for handling IRQ contexts
145
146 This API provides functions to create a new IRQ context, get a pointer to
147 the current context, or set the context that will be used when returning
148 from an exception.
149
150 @{
151*/
152
153/** Fill a newly allocated context block.
154
155 The given parameters will be passed to the called routine (up to the
156 architecture maximum). For the Dreamcast, this maximum is 4.
157
158 \param context The IRQ context to fill in.
159 \param stack_pointer The value to set in the stack pointer.
160 \param routine The address of the program counter for the context.
161 \param args Any arguments to set in the registers. This cannot
162 be NULL, and must have enough values to fill in up
163 to the architecture maximum.
164*/
165static inline void irq_create_context(irq_context_t *context,
166 uintptr_t stack_pointer,
167 uintptr_t routine,
168 const uintptr_t *args) {
169 arch_irq_create_context(context, stack_pointer, routine, args);
170}
171
172/** Switch out contexts (for interrupt return).
173
174 This function will set the processor state that will be restored when the
175 exception returns.
176
177 \param cxt The IRQ context to restore.
178
179 \sa irq_get_context()
180*/
181static inline void irq_set_context(irq_context_t *cxt) {
182 arch_irq_set_context(cxt);
183}
184
185/** Get the current IRQ context.
186
187 This will fetch the processor context prior to the exception handling during
188 an IRQ service routine.
189
190 \return The current IRQ context.
191
192 \sa irq_set_context()
193*/
194static inline irq_context_t *irq_get_context(void) {
195 return arch_irq_get_context();
196}
197
198/** @} */
199
200/** \defgroup irq_handlers Handlers
201 \brief API for managing IRQ handlers
202
203 This API provides a series of methods for registering and retrieving
204 different types of exception handlers.
205
206 @{
207*/
208
209/** Set or remove an IRQ handler.
210
211 Passing a NULL value for hnd will remove the current handler, if any.
212
213 \param code The IRQ type to set the handler for
214 (see #irq_t).
215 \param hnd A pointer to a procedure to handle the exception.
216 \param data A pointer that will be passed along to the callback.
217
218 \retval 0 On success.
219 \retval -1 If the code is invalid.
220
221 \sa irq_get_handler()
222*/
223static inline int irq_set_handler(irq_t code, irq_hdl_t hnd, void *data) {
224 return arch_irq_set_handler(code, hnd, data);
225}
226
227/** Get the address of the current handler for the IRQ type.
228
229 \param code The IRQ type to look up.
230
231 \return The current handler for the IRQ type and
232 its userdata.
233
234 \sa irq_set_handler()
235*/
236static inline irq_cb_t irq_get_handler(irq_t code) {
237 return arch_irq_get_handler(code);
238}
239
240/** Set a global exception handler.
241
242 This function sets a global catch-all filter for all exception types.
243
244 \note The specific handler will still be called for the
245 exception if one is set. If not, setting one of
246 these will stop the unhandled exception error.
247
248 \param hnd A pointer to the procedure to handle the exception.
249 \param data A pointer that will be passed along to the callback.
250
251 \retval 0 On success (no error conditions defined).
252
253*/
254static inline int irq_set_global_handler(irq_hdl_t hnd, void *data) {
255 return arch_irq_set_global_handler(hnd, data);
256}
257
258/** Get the global exception handler.
259
260 \return The global exception handler and userdata set with
261 irq_set_global_handler(), or NULL if none is set.
262*/
263static inline irq_cb_t irq_get_global_handler(void) {
264 return arch_irq_get_global_handler();
265}
266
267/** @} */
268
269/** \cond INTERNAL */
270
271/** Initialize interrupts.
272
273 \retval 0 On success (no error conditions defined).
274
275 \sa irq_shutdown()
276*/
277int irq_init(void);
278
279/** Shutdown interrupts.
280
281 Restores the state to how it was before irq_init() was called.
282
283 \sa irq_init()
284*/
285void irq_shutdown(void);
286
287static inline void __irq_scoped_cleanup(irq_mask_t *state) {
288 irq_restore(*state);
289}
290
291#define ___irq_disable_scoped(l) \
292 irq_mask_t __scoped_irq_##l __attribute__((cleanup(__irq_scoped_cleanup))) = irq_disable()
293
294#define __irq_disable_scoped(l) ___irq_disable_scoped(l)
295/** \endcond */
296
297__END_DECLS
298
299#endif /* __KOS_IRQ_H */
void hnd(const char *file, int line, const char *expr, const char *msg, const char *func)
Definition asserthnd.c:53
static struct @69 data[BARRIER_COUNT]
static pvr_poly_cxt_t cxt
Definition bubbles.c:28
static irq_context_t * irq_get_context(void)
Get the current IRQ context.
Definition irq.h:194
static void irq_create_context(irq_context_t *context, uintptr_t stack_pointer, uintptr_t routine, const uintptr_t *args)
Fill a newly allocated context block.
Definition irq.h:165
static void irq_set_context(irq_context_t *cxt)
Switch out contexts (for interrupt return).
Definition irq.h:181
static irq_cb_t irq_get_handler(irq_t code)
Get the address of the current handler for the IRQ type.
Definition irq.h:236
static irq_cb_t irq_get_global_handler(void)
Get the global exception handler.
Definition irq.h:263
static int irq_set_global_handler(irq_hdl_t hnd, void *data)
Set a global exception handler.
Definition irq.h:254
static int irq_set_handler(irq_t code, irq_hdl_t hnd, void *data)
Set or remove an IRQ handler.
Definition irq.h:223
static void irq_enable(void)
Enable all interrupts.
Definition irq.h:91
static irq_mask_t irq_disable(void)
Disable interrupts.
Definition irq.h:105
static void irq_restore(irq_mask_t state)
Restore interrupt state.
Definition irq.h:119
static bool irq_inside_int(void)
Returns whether inside of an interrupt context.
Definition irq.h:137
enum irq_exception irq_t
Architecture-specific interrupt exception codes.
Definition irq.h:49
struct irq_context irq_context_t
Architecture-specific structure for holding the processor state.
Definition irq.h:43
uint32_t irq_mask_t
Type representing an interrupt mask state.
Definition irq.h:52
void(* irq_hdl_t)(irq_t code, irq_context_t *context, void *data)
The type of an IRQ handler.
Definition irq.h:60
Interrupt and exception handling.
The type of a full callback of an IRQ handler and userdata.
Definition irq.h:67
void * data
A pointer that will be passed along to the callback.
Definition irq.h:69
irq_hdl_t hdl
A pointer to a procedure to handle an exception.
Definition irq.h:68