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