hpm_plic_drv.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright (c) 2021 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_PLIC_DRV_H
  8. #define HPM_PLIC_DRV_H
  9. /**
  10. * @brief PLIC driver APIs
  11. * @defgroup plic_interface PLIC driver APIs
  12. * @{
  13. */
  14. #define HPM_PLIC_TARGET_M_MODE 0
  15. #define HPM_PLIC_TARGET_S_MODE 1
  16. /* Feature Register */
  17. #define HPM_PLIC_FEATURE_OFFSET (0x00000000UL)
  18. #define HPM_PLIC_FEATURE_VECTORED_MODE (0x2UL)
  19. #define HPM_PLIC_FEATURE_PREEMPTIVE_PRIORITY_IRQ (0x1UL)
  20. /* Priority Register - 32 bits per irq */
  21. #define HPM_PLIC_PRIORITY_OFFSET (0x00000004UL)
  22. #define HPM_PLIC_PRIORITY_SHIFT_PER_SOURCE 2
  23. /* Pending Register - 1 bit per source */
  24. #define HPM_PLIC_PENDING_OFFSET (0x00001000UL)
  25. #define HPM_PLIC_PENDING_SHIFT_PER_SOURCE 0
  26. /* Enable Register - 0x80 per target */
  27. #define HPM_PLIC_ENABLE_OFFSET (0x00002000UL)
  28. #define HPM_PLIC_ENABLE_SHIFT_PER_TARGET 7
  29. /* Priority Threshold Register - 0x1000 per target */
  30. #define HPM_PLIC_THRESHOLD_OFFSET (0x00200000UL)
  31. #define HPM_PLIC_THRESHOLD_SHIFT_PER_TARGET 12
  32. /* Claim Register - 0x1000 per target */
  33. #define HPM_PLIC_CLAIM_OFFSET (0x00200004UL)
  34. #define HPM_PLIC_CLAIM_SHIFT_PER_TARGET 12
  35. #if !defined(__ASSEMBLER__)
  36. /**
  37. * @brief Set plic feature
  38. *
  39. * @param[in] base PLIC base address
  40. * @param[in] feature Specific feature to be set
  41. *
  42. */
  43. ATTR_ALWAYS_INLINE static inline void __plic_set_feature(uint32_t base, uint32_t feature)
  44. {
  45. *(volatile uint32_t *)(base + HPM_PLIC_FEATURE_OFFSET) = feature;
  46. }
  47. /**
  48. * @brief Set plic threshold
  49. *
  50. * @param[in] base PLIC base address
  51. * @param[in] target Target to handle specific interrupt
  52. * @param[in] threshold Threshold of IRQ can be serviced
  53. *
  54. */
  55. ATTR_ALWAYS_INLINE static inline void __plic_set_threshold(uint32_t base,
  56. uint32_t target,
  57. uint32_t threshold)
  58. {
  59. volatile uint32_t *threshold_ptr = (volatile uint32_t *)(base +
  60. HPM_PLIC_THRESHOLD_OFFSET +
  61. (target << HPM_PLIC_THRESHOLD_SHIFT_PER_TARGET));
  62. *threshold_ptr = threshold;
  63. }
  64. /**
  65. * @brief Set interrupt priority
  66. *
  67. * @param[in] base PLIC base address
  68. * @param[in] irq Target interrupt number
  69. * @param[in] priority Priority to be assigned
  70. *
  71. */
  72. ATTR_ALWAYS_INLINE static inline void __plic_set_irq_priority(uint32_t base,
  73. uint32_t irq,
  74. uint32_t priority)
  75. {
  76. volatile uint32_t *priority_ptr = (volatile uint32_t *)(base +
  77. HPM_PLIC_PRIORITY_OFFSET + ((irq-1) << HPM_PLIC_PRIORITY_SHIFT_PER_SOURCE));
  78. *priority_ptr = priority;
  79. }
  80. /**
  81. * @brief Set interrupt pending bit
  82. *
  83. * @param[in] base PLIC base address
  84. * @param[in] irq Target interrupt number
  85. *
  86. */
  87. ATTR_ALWAYS_INLINE static inline void __plic_set_irq_pending(uint32_t base, uint32_t irq)
  88. {
  89. volatile uint32_t *current_ptr = (volatile uint32_t *)(base +
  90. HPM_PLIC_PENDING_OFFSET + ((irq >> 5) << 2));
  91. *current_ptr = (1 << (irq & 0x1F));
  92. }
  93. /**
  94. * @brief Enable interrupt
  95. *
  96. * @param[in] base PLIC base address
  97. * @param[in] target Target to handle specific interrupt
  98. * @param[in] irq Interrupt number to be enabled
  99. *
  100. */
  101. ATTR_ALWAYS_INLINE static inline void __plic_enable_irq(uint32_t base,
  102. uint32_t target,
  103. uint32_t irq)
  104. {
  105. volatile uint32_t *current_ptr = (volatile uint32_t *)(base +
  106. HPM_PLIC_ENABLE_OFFSET +
  107. (target << HPM_PLIC_ENABLE_SHIFT_PER_TARGET) +
  108. ((irq >> 5) << 2));
  109. uint32_t current = *current_ptr;
  110. current = current | (1 << (irq & 0x1F));
  111. *current_ptr = current;
  112. }
  113. /**
  114. * @brief Disable interrupt
  115. *
  116. * @param[in] base PLIC base address
  117. * @param[in] target Target to handle specific interrupt
  118. * @param[in] irq Interrupt number to be disabled
  119. *
  120. */
  121. ATTR_ALWAYS_INLINE static inline void __plic_disable_irq(uint32_t base,
  122. uint32_t target,
  123. uint32_t irq)
  124. {
  125. volatile uint32_t *current_ptr = (volatile uint32_t *)(base +
  126. HPM_PLIC_ENABLE_OFFSET +
  127. (target << HPM_PLIC_ENABLE_SHIFT_PER_TARGET) +
  128. ((irq >> 5) << 2));
  129. uint32_t current = *current_ptr;
  130. current = current & ~((1 << (irq & 0x1F)));
  131. *current_ptr = current;
  132. }
  133. /**
  134. * @brief Claim interrupt
  135. *
  136. * @param[in] base PLIC base address
  137. * @param[in] target Target to claim interrupt
  138. *
  139. */
  140. ATTR_ALWAYS_INLINE static inline uint32_t __plic_claim_irq(uint32_t base, uint32_t target)
  141. {
  142. volatile uint32_t *claim_addr = (volatile uint32_t *)(base +
  143. HPM_PLIC_CLAIM_OFFSET +
  144. (target << HPM_PLIC_CLAIM_SHIFT_PER_TARGET));
  145. return *claim_addr;
  146. }
  147. /**
  148. * @brief Complete interrupt
  149. *
  150. * @param[in] base PLIC base address
  151. * @param[in] target Target to handle specific interrupt
  152. * @param[in] irq Interrupt number
  153. *
  154. */
  155. ATTR_ALWAYS_INLINE static inline void __plic_complete_irq(uint32_t base,
  156. uint32_t target,
  157. uint32_t irq)
  158. {
  159. volatile uint32_t *claim_addr = (volatile uint32_t *)(base +
  160. HPM_PLIC_CLAIM_OFFSET +
  161. (target << HPM_PLIC_CLAIM_SHIFT_PER_TARGET));
  162. *claim_addr = irq;
  163. }
  164. #endif /* __ASSEMBLER__ */
  165. /**
  166. * @}
  167. */
  168. #endif /* HPM_PLIC_DRV_H */