test_eclic.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #include <stdlib.h>
  2. #include "ctest.h"
  3. #include "nuclei_sdk_soc.h"
  4. /**
  5. * \brief Test case: TC_CoreFunc_EnDisIRQ
  6. * \details
  7. * Check expected behavior of interrupt related control functions:
  8. * - __disable_irq() and __enable_irq()
  9. * - ECLIC_EnableIRQ, ECLIC_DisableIRQ, and ECLIC_GetEnableIRQ
  10. * - ECLIC_SetPendingIRQ, ECLIC_ClearPendingIRQ, and ECLIC_GetPendingIRQ
  11. */
  12. extern void eclic_mtip_handler(void);
  13. CTEST(eclic, en_dis_irq)
  14. {
  15. // Globally disable all interrupt servicing
  16. __disable_irq();
  17. ECLIC_SetShvIRQ(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT);
  18. ASSERT_EQUAL(ECLIC_GetShvIRQ(SysTimer_IRQn), ECLIC_NON_VECTOR_INTERRUPT);
  19. ECLIC_SetTrigIRQ(SysTimer_IRQn, ECLIC_POSTIVE_EDGE_TRIGGER);
  20. ASSERT_EQUAL(ECLIC_GetTrigIRQ(SysTimer_IRQn), ECLIC_POSTIVE_EDGE_TRIGGER);
  21. ECLIC_SetLevelIRQ(SysTimer_IRQn, 1);
  22. ASSERT_EQUAL(ECLIC_GetLevelIRQ(SysTimer_IRQn), 1);
  23. ECLIC_SetLevelIRQ(SysTimer_IRQn, 0);
  24. ASSERT_EQUAL(ECLIC_GetLevelIRQ(SysTimer_IRQn), 0);
  25. ECLIC_SetPriorityIRQ(SysTimer_IRQn, 0);
  26. ASSERT_EQUAL(ECLIC_GetPriorityIRQ(SysTimer_IRQn), 0);
  27. ECLIC_SetCfgNlbits(__ECLIC_INTCTLBITS - 1);
  28. ECLIC_SetPriorityIRQ(SysTimer_IRQn, 1);
  29. ASSERT_EQUAL(ECLIC_GetPriorityIRQ(SysTimer_IRQn), 1);
  30. // Clear its pending state
  31. ECLIC_ClearPendingIRQ(SysTimer_IRQn);
  32. ASSERT_EQUAL(ECLIC_GetPendingIRQ(SysTimer_IRQn), 0);
  33. // Register test interrupt handler.
  34. ECLIC_SetVector(SysTimer_IRQn, (rv_csr_t)eclic_mtip_handler);
  35. CTEST_LOG("Register irq vector 0x%lx vs 0x%lx", ECLIC_GetVector(SysTimer_IRQn), (rv_csr_t)eclic_mtip_handler);
  36. ASSERT_EQUAL(ECLIC_GetVector(SysTimer_IRQn), (rv_csr_t)eclic_mtip_handler);
  37. // Enable the interrupt
  38. ECLIC_EnableIRQ(SysTimer_IRQn);
  39. ASSERT_EQUAL(ECLIC_GetEnableIRQ(SysTimer_IRQn), 1);
  40. // Set the interrupt pending state
  41. ECLIC_SetPendingIRQ(SysTimer_IRQn);
  42. for (uint32_t i = 10; i > 0; --i) {}
  43. // Interrupt is not taken
  44. ASSERT_EQUAL(ECLIC_GetPendingIRQ(SysTimer_IRQn), 1);
  45. // Globally enable interrupt servicing
  46. __enable_irq();
  47. for (uint32_t i = 1000; i > 0; --i) {}
  48. // Interrupt it not pending anymore.
  49. ASSERT_EQUAL(ECLIC_GetPendingIRQ(SysTimer_IRQn), 0);
  50. // Disable interrupt
  51. ECLIC_DisableIRQ(SysTimer_IRQn);
  52. ASSERT_EQUAL(ECLIC_GetEnableIRQ(SysTimer_IRQn), 0);
  53. // Set interrupt pending
  54. ECLIC_SetPendingIRQ(SysTimer_IRQn);
  55. for (uint32_t i = 10; i > 0; --i) {
  56. }
  57. // Interrupt is not taken again
  58. ASSERT_EQUAL(ECLIC_GetPendingIRQ(SysTimer_IRQn), 1);
  59. // Clear interrupt pending
  60. ECLIC_ClearPendingIRQ(SysTimer_IRQn);
  61. for (uint32_t i = 10; i > 0; --i) {
  62. }
  63. // Interrupt it not pending anymore.
  64. ASSERT_EQUAL(ECLIC_GetPendingIRQ(SysTimer_IRQn), 0);
  65. // Globally disable interrupt servicing
  66. __disable_irq();
  67. }
  68. void get_max_lvl_pri(uint8_t* maxpri, uint8_t* maxlvl)
  69. {
  70. uint8_t nlbits = __ECLIC_GetCfgNlbits();
  71. uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS;
  72. *maxpri = 0;
  73. *maxlvl = 0;
  74. if (nlbits < intctlbits) {
  75. *maxpri = ((1 << (intctlbits - nlbits)) - 1);
  76. } else { // see #56 if nlbits set to bigger than CLICINTCTLBITS
  77. nlbits = intctlbits;
  78. }
  79. if (nlbits > 0) {
  80. *maxlvl = (1 << nlbits) - 1;
  81. }
  82. }
  83. /**
  84. * \brief Test case: eclic_LvlPri
  85. * \details
  86. * Check expected behavior of interrupt level and priority control functions:
  87. * - ECLIC_SetPriorityIRQ, ECLIC_GetPriorityIRQ,
  88. * - ECLIC_SetLevelIRQ, ECLIC_GetLevelIRQ
  89. */
  90. CTEST(eclic, lvl_pri_irq)
  91. {
  92. uint8_t oldnlbits = __ECLIC_GetCfgNlbits();
  93. uint8_t maxlvl, maxpri;
  94. uint8_t lvlnew, prinew;
  95. get_max_lvl_pri(&maxpri, &maxlvl);
  96. if (maxlvl == 0) {
  97. lvlnew = 0;
  98. } else {
  99. lvlnew = rand() % maxlvl;
  100. }
  101. if (maxpri == 0) {
  102. prinew = 0;
  103. } else {
  104. prinew = rand() % maxpri;
  105. }
  106. ECLIC_SetPriorityIRQ(SysTimer_IRQn, prinew);
  107. ASSERT_EQUAL(ECLIC_GetPriorityIRQ(SysTimer_IRQn), prinew);
  108. ECLIC_SetLevelIRQ(SysTimer_IRQn, lvlnew);
  109. ASSERT_EQUAL(ECLIC_GetLevelIRQ(SysTimer_IRQn), lvlnew);
  110. ECLIC_SetPriorityIRQ(SysTimer_IRQn, 255);
  111. ASSERT_EQUAL(ECLIC_GetPriorityIRQ(SysTimer_IRQn), maxpri);
  112. ECLIC_SetLevelIRQ(SysTimer_IRQn, 255);
  113. ASSERT_EQUAL(ECLIC_GetLevelIRQ(SysTimer_IRQn), maxlvl);
  114. ECLIC_SetCfgNlbits(3);
  115. get_max_lvl_pri(&maxpri, &maxlvl);
  116. ECLIC_SetLevelIRQ(SysTimer_IRQn, 15);
  117. ASSERT_EQUAL(ECLIC_GetLevelIRQ(SysTimer_IRQn), maxlvl);
  118. ECLIC_SetPriorityIRQ(SysTimer_IRQn, 31);
  119. ASSERT_EQUAL(ECLIC_GetPriorityIRQ(SysTimer_IRQn), maxpri);
  120. ECLIC_SetCfgNlbits(2);
  121. get_max_lvl_pri(&maxpri, &maxlvl);
  122. ECLIC_SetLevelIRQ(SysTimer_IRQn, 2);
  123. ECLIC_SetPriorityIRQ(SysTimer_IRQn, 5);
  124. ASSERT_EQUAL(ECLIC_GetLevelIRQ(SysTimer_IRQn) <= maxlvl, 1);
  125. ASSERT_EQUAL(ECLIC_GetPriorityIRQ(SysTimer_IRQn) <= maxpri, 1);
  126. ECLIC_SetCfgNlbits(oldnlbits);
  127. ASSERT_EQUAL(ECLIC_GetCfgNlbits(), oldnlbits);
  128. }
  129. /**
  130. * \brief Test case: eclic_register
  131. * \details
  132. * Check expected behavior of eclic register read/write:
  133. * - ECLIC_SetPriorityIRQ, ECLIC_GetPriorityIRQ,
  134. * - ECLIC_SetLevelIRQ, ECLIC_GetLevelIRQ
  135. */
  136. CTEST(eclic, reg_read_write)
  137. {
  138. uint32_t orig = ECLIC_GetCfgNlbits();
  139. // Check whether __ECLIC_INTCTLBITS macro is set to real hardware implemented one
  140. ASSERT_EQUAL(ECLIC_GetInfoCtlbits(), __ECLIC_INTCTLBITS);
  141. ECLIC_SetCfgNlbits(__ECLIC_INTCTLBITS - 1);
  142. ASSERT_EQUAL(ECLIC_GetCfgNlbits(), __ECLIC_INTCTLBITS - 1);
  143. ECLIC_SetCfgNlbits(orig);
  144. orig = ECLIC_GetMth();
  145. ECLIC_SetMth(255);
  146. ASSERT_EQUAL(ECLIC_GetMth(), 255);
  147. ECLIC_SetMth(orig);
  148. ASSERT_EQUAL(ECLIC_GetMth(), orig);
  149. ECLIC_GetTrigIRQ(SysTimer_IRQn);
  150. ECLIC_SetTrigIRQ(SysTimer_IRQn, ECLIC_NEGTIVE_EDGE_TRIGGER);
  151. ASSERT_EQUAL(ECLIC_GetTrigIRQ(SysTimer_IRQn), ECLIC_NEGTIVE_EDGE_TRIGGER);
  152. CTEST_LOG("CLICINTCTLBITS : %d", ECLIC_GetInfoCtlbits());
  153. CTEST_LOG("CLIC VERSION : 0x%x", ECLIC_GetInfoVer());
  154. CTEST_LOG("NUM_INTERRUPT : %d", ECLIC_GetInfoNum());
  155. CTEST_LOG("MTH : %d", ECLIC_GetMth());
  156. CTEST_LOG("NLBITS : %d", ECLIC_GetCfgNlbits());
  157. }
  158. CTEST(eclic, nmi_entry)
  159. {
  160. ASSERT_EQUAL(__get_nmi_entry(), __RV_CSR_READ(CSR_MTVEC));
  161. }
  162. void new_nonvec_entry(void)
  163. {
  164. }
  165. CTEST(eclic, nonvec_entry)
  166. {
  167. rv_csr_t entry = __get_nonvec_entry();
  168. CTEST_LOG("Non vector entry is 0x%lx", entry);
  169. __disable_irq();
  170. __set_nonvec_entry((rv_csr_t)new_nonvec_entry);
  171. //CTEST_LOG("Non vector entry is 0x%x, 0x%x", __Get_Nonvec_Entry(), new_nonvec_entry);
  172. ASSERT_EQUAL(__get_nonvec_entry(), (rv_csr_t)new_nonvec_entry & (rv_csr_t)(~0x3));
  173. __set_nonvec_entry((rv_csr_t)entry);
  174. ASSERT_EQUAL(__get_nonvec_entry(), entry);
  175. //__enable_irq();
  176. }
  177. void new_exc_entry(void)
  178. {
  179. }
  180. CTEST(eclic, exc_entry)
  181. {
  182. rv_csr_t entry = __get_exc_entry();
  183. CTEST_LOG("Exception entry is 0x%lx", entry);
  184. __set_exc_entry((rv_csr_t)new_exc_entry);
  185. CTEST_LOG("Exception set entry is 0x%lx, 0x%lx", __get_exc_entry(), (rv_csr_t)new_exc_entry);
  186. ASSERT_EQUAL(__get_exc_entry(), (rv_csr_t)new_exc_entry & (rv_csr_t)(~0x3F));
  187. __set_exc_entry((rv_csr_t)entry);
  188. ASSERT_EQUAL(__get_exc_entry(), entry);
  189. }