interrupt.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdint.h>
  7. #include <stddef.h>
  8. #include <assert.h>
  9. #include "soc/soc.h"
  10. #include "riscv/interrupt.h"
  11. #include "soc/interrupt_reg.h"
  12. #include "riscv/csr.h"
  13. #include "esp_attr.h"
  14. #include "riscv/rv_utils.h"
  15. //TODO: IDF-7795, P4, see jira to know what changed and what need to be checked
  16. #define RV_INT_COUNT 32
  17. static inline void assert_valid_rv_int_num(int rv_int_num)
  18. {
  19. #if SOC_INT_CLIC_SUPPORTED
  20. assert(rv_int_num < RV_INT_COUNT && "Invalid CPU interrupt number");
  21. #else
  22. assert(rv_int_num != 0 && rv_int_num < RV_INT_COUNT && "Invalid CPU interrupt number");
  23. #endif
  24. }
  25. /*************************** Software interrupt dispatcher ***************************/
  26. typedef struct {
  27. intr_handler_t handler;
  28. void *arg;
  29. } intr_handler_item_t;
  30. #if SOC_INT_CLIC_SUPPORTED
  31. static intr_handler_item_t s_intr_handlers_core0[48];
  32. static intr_handler_item_t s_intr_handlers_core1[48];
  33. #else
  34. static intr_handler_item_t s_intr_handlers[32];
  35. #endif
  36. void intr_handler_set(int int_no, intr_handler_t fn, void *arg)
  37. {
  38. assert_valid_rv_int_num(int_no);
  39. #if SOC_INT_CLIC_SUPPORTED
  40. if (rv_utils_get_core_id() == 0) {
  41. s_intr_handlers_core0[int_no + CLIC_EXT_INTR_NUM_OFFSET] = (intr_handler_item_t) {
  42. .handler = fn,
  43. .arg = arg,
  44. };
  45. } else {
  46. s_intr_handlers_core1[int_no + CLIC_EXT_INTR_NUM_OFFSET] = (intr_handler_item_t) {
  47. .handler = fn,
  48. .arg = arg,
  49. };
  50. }
  51. #else
  52. s_intr_handlers[int_no] = (intr_handler_item_t) {
  53. .handler = fn,
  54. .arg = arg
  55. };
  56. #endif
  57. }
  58. intr_handler_t intr_handler_get(int rv_int_num)
  59. {
  60. #if SOC_INT_CLIC_SUPPORTED
  61. if (rv_utils_get_core_id() == 0)
  62. return s_intr_handlers_core0[rv_int_num + CLIC_EXT_INTR_NUM_OFFSET].handler;
  63. else
  64. return s_intr_handlers_core1[rv_int_num + CLIC_EXT_INTR_NUM_OFFSET].handler;
  65. #else
  66. return s_intr_handlers[rv_int_num].handler;
  67. #endif
  68. }
  69. void *intr_handler_get_arg(int rv_int_num)
  70. {
  71. #if SOC_INT_CLIC_SUPPORTED
  72. if (rv_utils_get_core_id() == 0)
  73. return s_intr_handlers_core0[rv_int_num + CLIC_EXT_INTR_NUM_OFFSET].arg;
  74. else
  75. return s_intr_handlers_core1[rv_int_num + CLIC_EXT_INTR_NUM_OFFSET].arg;
  76. #else
  77. return s_intr_handlers[rv_int_num].arg;
  78. #endif
  79. }
  80. /* called from vectors.S */
  81. void _global_interrupt_handler(intptr_t sp, int mcause)
  82. {
  83. #if SOC_INT_CLIC_SUPPORTED
  84. if (rv_utils_get_core_id() == 0) {
  85. intr_handler_item_t it = s_intr_handlers_core0[mcause];
  86. if (it.handler) {
  87. (*it.handler)(it.arg);
  88. }
  89. } else {
  90. intr_handler_item_t it = s_intr_handlers_core1[mcause];
  91. if (it.handler) {
  92. (*it.handler)(it.arg);
  93. }
  94. }
  95. #else
  96. intr_handler_item_t it = s_intr_handlers[mcause];
  97. if (it.handler) {
  98. (*it.handler)(it.arg);
  99. }
  100. #endif
  101. }
  102. /*************************** RISC-V interrupt enable/disable ***************************/
  103. void intr_matrix_route(int intr_src, int intr_num)
  104. {
  105. #if !SOC_INT_CLIC_SUPPORTED
  106. assert(intr_num != 0);
  107. REG_WRITE(DR_REG_INTERRUPT_BASE + 4 * intr_src, intr_num);
  108. #else
  109. if (rv_utils_get_core_id() == 0)
  110. REG_WRITE(DR_REG_INTERRUPT_CORE0_BASE + 4 * intr_src, intr_num + CLIC_EXT_INTR_NUM_OFFSET);
  111. else
  112. REG_WRITE(DR_REG_INTERRUPT_CORE1_BASE + 4 * intr_src, intr_num + CLIC_EXT_INTR_NUM_OFFSET);
  113. #endif
  114. }
  115. // CLIC for each interrupt line provides a IE register
  116. // this api is not used
  117. #if !SOC_INT_CLIC_SUPPORTED
  118. uint32_t esprv_intc_get_interrupt_unmask(void)
  119. {
  120. return REG_READ(INTERRUPT_CORE0_CPU_INT_ENABLE_REG);
  121. }
  122. #endif
  123. /*************************** ESP-RV Interrupt Controller ***************************/
  124. enum intr_type esprv_intc_int_get_type(int intr_num)
  125. {
  126. #if SOC_INT_CLIC_SUPPORTED
  127. uint32_t intr_type_reg = REG_GET_FIELD(CLIC_INT_CTRL_REG(intr_num + CLIC_EXT_INTR_NUM_OFFSET), CLIC_INT_ATTR_TRIG);
  128. return (intr_type_reg & 1) ? INTR_TYPE_EDGE : INTR_TYPE_LEVEL;
  129. // May also support rising edge and falling edge.
  130. #else
  131. uint32_t intr_type_reg = REG_READ(INTERRUPT_CORE0_CPU_INT_TYPE_REG);
  132. return (intr_type_reg & (1 << intr_num)) ? INTR_TYPE_EDGE : INTR_TYPE_LEVEL;
  133. #endif
  134. }
  135. int esprv_intc_int_get_priority(int rv_int_num)
  136. {
  137. #if SOC_INT_CLIC_SUPPORTED
  138. uint32_t intr_priority_reg = REG_GET_FIELD(CLIC_INT_CTRL_REG(rv_int_num + CLIC_EXT_INTR_NUM_OFFSET), CLIC_INT_CTL);
  139. return (intr_priority_reg >> (8 - NLBITS));
  140. #else
  141. uint32_t intr_priority_reg = REG_READ(INTC_INT_PRIO_REG(rv_int_num));
  142. return intr_priority_reg;
  143. #endif
  144. }
  145. /*************************** Exception names. Used in .gdbinit file. ***************************/
  146. const char *riscv_excp_names[16] __attribute__((used)) = {
  147. "misaligned_fetch",
  148. "fault_fetch",
  149. "illegal_instruction",
  150. "breakpoint",
  151. "misaligned_load",
  152. "fault_load",
  153. "misaligned_store",
  154. "fault_store",
  155. "user_ecall",
  156. "supervisor_ecall",
  157. "hypervisor_ecall",
  158. "machine_ecall",
  159. "exec_page_fault",
  160. "load_page_fault",
  161. "reserved",
  162. "store_page_fault"
  163. };