1 /* Copyright 2018 SiFive, Inc */
2 /* SPDX-License-Identifier: Apache-2.0 */
4 #ifndef METAL__INTERRUPT_H
5 #define METAL__INTERRUPT_H
8 * @brief API for registering and manipulating interrupts
14 * @brief Possible mode of interrupts to operate
16 typedef enum metal_vector_mode_ {
17 METAL_DIRECT_MODE = 0,
18 METAL_VECTOR_MODE = 1,
19 METAL_SELECTIVE_VECTOR_MODE = 2,
20 METAL_HARDWARE_VECTOR_MODE = 3
24 * @brief Function signature for interrupt callback handlers
26 typedef void (*metal_interrupt_handler_t) (int, void *);
28 struct metal_interrupt;
30 struct metal_interrupt_vtable {
31 void (*interrupt_init)(struct metal_interrupt *controller);
32 int (*interrupt_register)(struct metal_interrupt *controller, int id,
33 metal_interrupt_handler_t isr, void *priv_data);
34 int (*interrupt_enable)(struct metal_interrupt *controller, int id);
35 int (*interrupt_disable)(struct metal_interrupt *controller, int id);
36 int (*interrupt_vector_enable)(struct metal_interrupt *controller,
37 int id, metal_vector_mode mode);
38 int (*interrupt_vector_disable)(struct metal_interrupt *controller, int id);
39 int (*command_request)(struct metal_interrupt *controller, int cmd, void *data);
40 int (*mtimecmp_set)(struct metal_interrupt *controller, int hartid, unsigned long long time);
44 * @brief A handle for an interrupt
46 struct metal_interrupt {
47 const struct metal_interrupt_vtable *vtable;
51 * @brief Initialize a given interrupt controller
53 * Initialize a given interrupt controller. This function must be called
54 * before any interrupts are registered or enabled with the handler. It
55 * is invalid to initialize an interrupt controller more than once.
57 * @param controller The handle for the interrupt controller
59 inline void metal_interrupt_init(struct metal_interrupt *controller)
61 return controller->vtable->interrupt_init(controller);
66 * @brief Register an interrupt handler
67 * @param controller The handle for the interrupt controller
68 * @param id The interrupt ID to register
69 * @param handler The interrupt handler callback
70 * @param priv_data Private data for the interrupt handler
71 * @return 0 upon success
73 inline int metal_interrupt_register_handler(struct metal_interrupt *controller,
75 metal_interrupt_handler_t handler,
78 return controller->vtable->interrupt_register(controller, id, handler, priv_data);
82 * @brief Enable an interrupt
83 * @param controller The handle for the interrupt controller
84 * @param id The interrupt ID to enable
85 * @return 0 upon success
87 inline int metal_interrupt_enable(struct metal_interrupt *controller, int id)
89 return controller->vtable->interrupt_enable(controller, id);
93 * @brief Disable an interrupt
94 * @param controller The handle for the interrupt controller
95 * @param id The interrupt ID to disable
96 * @return 0 upon success
98 inline int metal_interrupt_disable(struct metal_interrupt *controller, int id)
100 return controller->vtable->interrupt_disable(controller, id);
104 * @brief Enable an interrupt vector
105 * @param controller The handle for the interrupt controller
106 * @param id The interrupt ID to enable
107 * @param mode The interrupt mode type to enable
108 * @return 0 upon success
110 inline int metal_interrupt_vector_enable(struct metal_interrupt *controller,
111 int id, metal_vector_mode mode)
113 return controller->vtable->interrupt_vector_enable(controller, id, mode);
117 * @brief Disable an interrupt vector
118 * @param controller The handle for the interrupt controller
119 * @param id The interrupt ID to disable
120 * @return 0 upon success
122 inline int metal_interrupt_vector_disable(struct metal_interrupt *controller, int id)
124 return controller->vtable->interrupt_vector_disable(controller, id);
127 /* Utilities function to controll, manages devices via a given interrupt controller */
128 inline int _metal_interrupt_command_request(struct metal_interrupt *controller,
131 return controller->vtable->command_request(controller, cmd, data);