interrupt.h 15 KB

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