plic.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. /* Copyright 2018 Canaan Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. /**
  16. * @file
  17. * @brief The PLIC complies with the RISC-V Privileged Architecture
  18. * specification, and can support a maximum of 1023 external
  19. * interrupt sources targeting up to 15,872 core contexts.
  20. *
  21. * @note PLIC RAM Layout
  22. *
  23. * | Address | Description |
  24. * |-----------|---------------------------------|
  25. * |0x0C000000 | Reserved |
  26. * |0x0C000004 | source 1 priority |
  27. * |0x0C000008 | source 2 priority |
  28. * |... | ... |
  29. * |0x0C000FFC | source 1023 priority |
  30. * | | |
  31. * |0x0C001000 | Start of pending array |
  32. * |... | (read-only) |
  33. * |0x0C00107C | End of pending array |
  34. * |0x0C001080 | Reserved |
  35. * |... | ... |
  36. * |0x0C001FFF | Reserved |
  37. * | | |
  38. * |0x0C002000 | target 0 enables |
  39. * |0x0C002080 | target 1 enables |
  40. * |... | ... |
  41. * |0x0C1F1F80 | target 15871 enables |
  42. * |0x0C1F2000 | Reserved |
  43. * |... | ... |
  44. * |0x0C1FFFFC | Reserved |
  45. * | | |
  46. * |0x0C200000 | target 0 priority threshold |
  47. * |0x0C200004 | target 0 claim/complete |
  48. * |... | ... |
  49. * |0x0C201000 | target 1 priority threshold |
  50. * |0x0C201004 | target 1 claim/complete |
  51. * |... | ... |
  52. * |0x0FFFF000 | target 15871 priority threshold |
  53. * |0x0FFFF004 | target 15871 claim/complete |
  54. *
  55. */
  56. #ifndef _DRIVER_PLIC_H
  57. #define _DRIVER_PLIC_H
  58. #include <stdint.h>
  59. #include "encoding.h"
  60. #include "platform.h"
  61. /* For c++ compatibility */
  62. #ifdef __cplusplus
  63. extern "C" {
  64. #endif
  65. /* clang-format off */
  66. /* IRQ number settings */
  67. #define PLIC_NUM_SOURCES (IRQN_MAX - 1)
  68. #define PLIC_NUM_PRIORITIES (7)
  69. /* Real number of cores */
  70. #define PLIC_NUM_CORES (2)
  71. /* clang-format on */
  72. /**
  73. * @brief PLIC External Interrupt Numbers
  74. *
  75. * @note PLIC interrupt sources
  76. *
  77. * | Source | Name | Description |
  78. * |--------|--------------------------|------------------------------------|
  79. * | 0 | IRQN_NO_INTERRUPT | The non-existent interrupt |
  80. * | 1 | IRQN_SPI0_INTERRUPT | SPI0 interrupt |
  81. * | 2 | IRQN_SPI1_INTERRUPT | SPI1 interrupt |
  82. * | 3 | IRQN_SPI_SLAVE_INTERRUPT | SPI_SLAVE interrupt |
  83. * | 4 | IRQN_SPI3_INTERRUPT | SPI3 interrupt |
  84. * | 5 | IRQN_I2S0_INTERRUPT | I2S0 interrupt |
  85. * | 6 | IRQN_I2S1_INTERRUPT | I2S1 interrupt |
  86. * | 7 | IRQN_I2S2_INTERRUPT | I2S2 interrupt |
  87. * | 8 | IRQN_I2C0_INTERRUPT | I2C0 interrupt |
  88. * | 9 | IRQN_I2C1_INTERRUPT | I2C1 interrupt |
  89. * | 10 | IRQN_I2C2_INTERRUPT | I2C2 interrupt |
  90. * | 11 | IRQN_UART1_INTERRUPT | UART1 interrupt |
  91. * | 12 | IRQN_UART2_INTERRUPT | UART2 interrupt |
  92. * | 13 | IRQN_UART3_INTERRUPT | UART3 interrupt |
  93. * | 14 | IRQN_TIMER0A_INTERRUPT | TIMER0 channel 0 or 1 interrupt |
  94. * | 15 | IRQN_TIMER0B_INTERRUPT | TIMER0 channel 2 or 3 interrupt |
  95. * | 16 | IRQN_TIMER1A_INTERRUPT | TIMER1 channel 0 or 1 interrupt |
  96. * | 17 | IRQN_TIMER1B_INTERRUPT | TIMER1 channel 2 or 3 interrupt |
  97. * | 18 | IRQN_TIMER2A_INTERRUPT | TIMER2 channel 0 or 1 interrupt |
  98. * | 19 | IRQN_TIMER2B_INTERRUPT | TIMER2 channel 2 or 3 interrupt |
  99. * | 20 | IRQN_RTC_INTERRUPT | RTC tick and alarm interrupt |
  100. * | 21 | IRQN_WDT0_INTERRUPT | Watching dog timer0 interrupt |
  101. * | 22 | IRQN_WDT1_INTERRUPT | Watching dog timer1 interrupt |
  102. * | 23 | IRQN_APB_GPIO_INTERRUPT | APB GPIO interrupt |
  103. * | 24 | IRQN_DVP_INTERRUPT | Digital video port interrupt |
  104. * | 25 | IRQN_AI_INTERRUPT | AI accelerator interrupt |
  105. * | 26 | IRQN_FFT_INTERRUPT | FFT accelerator interrupt |
  106. * | 27 | IRQN_DMA0_INTERRUPT | DMA channel0 interrupt |
  107. * | 28 | IRQN_DMA1_INTERRUPT | DMA channel1 interrupt |
  108. * | 29 | IRQN_DMA2_INTERRUPT | DMA channel2 interrupt |
  109. * | 30 | IRQN_DMA3_INTERRUPT | DMA channel3 interrupt |
  110. * | 31 | IRQN_DMA4_INTERRUPT | DMA channel4 interrupt |
  111. * | 32 | IRQN_DMA5_INTERRUPT | DMA channel5 interrupt |
  112. * | 33 | IRQN_UARTHS_INTERRUPT | Hi-speed UART0 interrupt |
  113. * | 34 | IRQN_GPIOHS0_INTERRUPT | Hi-speed GPIO0 interrupt |
  114. * | 35 | IRQN_GPIOHS1_INTERRUPT | Hi-speed GPIO1 interrupt |
  115. * | 36 | IRQN_GPIOHS2_INTERRUPT | Hi-speed GPIO2 interrupt |
  116. * | 37 | IRQN_GPIOHS3_INTERRUPT | Hi-speed GPIO3 interrupt |
  117. * | 38 | IRQN_GPIOHS4_INTERRUPT | Hi-speed GPIO4 interrupt |
  118. * | 39 | IRQN_GPIOHS5_INTERRUPT | Hi-speed GPIO5 interrupt |
  119. * | 40 | IRQN_GPIOHS6_INTERRUPT | Hi-speed GPIO6 interrupt |
  120. * | 41 | IRQN_GPIOHS7_INTERRUPT | Hi-speed GPIO7 interrupt |
  121. * | 42 | IRQN_GPIOHS8_INTERRUPT | Hi-speed GPIO8 interrupt |
  122. * | 43 | IRQN_GPIOHS9_INTERRUPT | Hi-speed GPIO9 interrupt |
  123. * | 44 | IRQN_GPIOHS10_INTERRUPT | Hi-speed GPIO10 interrupt |
  124. * | 45 | IRQN_GPIOHS11_INTERRUPT | Hi-speed GPIO11 interrupt |
  125. * | 46 | IRQN_GPIOHS12_INTERRUPT | Hi-speed GPIO12 interrupt |
  126. * | 47 | IRQN_GPIOHS13_INTERRUPT | Hi-speed GPIO13 interrupt |
  127. * | 48 | IRQN_GPIOHS14_INTERRUPT | Hi-speed GPIO14 interrupt |
  128. * | 49 | IRQN_GPIOHS15_INTERRUPT | Hi-speed GPIO15 interrupt |
  129. * | 50 | IRQN_GPIOHS16_INTERRUPT | Hi-speed GPIO16 interrupt |
  130. * | 51 | IRQN_GPIOHS17_INTERRUPT | Hi-speed GPIO17 interrupt |
  131. * | 52 | IRQN_GPIOHS18_INTERRUPT | Hi-speed GPIO18 interrupt |
  132. * | 53 | IRQN_GPIOHS19_INTERRUPT | Hi-speed GPIO19 interrupt |
  133. * | 54 | IRQN_GPIOHS20_INTERRUPT | Hi-speed GPIO20 interrupt |
  134. * | 55 | IRQN_GPIOHS21_INTERRUPT | Hi-speed GPIO21 interrupt |
  135. * | 56 | IRQN_GPIOHS22_INTERRUPT | Hi-speed GPIO22 interrupt |
  136. * | 57 | IRQN_GPIOHS23_INTERRUPT | Hi-speed GPIO23 interrupt |
  137. * | 58 | IRQN_GPIOHS24_INTERRUPT | Hi-speed GPIO24 interrupt |
  138. * | 59 | IRQN_GPIOHS25_INTERRUPT | Hi-speed GPIO25 interrupt |
  139. * | 60 | IRQN_GPIOHS26_INTERRUPT | Hi-speed GPIO26 interrupt |
  140. * | 61 | IRQN_GPIOHS27_INTERRUPT | Hi-speed GPIO27 interrupt |
  141. * | 62 | IRQN_GPIOHS28_INTERRUPT | Hi-speed GPIO28 interrupt |
  142. * | 63 | IRQN_GPIOHS29_INTERRUPT | Hi-speed GPIO29 interrupt |
  143. * | 64 | IRQN_GPIOHS30_INTERRUPT | Hi-speed GPIO30 interrupt |
  144. * | 65 | IRQN_GPIOHS31_INTERRUPT | Hi-speed GPIO31 interrupt |
  145. *
  146. */
  147. /* clang-format off */
  148. typedef enum _plic_irq
  149. {
  150. IRQN_NO_INTERRUPT = 0, /*!< The non-existent interrupt */
  151. IRQN_SPI0_INTERRUPT = 1, /*!< SPI0 interrupt */
  152. IRQN_SPI1_INTERRUPT = 2, /*!< SPI1 interrupt */
  153. IRQN_SPI_SLAVE_INTERRUPT = 3, /*!< SPI_SLAVE interrupt */
  154. IRQN_SPI3_INTERRUPT = 4, /*!< SPI3 interrupt */
  155. IRQN_I2S0_INTERRUPT = 5, /*!< I2S0 interrupt */
  156. IRQN_I2S1_INTERRUPT = 6, /*!< I2S1 interrupt */
  157. IRQN_I2S2_INTERRUPT = 7, /*!< I2S2 interrupt */
  158. IRQN_I2C0_INTERRUPT = 8, /*!< I2C0 interrupt */
  159. IRQN_I2C1_INTERRUPT = 9, /*!< I2C1 interrupt */
  160. IRQN_I2C2_INTERRUPT = 10, /*!< I2C2 interrupt */
  161. IRQN_UART1_INTERRUPT = 11, /*!< UART1 interrupt */
  162. IRQN_UART2_INTERRUPT = 12, /*!< UART2 interrupt */
  163. IRQN_UART3_INTERRUPT = 13, /*!< UART3 interrupt */
  164. IRQN_TIMER0A_INTERRUPT = 14, /*!< TIMER0 channel 0 or 1 interrupt */
  165. IRQN_TIMER0B_INTERRUPT = 15, /*!< TIMER0 channel 2 or 3 interrupt */
  166. IRQN_TIMER1A_INTERRUPT = 16, /*!< TIMER1 channel 0 or 1 interrupt */
  167. IRQN_TIMER1B_INTERRUPT = 17, /*!< TIMER1 channel 2 or 3 interrupt */
  168. IRQN_TIMER2A_INTERRUPT = 18, /*!< TIMER2 channel 0 or 1 interrupt */
  169. IRQN_TIMER2B_INTERRUPT = 19, /*!< TIMER2 channel 2 or 3 interrupt */
  170. IRQN_RTC_INTERRUPT = 20, /*!< RTC tick and alarm interrupt */
  171. IRQN_WDT0_INTERRUPT = 21, /*!< Watching dog timer0 interrupt */
  172. IRQN_WDT1_INTERRUPT = 22, /*!< Watching dog timer1 interrupt */
  173. IRQN_APB_GPIO_INTERRUPT = 23, /*!< APB GPIO interrupt */
  174. IRQN_DVP_INTERRUPT = 24, /*!< Digital video port interrupt */
  175. IRQN_AI_INTERRUPT = 25, /*!< AI accelerator interrupt */
  176. IRQN_FFT_INTERRUPT = 26, /*!< FFT accelerator interrupt */
  177. IRQN_DMA0_INTERRUPT = 27, /*!< DMA channel0 interrupt */
  178. IRQN_DMA1_INTERRUPT = 28, /*!< DMA channel1 interrupt */
  179. IRQN_DMA2_INTERRUPT = 29, /*!< DMA channel2 interrupt */
  180. IRQN_DMA3_INTERRUPT = 30, /*!< DMA channel3 interrupt */
  181. IRQN_DMA4_INTERRUPT = 31, /*!< DMA channel4 interrupt */
  182. IRQN_DMA5_INTERRUPT = 32, /*!< DMA channel5 interrupt */
  183. IRQN_UARTHS_INTERRUPT = 33, /*!< Hi-speed UART0 interrupt */
  184. IRQN_GPIOHS0_INTERRUPT = 34, /*!< Hi-speed GPIO0 interrupt */
  185. IRQN_GPIOHS1_INTERRUPT = 35, /*!< Hi-speed GPIO1 interrupt */
  186. IRQN_GPIOHS2_INTERRUPT = 36, /*!< Hi-speed GPIO2 interrupt */
  187. IRQN_GPIOHS3_INTERRUPT = 37, /*!< Hi-speed GPIO3 interrupt */
  188. IRQN_GPIOHS4_INTERRUPT = 38, /*!< Hi-speed GPIO4 interrupt */
  189. IRQN_GPIOHS5_INTERRUPT = 39, /*!< Hi-speed GPIO5 interrupt */
  190. IRQN_GPIOHS6_INTERRUPT = 40, /*!< Hi-speed GPIO6 interrupt */
  191. IRQN_GPIOHS7_INTERRUPT = 41, /*!< Hi-speed GPIO7 interrupt */
  192. IRQN_GPIOHS8_INTERRUPT = 42, /*!< Hi-speed GPIO8 interrupt */
  193. IRQN_GPIOHS9_INTERRUPT = 43, /*!< Hi-speed GPIO9 interrupt */
  194. IRQN_GPIOHS10_INTERRUPT = 44, /*!< Hi-speed GPIO10 interrupt */
  195. IRQN_GPIOHS11_INTERRUPT = 45, /*!< Hi-speed GPIO11 interrupt */
  196. IRQN_GPIOHS12_INTERRUPT = 46, /*!< Hi-speed GPIO12 interrupt */
  197. IRQN_GPIOHS13_INTERRUPT = 47, /*!< Hi-speed GPIO13 interrupt */
  198. IRQN_GPIOHS14_INTERRUPT = 48, /*!< Hi-speed GPIO14 interrupt */
  199. IRQN_GPIOHS15_INTERRUPT = 49, /*!< Hi-speed GPIO15 interrupt */
  200. IRQN_GPIOHS16_INTERRUPT = 50, /*!< Hi-speed GPIO16 interrupt */
  201. IRQN_GPIOHS17_INTERRUPT = 51, /*!< Hi-speed GPIO17 interrupt */
  202. IRQN_GPIOHS18_INTERRUPT = 52, /*!< Hi-speed GPIO18 interrupt */
  203. IRQN_GPIOHS19_INTERRUPT = 53, /*!< Hi-speed GPIO19 interrupt */
  204. IRQN_GPIOHS20_INTERRUPT = 54, /*!< Hi-speed GPIO20 interrupt */
  205. IRQN_GPIOHS21_INTERRUPT = 55, /*!< Hi-speed GPIO21 interrupt */
  206. IRQN_GPIOHS22_INTERRUPT = 56, /*!< Hi-speed GPIO22 interrupt */
  207. IRQN_GPIOHS23_INTERRUPT = 57, /*!< Hi-speed GPIO23 interrupt */
  208. IRQN_GPIOHS24_INTERRUPT = 58, /*!< Hi-speed GPIO24 interrupt */
  209. IRQN_GPIOHS25_INTERRUPT = 59, /*!< Hi-speed GPIO25 interrupt */
  210. IRQN_GPIOHS26_INTERRUPT = 60, /*!< Hi-speed GPIO26 interrupt */
  211. IRQN_GPIOHS27_INTERRUPT = 61, /*!< Hi-speed GPIO27 interrupt */
  212. IRQN_GPIOHS28_INTERRUPT = 62, /*!< Hi-speed GPIO28 interrupt */
  213. IRQN_GPIOHS29_INTERRUPT = 63, /*!< Hi-speed GPIO29 interrupt */
  214. IRQN_GPIOHS30_INTERRUPT = 64, /*!< Hi-speed GPIO30 interrupt */
  215. IRQN_GPIOHS31_INTERRUPT = 65, /*!< Hi-speed GPIO31 interrupt */
  216. IRQN_MAX
  217. } plic_irq_t;
  218. /* clang-format on */
  219. /**
  220. * @brief Interrupt Source Priorities
  221. *
  222. * Each external interrupt source can be assigned a priority by
  223. * writing to its 32-bit memory-mapped priority register. The
  224. * number and value of supported priority levels can vary by
  225. * implementa- tion, with the simplest implementations having all
  226. * devices hardwired at priority 1, in which case, interrupts with
  227. * the lowest ID have the highest effective priority. The priority
  228. * registers are all WARL.
  229. */
  230. typedef struct _plic_source_priorities
  231. {
  232. /* 0x0C000000: Reserved, 0x0C000004-0x0C000FFC: 1-1023 priorities */
  233. uint32_t priority[1024];
  234. } __attribute__((packed, aligned(4))) plic_source_priorities_t;
  235. /**
  236. * @brief Interrupt Pending Bits
  237. *
  238. * The current status of the interrupt source pending bits in the
  239. * PLIC core can be read from the pending array, organized as 32
  240. * words of 32 bits. The pending bit for interrupt ID N is stored
  241. * in bit (N mod 32) of word (N/32). Bit 0 of word 0, which
  242. * represents the non-existent interrupt source 0, is always
  243. * hardwired to zero. The pending bits are read-only. A pending
  244. * bit in the PLIC core can be cleared by setting enable bits to
  245. * only enable the desired interrupt, then performing a claim. A
  246. * pending bit can be set by instructing the associated gateway to
  247. * send an interrupt service request.
  248. */
  249. typedef struct _plic_pending_bits
  250. {
  251. /* 0x0C001000-0x0C00107C: Bit 0 is zero, Bits 1-1023 is pending bits */
  252. uint32_t u32[32];
  253. /* 0x0C001080-0x0C001FFF: Reserved */
  254. uint8_t resv[0xF80];
  255. } __attribute__((packed, aligned(4))) plic_pending_bits_t;
  256. /**
  257. * @brief Target Interrupt Enables
  258. *
  259. * For each interrupt target, each device’s interrupt can be
  260. * enabled by setting the corresponding bit in that target’s
  261. * enables registers. The enables for a target are accessed as a
  262. * contiguous array of 32×32-bit words, packed the same way as the
  263. * pending bits. For each target, bit 0 of enable word 0
  264. * represents the non-existent interrupt ID 0 and is hardwired to
  265. * 0. Unused interrupt IDs are also hardwired to zero. The enables
  266. * arrays for different targets are packed contiguously in the
  267. * address space. Only 32-bit word accesses are supported by the
  268. * enables array in RV32 systems. Implementations can trap on
  269. * accesses to enables for non-existent targets, but must allow
  270. * access to the full enables array for any extant target,
  271. * treating all non-existent interrupt source’s enables as
  272. * hardwired to zero.
  273. */
  274. typedef struct _plic_target_enables
  275. {
  276. /* 0x0C002000-0x0C1F1F80: target 0-15871 enables */
  277. struct
  278. {
  279. uint32_t enable[32 * 2]; /* Offset 0x00-0x7C: Bit 0 is zero, Bits 1-1023 is bits*/
  280. } target[15872 / 2];
  281. /* 0x0C1F2000-0x0C1FFFFC: Reserved, size 0xE000 */
  282. uint8_t resv[0xE000];
  283. } __attribute__((packed, aligned(4))) plic_target_enables_t;
  284. /**
  285. * @brief PLIC Targets
  286. *
  287. * Target Priority Thresholds The threshold for a pending
  288. * interrupt priority that can interrupt each target can be set in
  289. * the target’s threshold register. The threshold is a WARL field,
  290. * where different implementations can support different numbers
  291. * of thresholds. The simplest implementation has a threshold
  292. * hardwired to zero.
  293. *
  294. * Target Claim Each target can perform a claim by reading the
  295. * claim/complete register, which returns the ID of the highest
  296. * priority pending interrupt or zero if there is no pending
  297. * interrupt for the target. A successful claim will also
  298. * atomically clear the corresponding pending bit on the interrupt
  299. * source. A target can perform a claim at any time, even if the
  300. * EIP is not set. The claim operation is not affected by the
  301. * setting of the target’s priority threshold register.
  302. *
  303. * Target Completion A target signals it has completed running a
  304. * handler by writing the interrupt ID it received from the claim
  305. * to the claim/complete register. This is routed to the
  306. * corresponding interrupt gateway, which can now send another
  307. * interrupt request to the PLIC. The PLIC does not check whether
  308. * the completion ID is the same as the last claim ID for that
  309. * target. If the completion ID does not match an interrupt source
  310. * that is currently enabled for the target, the completion is
  311. * silently ignored.
  312. */
  313. typedef struct _plic_target
  314. {
  315. /* 0x0C200000-0x0FFFF004: target 0-15871 */
  316. struct
  317. {
  318. uint32_t priority_threshold; /* Offset 0x000 */
  319. uint32_t claim_complete; /* Offset 0x004 */
  320. uint8_t resv[0x1FF8]; /* Offset 0x008, Size 0xFF8 */
  321. } target[15872 / 2];
  322. } __attribute__((packed, aligned(4))) plic_target_t;
  323. /**
  324. * @brief Platform-Level Interrupt Controller
  325. *
  326. * PLIC is Platform-Level Interrupt Controller. The PLIC complies
  327. * with the RISC-V Privileged Architecture specification, and can
  328. * support a maximum of 1023 external interrupt sources targeting
  329. * up to 15,872 core contexts.
  330. */
  331. typedef struct _plic
  332. {
  333. /* 0x0C000000-0x0C000FFC */
  334. plic_source_priorities_t source_priorities;
  335. /* 0x0C001000-0x0C001FFF */
  336. const plic_pending_bits_t pending_bits;
  337. /* 0x0C002000-0x0C1FFFFC */
  338. plic_target_enables_t target_enables;
  339. /* 0x0C200000-0x0FFFF004 */
  340. plic_target_t targets;
  341. } __attribute__((packed, aligned(4))) plic_t;
  342. extern volatile plic_t *const plic;
  343. /**
  344. * @brief Definitions for the interrupt callbacks
  345. */
  346. typedef int (*plic_irq_callback_t)(void *ctx);
  347. /**
  348. * @brief Definitions for IRQ table instance
  349. */
  350. typedef struct _plic_instance_t
  351. {
  352. plic_irq_callback_t callback;
  353. void *ctx;
  354. } plic_instance_t;
  355. typedef struct _plic_callback_t
  356. {
  357. plic_irq_callback_t callback;
  358. void *ctx;
  359. uint32_t priority;
  360. } plic_interrupt_t;
  361. /**
  362. * @brief Initialize PLIC external interrupt
  363. *
  364. * @note This function will set MIP_MEIP. The MSTATUS_MIE must set by user.
  365. *
  366. * @return result
  367. * - 0 Success
  368. * - Other Fail
  369. */
  370. void plic_init(void);
  371. /**
  372. * @brief Enable PLIC external interrupt
  373. *
  374. * @param[in] irq_number external interrupt number
  375. *
  376. * @return result
  377. * - 0 Success
  378. * - Other Fail
  379. */
  380. int plic_irq_enable(plic_irq_t irq_number);
  381. /**
  382. * @brief Disable PLIC external interrupt
  383. *
  384. * @param[in] irq_number The external interrupt number
  385. *
  386. * @return result
  387. * - 0 Success
  388. * - Other Fail
  389. */
  390. int plic_irq_disable(plic_irq_t irq_number);
  391. /**
  392. * @brief Set IRQ priority
  393. *
  394. * @param[in] irq_number The external interrupt number
  395. * @param[in] priority The priority of external interrupt number
  396. *
  397. * @return result
  398. * - 0 Success
  399. * - Other Fail
  400. */
  401. int plic_set_priority(plic_irq_t irq_number, uint32_t priority);
  402. /**
  403. * @brief Get IRQ priority
  404. *
  405. * @param[in] irq_number The external interrupt number
  406. *
  407. * @return The priority of external interrupt number
  408. */
  409. uint32_t plic_get_priority(plic_irq_t irq_number);
  410. /**
  411. * @brief Claim an IRQ
  412. *
  413. * @return The current IRQ number
  414. */
  415. uint32_t plic_irq_claim(void);
  416. /**
  417. * @brief Complete an IRQ
  418. *
  419. * @param[in] source The source IRQ number to complete
  420. *
  421. * @return result
  422. * - 0 Success
  423. * - Other Fail
  424. */
  425. int plic_irq_complete(uint32_t source);
  426. /**
  427. * @brief Register user callback function by IRQ number
  428. *
  429. * @param[in] irq The irq
  430. * @param[in] callback The callback
  431. * @param ctx The context
  432. *
  433. * @return result
  434. * - 0 Success
  435. * - Other Fail
  436. */
  437. void plic_irq_register(plic_irq_t irq, plic_irq_callback_t callback, void *ctx);
  438. /**
  439. * @brief Deegister user callback function by IRQ number
  440. *
  441. * @param[in] irq The irq
  442. *
  443. * @return result
  444. * - 0 Success
  445. * - Other Fail
  446. */
  447. void plic_irq_deregister(plic_irq_t irq);
  448. /**
  449. * @brief Deegister user callback function by IRQ number
  450. *
  451. * @param[in] irq The irq
  452. *
  453. * @return result
  454. * - 0 Success
  455. * - Other Fail
  456. */
  457. void plic_irq_unregister(plic_irq_t irq);
  458. /**
  459. * @brief Get IRQ table, Usage:
  460. * plic_instance_t (*plic_instance)[IRQN_MAX] = plic_get_instance();
  461. * ... plic_instance[x][y] ...;
  462. *
  463. * @return the point of IRQ table
  464. */
  465. plic_instance_t (*plic_get_instance(void))[IRQN_MAX];
  466. /* For c++ compatibility */
  467. #ifdef __cplusplus
  468. }
  469. #endif
  470. #endif /* _DRIVER_PLIC_H */