clint.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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 CLINT block holds memory-mapped control and status registers
  18. * associated with local interrupts for a Coreplex.
  19. *
  20. * @note CLINT RAM Layout
  21. *
  22. * | Address -| Description |
  23. * |------------|---------------------------------|
  24. * | 0x02000000 | msip for core 0 |
  25. * | 0x02000004 | msip for core 1 |
  26. * | ... | ... |
  27. * | 0x02003FF8 | msip for core 4094 |
  28. * | | |
  29. * | 0x02004000 | mtimecmp for core 0 |
  30. * | 0x02004008 | mtimecmp for core 1 |
  31. * | ... | ... |
  32. * | 0x0200BFF0 | mtimecmp For core 4094 |
  33. * | 0x0200BFF8 | mtime |
  34. * | | |
  35. * | 0x0200C000 | Reserved |
  36. * | ... | ... |
  37. * | 0x0200EFFC | Reserved |
  38. */
  39. #ifndef _DRIVER_CLINT_H
  40. #define _DRIVER_CLINT_H
  41. #include <stddef.h>
  42. #include <stdint.h>
  43. #include "platform.h"
  44. #ifdef __cplusplus
  45. extern "C" {
  46. #endif
  47. /* clang-format off */
  48. /* Register address offsets */
  49. #define CLINT_MSIP (0x0000)
  50. #define CLINT_MSIP_SIZE (0x4)
  51. #define CLINT_MTIMECMP (0x4000)
  52. #define CLINT_MTIMECMP_SIZE (0x8)
  53. #define CLINT_MTIME (0xBFF8)
  54. #define CLINT_MTIME_SIZE (0x8)
  55. /* Max number of cores */
  56. #define CLINT_MAX_CORES (4095)
  57. /* Real number of cores */
  58. #define CLINT_NUM_CORES (2)
  59. /* Clock frequency division factor */
  60. #define CLINT_CLOCK_DIV (50)
  61. /* clang-format on */
  62. /**
  63. * @brief MSIP Registers
  64. *
  65. * Machine-mode software interrupts are generated by writing to a
  66. * per-core memory-mapped control register. The msip registers are
  67. * 32-bit wide WARL registers, where the LSB is reflected in the
  68. * msip bit of the associated core’s mip register. Other bits in
  69. * the msip registers are hardwired to zero. The mapping supports
  70. * up to 4095 machine-mode cores.
  71. */
  72. typedef struct _clint_msip
  73. {
  74. uint32_t msip : 1; /*!< Bit 0 is msip */
  75. uint32_t zero : 31; /*!< Bits [32:1] is 0 */
  76. } __attribute__((packed, aligned(4))) clint_msip_t;
  77. /**
  78. * @brief Timer compare Registers Machine-mode timer interrupts are
  79. * generated by a real-time counter and a per-core comparator. The
  80. * mtime register is a 64-bit read-only register that contains the
  81. * current value of the real-time counter. Each mtimecmp register
  82. * holds its core’s time comparator. A timer interrupt is pending
  83. * whenever mtime is greater than or equal to the value in a
  84. * core’s mtimecmp register. The timer interrupt is reflected in
  85. * the mtip bit of the associated core’s mip register.
  86. */
  87. typedef uint64_t clint_mtimecmp_t;
  88. /**
  89. * @brief Timer Registers
  90. *
  91. * The mtime register has a 64-bit precision on all RV32, RV64,
  92. * and RV128 systems. Platforms provide a 64-bit memory-mapped
  93. * machine-mode timer compare register (mtimecmp), which causes a
  94. * timer interrupt to be posted when the mtime register contains a
  95. * value greater than or equal to the value in the mtimecmp
  96. * register. The interrupt remains posted until it is cleared by
  97. * writing the mtimecmp register. The interrupt will only be taken
  98. * if interrupts are enabled and the MTIE bit is set in the mie
  99. * register.
  100. */
  101. typedef uint64_t clint_mtime_t;
  102. /**
  103. * @brief CLINT object
  104. *
  105. * Coreplex-Local INTerrupts, which includes software interrupts,
  106. * local timer interrupts, and other interrupts routed directly to
  107. * a core.
  108. */
  109. typedef struct _clint
  110. {
  111. /* 0x0000 to 0x3FF8, MSIP Registers */
  112. clint_msip_t msip[CLINT_MAX_CORES];
  113. /* Resverd space, do not use */
  114. uint32_t resv0;
  115. /* 0x4000 to 0xBFF0, Timer Compare Registers */
  116. clint_mtimecmp_t mtimecmp[CLINT_MAX_CORES];
  117. /* 0xBFF8, Time Register */
  118. clint_mtime_t mtime;
  119. } __attribute__((packed, aligned(4))) clint_t;
  120. /**
  121. * @brief Clint object instanse
  122. */
  123. extern volatile clint_t *const clint;
  124. /**
  125. * @brief Definitions for the timer callbacks
  126. */
  127. typedef int (*clint_timer_callback_t)(void *ctx);
  128. /**
  129. * @brief Definitions for local interprocessor interrupt callbacks
  130. */
  131. typedef int (*clint_ipi_callback_t)(void *ctx);
  132. typedef struct _clint_timer_instance
  133. {
  134. uint64_t interval;
  135. uint64_t cycles;
  136. uint64_t single_shot;
  137. clint_timer_callback_t callback;
  138. void *ctx;
  139. } clint_timer_instance_t;
  140. typedef struct _clint_ipi_instance
  141. {
  142. clint_ipi_callback_t callback;
  143. void *ctx;
  144. } clint_ipi_instance_t;
  145. /**
  146. * @brief Get the time form CLINT timer register
  147. *
  148. * @note The CLINT must init to get right time
  149. *
  150. * @return 64bit Time
  151. */
  152. uint64_t clint_get_time(void);
  153. /**
  154. * @brief Init the CLINT timer
  155. *
  156. * @note MIP_MTIP will be clear after init. The MSTATUS_MIE must set by
  157. * user.
  158. *
  159. * @return result
  160. * - 0 Success
  161. * - Other Fail
  162. */
  163. int clint_timer_init(void);
  164. /**
  165. * @brief Stop the CLINT timer
  166. *
  167. * @note MIP_MTIP will be clear after stop
  168. *
  169. * @return result
  170. * - 0 Success
  171. * - Other Fail
  172. */
  173. int clint_timer_stop(void);
  174. /**
  175. * @brief Start the CLINT timer
  176. *
  177. * @param[in] interval The interval with Millisecond(ms)
  178. * @param[in] single_shot Single shot or repeat
  179. *
  180. * @return result
  181. * - 0 Success
  182. * - Other Fail
  183. */
  184. int clint_timer_start(uint64_t interval, int single_shot);
  185. /**
  186. * @brief Get the interval of timer
  187. *
  188. * @return The interval with Millisecond(ms)
  189. */
  190. uint64_t clint_timer_get_interval(void);
  191. /**
  192. * @brief Set the interval with Millisecond(ms)
  193. *
  194. * @param[in] interval The interval with Millisecond(ms)
  195. *
  196. * @return result
  197. * - 0 Success
  198. * - Other Fail
  199. */
  200. int clint_timer_set_interval(uint64_t interval);
  201. /**
  202. * @brief Get whether the timer is a single shot timer
  203. *
  204. * @return result
  205. * - 0 It is a repeat timer
  206. * - 1 It is a single shot timer
  207. */
  208. int clint_timer_get_single_shot(void);
  209. /**
  210. * @brief Set the timer working as a single shot timer or repeat timer
  211. *
  212. * @param[in] single_shot Single shot or repeat
  213. *
  214. * @return result
  215. * - 0 Success
  216. * - Other Fail
  217. */
  218. int clint_timer_set_single_shot(int single_shot);
  219. /**
  220. * @brief Set user callback function when timer is timeout
  221. *
  222. * @param[in] callback The callback function
  223. * @param[in] ctx The context
  224. *
  225. * @return result
  226. * - 0 Success
  227. * - Other Fail
  228. */
  229. int clint_timer_register(clint_timer_callback_t callback, void *ctx);
  230. /**
  231. * @brief Deregister user callback function
  232. *
  233. * @return result
  234. * - 0 Success
  235. * - Other Fail
  236. */
  237. int clint_timer_unregister(void);
  238. /**
  239. * @brief Initialize local interprocessor interrupt
  240. *
  241. * @return result
  242. * - 0 Success
  243. * - Other Fail
  244. */
  245. int clint_ipi_init(void);
  246. /**
  247. * @brief Enable local interprocessor interrupt
  248. *
  249. * @return result
  250. * - 0 Success
  251. * - Other Fail
  252. */
  253. int clint_ipi_enable(void);
  254. /**
  255. * @brief Disable local interprocessor interrupt
  256. *
  257. * @return result
  258. * - 0 Success
  259. * - Other Fail
  260. */
  261. int clint_ipi_disable(void);
  262. /**
  263. * @brief Send local interprocessor interrupt to core by core id
  264. *
  265. * @param[in] core_id The core identifier
  266. *
  267. * @return result
  268. * - 0 Success
  269. * - Other Fail
  270. */
  271. int clint_ipi_send(size_t core_id);
  272. /**
  273. * @brief Clear local interprocessor interrupt
  274. *
  275. * @param[in] core_id The core identifier
  276. *
  277. * @return result
  278. * - 1 An IPI was pending
  279. * - 0 Non IPI was pending
  280. * - -1 Fail
  281. */
  282. int clint_ipi_clear(size_t core_id);
  283. /**
  284. * @brief Set user callback function when interprocessor interrupt
  285. *
  286. * @param[in] callback The callback function
  287. * @param[in] ctx The context
  288. *
  289. * @return result
  290. * - 0 Success
  291. * - Other Fail
  292. */
  293. int clint_ipi_register(clint_ipi_callback_t callback, void *ctx);
  294. /**
  295. * @brief Deregister user callback function
  296. *
  297. * @return result
  298. * - 0 Success
  299. * - Other Fail
  300. */
  301. int clint_ipi_unregister(void);
  302. #ifdef __cplusplus
  303. }
  304. #endif
  305. #endif /* _DRIVER_CLINT_H */