]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/interrupt.h
Update RISCC-V-RV32-SiFive_HiFive1_FreedomStudio project to latest tools and metal...
[freertos] / FreeRTOS / Demo / RISC-V_RV32_SiFive_HiFive1_FreedomStudio / freedom-metal / metal / interrupt.h
1 /* Copyright 2018 SiFive, Inc */
2 /* SPDX-License-Identifier: Apache-2.0 */
3
4 #ifndef METAL__INTERRUPT_H
5 #define METAL__INTERRUPT_H
6
7 /*! @file interrupt.h
8  *  @brief API for registering and manipulating interrupts
9  */
10
11 #include <stddef.h>
12
13 /*!
14  * @brief Possible interrupt controllers
15  */
16 typedef enum metal_interrupt_controller_ {
17     METAL_CPU_CONTROLLER = 0,
18     METAL_CLINT_CONTROLLER = 1,
19     METAL_CLIC_CONTROLLER = 2,
20     METAL_PLIC_CONTROLLER = 3
21 } metal_intr_cntrl_type;
22
23 /*!
24  * @brief Possible mode of interrupts to operate
25  */
26 typedef enum metal_vector_mode_ {
27     METAL_DIRECT_MODE = 0,
28     METAL_VECTOR_MODE = 1,
29     METAL_SELECTIVE_NONVECTOR_MODE = 2,
30     METAL_SELECTIVE_VECTOR_MODE = 3,
31     METAL_HARDWARE_VECTOR_MODE = 4
32 } metal_vector_mode;
33
34 /*!
35  * @brief Possible mode of privilege interrupts to operate
36  */
37 typedef enum metal_intr_priv_mode_ {
38     METAL_INTR_PRIV_M_MODE = 0,
39     METAL_INTR_PRIV_MU_MODE = 1,
40     METAL_INTR_PRIV_MSU_MODE = 2
41 } metal_intr_priv_mode;
42
43 /*!
44  * @brief Function signature for interrupt callback handlers
45  */
46 typedef void (*metal_interrupt_handler_t) (int, void *);
47 typedef void (*metal_interrupt_vector_handler_t) (void);
48
49 struct metal_interrupt;
50
51 struct metal_interrupt_vtable {
52     void (*interrupt_init)(struct metal_interrupt *controller);
53     int (*interrupt_set_vector_mode)(struct metal_interrupt *controller, metal_vector_mode mode);
54     metal_vector_mode (*interrupt_get_vector_mode)(struct metal_interrupt *controller);
55     int (*interrupt_set_privilege)(struct metal_interrupt *controller, metal_intr_priv_mode priv);
56     metal_intr_priv_mode (*interrupt_get_privilege)(struct metal_interrupt *controller);
57     int (*interrupt_clear)(struct metal_interrupt *controller, int id);
58     int (*interrupt_set)(struct metal_interrupt *controller, int id);
59     int (*interrupt_register)(struct metal_interrupt *controller, int id,
60                               metal_interrupt_handler_t isr, void *priv_data);
61     int (*interrupt_vector_register)(struct metal_interrupt *controller, int id,
62                               metal_interrupt_vector_handler_t isr, void *priv_data);
63     int (*interrupt_enable)(struct metal_interrupt *controller, int id);
64     int (*interrupt_disable)(struct metal_interrupt *controller, int id);
65     int (*interrupt_vector_enable)(struct metal_interrupt *controller, int id);
66     int (*interrupt_vector_disable)(struct metal_interrupt *controller, int id);
67     unsigned int (*interrupt_get_threshold)(struct metal_interrupt *controller);
68     int (*interrupt_set_threshold)(struct metal_interrupt *controller, unsigned int threshold);
69     unsigned int (*interrupt_get_priority)(struct metal_interrupt *controller, int id);
70     int (*interrupt_set_priority)(struct metal_interrupt *controller, int id, unsigned int priority);
71     int (*command_request)(struct metal_interrupt *controller, int cmd, void *data);
72     int (*mtimecmp_set)(struct metal_interrupt *controller, int hartid, unsigned long long time);
73 };
74
75 /*!
76  * @brief A handle for an interrupt
77  */
78 struct metal_interrupt {
79     const struct metal_interrupt_vtable *vtable;
80 };
81
82 /*!
83  * @brief Initialize a given interrupt controller
84  *
85  * Initialize a given interrupt controller. This function must be called
86  * before any interrupts are registered or enabled with the handler. It
87  * is invalid to initialize an interrupt controller more than once.
88  *
89  * @param controller The handle for the interrupt controller
90  */
91 __inline__ void metal_interrupt_init(struct metal_interrupt *controller)
92 {
93     controller->vtable->interrupt_init(controller);
94 }
95
96 /*!
97  * @brief Get the handle for an given interrupt controller type
98  * @param cntrl The type ofinterrupt controller
99  * @param id The instance of the interrupt controller
100  * @return A handle to the interrupt controller (CLINT, CLIC, PLIC), or
101  * NULL if none is found for the requested label
102  */
103 struct metal_interrupt* metal_interrupt_get_controller(metal_intr_cntrl_type cntrl,
104                                                        int id);
105
106 /*!
107  * @brief Configure vector mode for an interrupt controller
108  *
109  * Configure vector mode for an interrupt controller.
110  * This function must be called after initialization and before
111  * configuring individual interrupts, registering ISR.
112  *
113  * @param controller The handle for the interrupt controller
114  * @param mode The vector mode of the interrupt controller.
115  * @return 0 upon success
116  */
117 __inline__ int metal_interrupt_set_vector_mode(struct metal_interrupt *controller,
118                                                metal_vector_mode mode)
119 {
120     return controller->vtable->interrupt_set_vector_mode(controller, mode);
121 }
122
123 /*!
124  * @brief Get vector mode of a given an interrupt controller
125  *
126  * Configure vector mode for an interrupt controller.
127  * This function must be called after initialization and before
128  * configuring individual interrupts, registering ISR.
129  *
130  * @param controller The handle for the interrupt controller
131  * @param mode The vector mode of the interrupt controller.
132  * @return The interrupt vector mode
133  */
134 __inline__ metal_vector_mode metal_interrupt_get_vector_mode(struct metal_interrupt *controller)
135 {
136     return controller->vtable->interrupt_get_vector_mode(controller);
137 }
138
139 /*!
140  * @brief Configure privilege mode a of given interrupt controller
141  *
142  * Configure privilege mode for a given interrupt controller.
143  * This function must be called after initialization and before
144  * configuring individual interrupts, registering ISR.
145  *
146  * @param controller The handle for the interrupt controller
147  * @param privilege The privilege mode of the interrupt controller.
148  * @return 0 upon success
149  */
150 __inline__ int metal_interrupt_set_privilege(struct metal_interrupt *controller,
151                                              metal_intr_priv_mode privilege)
152 {
153     return controller->vtable->interrupt_set_privilege(controller, privilege);
154 }
155
156 /*!
157  * @brief Get privilege mode a of given interrupt controller
158  *
159  * Get privilege mode for a given interrupt controller.
160  * This function must be called after initialization and before
161  * configuring individual interrupts, registering ISR.
162  *
163  * @param controller The handle for the interrupt controller
164  * @return The interrupt privilege mode
165  */
166 __inline__ metal_intr_priv_mode metal_interrupt_get_privilege(struct metal_interrupt *controller)
167 {
168     return controller->vtable->interrupt_get_privilege(controller);
169 }
170
171 /*!
172  * @brief clear an interrupt
173  * @param controller The handle for the interrupt controller
174  * @param id The interrupt ID to trigger
175  * @return 0 upon success
176  */
177 __inline__ int metal_interrupt_clear(struct metal_interrupt *controller, int id)
178 {
179     return controller->vtable->interrupt_clear(controller, id);
180 }                                         
181
182 /*!
183  * @brief Set an interrupt
184  * @param controller The handle for the interrupt controller
185  * @param id The interrupt ID to trigger
186  * @return 0 upon success
187  */
188 __inline__ int metal_interrupt_set(struct metal_interrupt *controller, int id)
189 {
190     return controller->vtable->interrupt_set(controller, id);
191 }
192
193 /*!
194  * @brief Register an interrupt handler
195  * @param controller The handle for the interrupt controller
196  * @param id The interrupt ID to register
197  * @param handler The interrupt handler callback
198  * @param priv_data Private data for the interrupt handler
199  * @return 0 upon success
200  */
201 __inline__ int metal_interrupt_register_handler(struct metal_interrupt *controller,
202                                           int id,
203                                           metal_interrupt_handler_t handler,
204                                           void *priv_data)
205 {
206     return controller->vtable->interrupt_register(controller, id, handler, priv_data);
207 }
208
209 /*!
210  * @brief Register an interrupt vector handler
211  * @param controller The handle for the interrupt controller
212  * @param id The interrupt ID to register
213  * @param handler The interrupt vector handler callback
214  * @param priv_data Private data for the interrupt handler
215  * @return 0 upon success
216  */
217 __inline__ int metal_interrupt_register_vector_handler(struct metal_interrupt *controller,
218                                           int id,
219                                           metal_interrupt_vector_handler_t handler,
220                                           void *priv_data)
221 {
222     return controller->vtable->interrupt_vector_register(controller, id, handler, priv_data);
223 }
224
225 /*!
226  * @brief Enable an interrupt
227  * @param controller The handle for the interrupt controller
228  * @param id The interrupt ID to enable
229  * @return 0 upon success
230  */
231 __inline__ int metal_interrupt_enable(struct metal_interrupt *controller, int id)
232 {
233     return controller->vtable->interrupt_enable(controller, id);
234 }
235
236 /*!
237  * @brief Disable an interrupt
238  * @param controller The handle for the interrupt controller
239  * @param id The interrupt ID to disable
240  * @return 0 upon success
241  */
242 __inline__ int metal_interrupt_disable(struct metal_interrupt *controller, int id)
243 {
244     return controller->vtable->interrupt_disable(controller, id);
245 }
246
247 /*!
248  * @brief Set interrupt threshold level
249  * @param controller The handle for the interrupt controller
250  * @param threshold The interrupt threshold level
251  * @return 0 upon success
252  */
253 inline int metal_interrupt_set_threshold(struct metal_interrupt *controller, unsigned int level)
254 {
255     return controller->vtable->interrupt_set_threshold(controller, level);
256 }
257
258 /*!
259  * @brief Get an interrupt threshold level
260  * @param controller The handle for the interrupt controller
261  * @return The interrupt threshold level
262  */
263 inline unsigned int metal_interrupt_get_threshold(struct metal_interrupt *controller)
264 {
265   return controller->vtable->interrupt_get_threshold(controller);
266 }
267
268 /*!
269  * @brief Set an interrupt priority level
270  * @param controller The handle for the interrupt controller
271  * @param id The interrupt ID to enable
272  * @param priority The interrupt priority level
273  * @return 0 upon success
274  */
275 inline int metal_interrupt_set_priority(struct metal_interrupt *controller,
276                                         int id, unsigned int priority)
277 {
278     return controller->vtable->interrupt_set_priority(controller, id, priority);
279 }
280
281 /*!
282  * @brief Get an interrupt priority level
283  * @param controller The handle for the interrupt controller
284  * @param id The interrupt ID to enable
285  * @return The interrupt priority level
286  */
287 inline unsigned int metal_interrupt_get_priority(struct metal_interrupt *controller, int id)
288 {
289   return controller->vtable->interrupt_get_priority(controller, id);
290 }
291
292 /*!
293  * @brief Enable an interrupt vector
294  * @param controller The handle for the interrupt controller
295  * @param id The interrupt ID to enable
296  * @return 0 upon success
297  */
298 __inline__ int metal_interrupt_vector_enable(struct metal_interrupt *controller, int id)
299 {
300     return controller->vtable->interrupt_vector_enable(controller, id);
301 }
302
303 /*!
304  * @brief Disable an interrupt vector
305  * @param controller The handle for the interrupt controller
306  * @param id The interrupt ID to disable
307  * @return 0 upon success
308  */
309 __inline__ int metal_interrupt_vector_disable(struct metal_interrupt *controller, int id)
310 {
311     return controller->vtable->interrupt_vector_disable(controller, id);
312 }
313
314 /*!
315  * @brief Default interrupt vector handler, that can be overriden by user
316  * @param None
317  * @return None
318  */
319 void __attribute__((weak, interrupt)) metal_interrupt_vector_handler(void);
320
321 /*!
322  * @brief Metal Software interrupt vector handler, that can be overriden by user
323  * @param None
324  * @return None
325  */
326 void __attribute__((weak, interrupt)) metal_software_interrupt_vector_handler(void);
327
328 /*!
329  * @brief Metal Timer interrupt vector handler, that can be overriden by user
330  * @param None
331  * @return None
332  */
333 void __attribute__((weak, interrupt)) metal_timer_interrupt_vector_handler(void);
334
335 /*!
336  * @brief Metal External interrupt vector handler, that can be overriden by user
337  * @param None
338  * @return None
339  */
340 void __attribute__((weak, interrupt)) metal_external_interrupt_vector_handler(void);
341
342 /*!
343  * @brief Metal Local 0 interrupt vector handler, that can be overriden by user
344  * @param None
345  * @return None
346  */
347 void __attribute__((weak, interrupt)) metal_lc0_interrupt_vector_handler(void);
348
349 /*!
350  * @brief Metal Local 1 interrupt vector handler, that can be overriden by user
351  * @param None
352  * @return None
353  */
354 void __attribute__((weak, interrupt)) metal_lc1_interrupt_vector_handler(void);
355
356 /*!
357  * @brief Metal Local 2 interrupt vector handler, that can be overriden by user
358  * @param None
359  * @return None
360  */
361 void __attribute__((weak, interrupt)) metal_lc2_interrupt_vector_handler(void);
362
363 /*!
364  * @brief Metal Local 3 interrupt vector handler, that can be overriden by user
365  * @param None
366  * @return None
367  */
368 void __attribute__((weak, interrupt)) metal_lc3_interrupt_vector_handler(void);
369
370 /*!
371  * @brief Metal Local 4 interrupt vector handler, that can be overriden by user
372  * @param None
373  * @return None
374  */
375 void __attribute__((weak, interrupt)) metal_lc4_interrupt_vector_handler(void);
376
377 /*!
378  * @brief Metal Local 5 interrupt vector handler, that can be overriden by user
379  * @param None
380  * @return None
381  */
382 void __attribute__((weak, interrupt)) metal_lc5_interrupt_vector_handler(void);
383
384 /*!
385  * @brief Metal Local 6 interrupt vector handler, that can be overriden by user
386  * @param None
387  * @return None
388  */
389 void __attribute__((weak, interrupt)) metal_lc6_interrupt_vector_handler(void);
390     
391 /*!
392  * @brief Metal Local 7 interrupt vector handler, that can be overriden by user
393  * @param None
394  * @return None
395  */
396 void __attribute__((weak, interrupt)) metal_lc7_interrupt_vector_handler(void);
397
398 /*!
399  * @brief Metal Local 8 interrupt vector handler, that can be overriden by user
400  * @param None
401  * @return None
402  */
403 void __attribute__((weak, interrupt)) metal_lc8_interrupt_vector_handler(void);
404
405 /*!
406  * @brief Metal Local 9 interrupt vector handler, that can be overriden by user
407  * @param None
408  * @return None
409  */
410 void __attribute__((weak, interrupt)) metal_lc9_interrupt_vector_handler(void);
411
412 /*!
413  * @brief Metal Local 10 interrupt vector handler, that can be overriden by user
414  * @param None
415  * @return None
416  */
417 void __attribute__((weak, interrupt)) metal_lc10_interrupt_vector_handler(void);
418
419 /*!
420  * @brief Metal Local 11 interrupt vector handler, that can be overriden by user
421  * @param None
422  * @return None
423  */
424 void __attribute__((weak, interrupt)) metal_lc11_interrupt_vector_handler(void);
425
426 /*!
427  * @brief Metal Local 12 interrupt vector handler, that can be overriden by user
428  * @param None
429  * @return None
430  */
431 void __attribute__((weak, interrupt)) metal_lc12_interrupt_vector_handler(void);
432
433 /*!
434  * @brief Metal Local 13 interrupt vector handler, that can be overriden by user
435  * @param None
436  * @return None
437  */
438 void __attribute__((weak, interrupt)) metal_lc13_interrupt_vector_handler(void);
439
440 /*!
441  * @brief Metal Local 14 interrupt vector handler, that can be overriden by user
442  * @param None
443  * @return None
444  */
445 void __attribute__((weak, interrupt)) metal_lc14_interrupt_vector_handler(void);
446
447 /*!
448  * @brief Metal Local 15 interrupt vector handler, that can be overriden by user
449  * @param None
450  * @return None
451  */
452 void __attribute__((weak, interrupt)) metal_lc15_interrupt_vector_handler(void);
453
454 /* Utilities function to controll, manages devices via a given interrupt controller */
455 __inline__ int _metal_interrupt_command_request(struct metal_interrupt *controller,
456                                          int cmd, void *data)
457 {
458     return controller->vtable->command_request(controller, cmd, data);
459 }
460
461 #endif