test_csr.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. #include <stdlib.h>
  2. #include "ctest.h"
  3. #include "nuclei_sdk_soc.h"
  4. CTEST(core, riscv_xlen)
  5. {
  6. ASSERT_EQUAL(__RISCV_XLEN, __riscv_xlen);
  7. }
  8. CTEST(core, csr_type)
  9. {
  10. ASSERT_EQUAL(sizeof(rv_csr_t), sizeof(unsigned long));
  11. #if __RISCV_XLEN == 32
  12. ASSERT_EQUAL(sizeof(rv_csr_t), 4);
  13. #else
  14. ASSERT_EQUAL(sizeof(rv_csr_t), 8);
  15. #endif
  16. }
  17. #if 0
  18. // CSR_MSCRATCH doesn't existed in N100
  19. CTEST(core, csr_swap)
  20. {
  21. __RV_CSR_WRITE(CSR_MSCRATCH, 0x12345678);
  22. ASSERT_EQUAL(__RV_CSR_SWAP(CSR_MSCRATCH, 0xABCDEF12), 0x12345678);
  23. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), 0xABCDEF12);
  24. rv_csr_t mscratch = 0xDEADBEAF;
  25. ASSERT_EQUAL(__RV_CSR_SWAP(CSR_MSCRATCH, mscratch), 0xABCDEF12);
  26. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), mscratch);
  27. }
  28. CTEST(core, csr_read)
  29. {
  30. __RV_CSR_WRITE(CSR_MSCRATCH, 0xDEADBEEF);
  31. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), 0xDEADBEEF);
  32. }
  33. CTEST(core, csr_write)
  34. {
  35. __RV_CSR_WRITE(CSR_MSCRATCH, 0xDEADBEEF);
  36. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), 0xDEADBEEF);
  37. rv_csr_t mscratch = 0x12376812;
  38. __RV_CSR_WRITE(CSR_MSCRATCH, mscratch);
  39. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), mscratch);
  40. }
  41. CTEST(core, csr_read_set)
  42. {
  43. __RV_CSR_WRITE(CSR_MSCRATCH, 0x0);
  44. ASSERT_EQUAL(__RV_CSR_READ_SET(CSR_MSCRATCH, 0xFF), 0x0);
  45. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), 0xFF);
  46. rv_csr_t random_val = __RV_CSR_READ(CSR_MCYCLE);
  47. __RV_CSR_WRITE(CSR_MSCRATCH, random_val);
  48. ASSERT_EQUAL(__RV_CSR_READ_SET(CSR_MSCRATCH, 0x12345678), random_val);
  49. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), 0x12345678 | random_val);
  50. }
  51. CTEST(core, csr_set)
  52. {
  53. __RV_CSR_WRITE(CSR_MSCRATCH, 0xFF003456);
  54. __RV_CSR_SET(CSR_MSCRATCH, 0x12EF);
  55. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), 0x12EF | 0xFF003456);
  56. rv_csr_t random_val = __RV_CSR_READ(CSR_MCYCLE);
  57. __RV_CSR_WRITE(CSR_MSCRATCH, random_val);
  58. __RV_CSR_SET(CSR_MSCRATCH, 0x12345678);
  59. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), 0x12345678 | random_val);
  60. }
  61. CTEST(core, csr_read_clear)
  62. {
  63. __RV_CSR_WRITE(CSR_MSCRATCH, 0xFF003456);
  64. ASSERT_EQUAL(__RV_CSR_READ_CLEAR(CSR_MSCRATCH, 0xFF), 0xFF003456);
  65. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), ~0xFF & 0xFF003456);
  66. rv_csr_t random_val = __RV_CSR_READ(CSR_MCYCLE);
  67. __RV_CSR_WRITE(CSR_MSCRATCH, random_val);
  68. ASSERT_EQUAL(__RV_CSR_READ_CLEAR(CSR_MSCRATCH, 0x12345678), random_val);
  69. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), ~0x12345678 & random_val);
  70. }
  71. CTEST(core, csr_clear)
  72. {
  73. __RV_CSR_WRITE(CSR_MSCRATCH, 0xFF003456);
  74. __RV_CSR_CLEAR(CSR_MSCRATCH, 0xFF);
  75. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), ~0xFF & 0xFF003456);
  76. rv_csr_t random_val = __RV_CSR_READ(CSR_MCYCLE);
  77. __RV_CSR_WRITE(CSR_MSCRATCH, random_val);
  78. __RV_CSR_READ_CLEAR(CSR_MSCRATCH, 0x12345678);
  79. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), ~0x12345678 & random_val);
  80. }
  81. #endif
  82. CTEST(core, irq)
  83. {
  84. __enable_irq();
  85. ASSERT_NOT_EQUAL(__RV_CSR_READ(CSR_MSTATUS) & MSTATUS_MIE, 0);
  86. __disable_irq();
  87. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSTATUS) & MSTATUS_MIE, 0);
  88. }
  89. CTEST(core, cycle)
  90. {
  91. uint32_t cycles = 0;
  92. cycles = __RV_CSR_READ(CSR_MCYCLE);
  93. ASSERT_EQUAL(__get_rv_cycle() > cycles, 1);
  94. }
  95. CTEST(core, instret)
  96. {
  97. uint32_t instret = 0;
  98. instret = __RV_CSR_READ(CSR_MINSTRET);
  99. ASSERT_EQUAL(__get_rv_instret() > instret, 1);
  100. }
  101. CTEST(core, nop)
  102. {
  103. uint32_t instret = __RV_CSR_READ(CSR_MINSTRET);
  104. uint32_t diff = __RV_CSR_READ(CSR_MINSTRET) - instret;
  105. instret = __RV_CSR_READ(CSR_MINSTRET);
  106. __NOP();
  107. uint32_t diff2 = __RV_CSR_READ(CSR_MINSTRET) - instret;
  108. //CTEST_LOG("Diff: %d, %d\r\n", diff, diff2);
  109. ASSERT_EQUAL(diff2 > diff, 1);
  110. }
  111. __INTERRUPT void SOC_MTIMER_HANDLER(void)
  112. {
  113. // Clear Systimer pending flag by set compare value very large
  114. SysTimer_SetCompareValue(0xFFFFFFFF);
  115. IRQC_DisableIRQ(SysTimer_IRQn);
  116. }
  117. CTEST(core, wfi)
  118. {
  119. __disable_irq();
  120. SysTick_Config(10);
  121. SysTimer_Start();
  122. __WFI();
  123. ASSERT_NOT_EQUAL(IRQC_GetEnableIRQ(SysTimer_IRQn), 0);
  124. IRQC_DisableIRQ(SysTimer_IRQn);
  125. SysTick_Config(10);
  126. SysTimer_Start();
  127. __enable_irq();
  128. __WFI();
  129. // Should enter interrupt handler first, then do following steps
  130. ASSERT_EQUAL(IRQC_GetPendingIRQ(SysTimer_IRQn), 0);
  131. ASSERT_EQUAL(IRQC_GetEnableIRQ(SysTimer_IRQn), 0);
  132. __disable_irq();
  133. }
  134. CTEST(core, wfe)
  135. {
  136. // TODO Not yet find a way to test it
  137. }
  138. static uint32_t ecall = 0;
  139. void ecall_handler(unsigned long mcause, unsigned long sp)
  140. {
  141. ecall = 1;
  142. EXC_Frame_Type *exc_frame = (EXC_Frame_Type *)sp;
  143. // mepc for ecall is the pc where ecall instruction located
  144. // so we just add 4 to mepc to return to the next instruction
  145. exc_frame->epc += 4;
  146. CTEST_LOG("__ECALL called\n");
  147. }
  148. CTEST(core, ecall)
  149. {
  150. ecall = 0;
  151. // working: ecall will not trigger the exception of machine mode ecall
  152. Exception_Register_EXC(MmodeEcall_EXCn, (unsigned long)ecall_handler);
  153. __ECALL();
  154. ASSERT_EQUAL(ecall, 1);
  155. }
  156. CTEST(core, sleepmode)
  157. {
  158. __disable_irq();
  159. SysTick_Config(100);
  160. CTEST_LOG("Enter to Shallow Sleep Mode\r\n");
  161. __set_wfi_sleepmode(WFI_SHALLOW_SLEEP);
  162. __WFI();
  163. // Should not enter interrupt handler
  164. ASSERT_NOT_EQUAL(IRQC_GetEnableIRQ(SysTimer_IRQn), 0);
  165. IRQC_DisableIRQ(SysTimer_IRQn);
  166. SysTick_Config(100);
  167. __enable_irq();
  168. // Uncomment the following line, the CPU will enter to deep sleep
  169. //CTEST_LOG("Enter to Deep Sleep Mode\r\n");
  170. //__set_wfi_sleepmode(WFI_DEEP_SLEEP);
  171. __WFI();
  172. // Should enter interrupt handler first, then do following steps
  173. ASSERT_EQUAL(IRQC_GetPendingIRQ(SysTimer_IRQn), 0);
  174. ASSERT_EQUAL(IRQC_GetEnableIRQ(SysTimer_IRQn), 0);
  175. __disable_irq();
  176. }
  177. CTEST(core, txevt)
  178. {
  179. CTEST_LOG("Send TXEVT\r\n");
  180. __TXEVT();
  181. }
  182. CTEST(core, mcycle_enable_disable)
  183. {
  184. CTEST_LOG("Disable MCYCLE Counter\r\n");
  185. __disable_mcycle_counter();
  186. ASSERT_EQUAL(__RV_CSR_READ(CSR_MCOUNTINHIBIT) & MCOUNTINHIBIT_CY, MCOUNTINHIBIT_CY);
  187. uint64_t cycle_b = __get_rv_cycle();
  188. __NOP();
  189. __NOP();
  190. __NOP();
  191. uint64_t cycle_a = __get_rv_cycle();
  192. ASSERT_EQUAL(cycle_b, cycle_a);
  193. CTEST_LOG("Enable MCYCLE Counter\r\n");
  194. __enable_mcycle_counter();
  195. ASSERT_NOT_EQUAL(__RV_CSR_READ(CSR_MCOUNTINHIBIT) & MCOUNTINHIBIT_CY, MCOUNTINHIBIT_CY);
  196. cycle_b = __get_rv_cycle();
  197. __NOP();
  198. __NOP();
  199. __NOP();
  200. cycle_a = __get_rv_cycle();
  201. ASSERT_EQUAL(cycle_a > cycle_b, 1);
  202. }
  203. CTEST(core, minstret_enable_disable)
  204. {
  205. CTEST_LOG("Disable MINSTRET Counter\r\n");
  206. __disable_minstret_counter();
  207. ASSERT_EQUAL(__RV_CSR_READ(CSR_MCOUNTINHIBIT) & MCOUNTINHIBIT_IR, MCOUNTINHIBIT_IR);
  208. uint64_t instret_b = __get_rv_instret();
  209. __NOP();
  210. __NOP();
  211. __NOP();
  212. uint64_t instret_a = __get_rv_instret();
  213. ASSERT_EQUAL(instret_b, instret_a);
  214. CTEST_LOG("Enable MINSTRET Counter\r\n");
  215. __enable_minstret_counter();
  216. ASSERT_NOT_EQUAL(__RV_CSR_READ(CSR_MCOUNTINHIBIT) & MCOUNTINHIBIT_IR, MCOUNTINHIBIT_IR);
  217. instret_b = __get_rv_instret();
  218. __NOP();
  219. __NOP();
  220. __NOP();
  221. instret_a = __get_rv_instret();
  222. ASSERT_EQUAL(instret_a > instret_b, 1);
  223. }
  224. CTEST(core, allcounter_enable_disable)
  225. {
  226. CTEST_LOG("Disable All Counter\r\n");
  227. __disable_all_counter();
  228. ASSERT_EQUAL(__RV_CSR_READ(CSR_MCOUNTINHIBIT) & (MCOUNTINHIBIT_IR | MCOUNTINHIBIT_CY), MCOUNTINHIBIT_IR | MCOUNTINHIBIT_CY);
  229. __disable_mcycle_counter();
  230. uint64_t cycle_b = __get_rv_cycle();
  231. __NOP();
  232. __NOP();
  233. __NOP();
  234. uint64_t cycle_a = __get_rv_cycle();
  235. ASSERT_EQUAL(cycle_b, cycle_a);
  236. uint64_t instret_b = __get_rv_instret();
  237. __NOP();
  238. __NOP();
  239. __NOP();
  240. uint64_t instret_a = __get_rv_instret();
  241. ASSERT_EQUAL(instret_b, instret_a);
  242. CTEST_LOG("Enable All Counter\r\n");
  243. __enable_all_counter();
  244. ASSERT_EQUAL(__RV_CSR_READ(CSR_MCOUNTINHIBIT) & (MCOUNTINHIBIT_IR | MCOUNTINHIBIT_CY), 0);
  245. instret_b = __get_rv_instret();
  246. __NOP();
  247. __NOP();
  248. __NOP();
  249. instret_a = __get_rv_instret();
  250. ASSERT_EQUAL(instret_a > instret_b, 1);
  251. cycle_b = __get_rv_cycle();
  252. __NOP();
  253. __NOP();
  254. __NOP();
  255. cycle_a = __get_rv_cycle();
  256. ASSERT_EQUAL(cycle_a > cycle_b, 1);
  257. }
  258. CTEST(core, fence)
  259. {
  260. __FENCE(rw, rw);
  261. __FENCE(iorw, rw);
  262. __FENCE_I();
  263. __RWMB();
  264. __RMB();
  265. __WMB();
  266. __SMP_RWMB();
  267. __SMP_RMB();
  268. __SMP_WMB();
  269. __CPU_RELAX();
  270. }
  271. CTEST(core, lb)
  272. {
  273. uint32_t data = 0x12345678;
  274. unsigned long pdata = (unsigned long)(&data);
  275. ASSERT_EQUAL(__LB((void*)pdata), 0x78);
  276. ASSERT_EQUAL(__LB((void*)(pdata + 1)), 0x56);
  277. ASSERT_EQUAL(__LB((void*)(pdata + 2)), 0x34);
  278. ASSERT_EQUAL(__LB((void*)(pdata + 3)), 0x12);
  279. }
  280. CTEST(core, sb)
  281. {
  282. uint32_t data = 0x12345678;
  283. unsigned long pdata = (unsigned long)(&data);
  284. __SB((void*)pdata, 0xAB);
  285. ASSERT_EQUAL(__LB((void*)pdata), 0xAB);
  286. __SB((void*)(pdata + 1), 0xCD);
  287. ASSERT_EQUAL(__LB((void*)(pdata + 1)), 0xCD);
  288. __SB((void*)(pdata + 2), 0xEF);
  289. ASSERT_EQUAL(__LB((void*)(pdata + 2)), 0xEF);
  290. __SB((void*)(pdata + 3), 0x00);
  291. ASSERT_EQUAL(__LB((void*)(pdata + 3)), 0x00);
  292. }
  293. CTEST(core, lh)
  294. {
  295. uint32_t data = 0x12345678;
  296. unsigned long pdata = (unsigned long)(&data);
  297. ASSERT_EQUAL(__LH((void*)pdata), 0x5678);
  298. ASSERT_EQUAL(__LH((void*)(pdata + 2)), 0x1234);
  299. }
  300. CTEST(core, sh)
  301. {
  302. uint32_t data = 0x12345678;
  303. unsigned long pdata = (unsigned long)(&data);
  304. __SH((void*)pdata, 0xABCD);
  305. ASSERT_EQUAL(__LH((void*)pdata), 0xABCD);
  306. __SH((void*)(pdata + 2), 0xEF00);
  307. ASSERT_EQUAL(__LH((void*)(pdata + 2)), 0xEF00);
  308. }
  309. CTEST(core, lw)
  310. {
  311. uint32_t data[2] = {0x12345678, 0xABCDEF01};
  312. unsigned long pdata = (unsigned long)(&data);
  313. ASSERT_EQUAL(__LW((void*)pdata), 0x12345678);
  314. ASSERT_EQUAL(__LW((void*)(pdata + 4)), 0xABCDEF01);
  315. }
  316. CTEST(core, sw)
  317. {
  318. uint32_t data[2] = {0x12345678, 0xABCDEF01};
  319. unsigned long pdata = (unsigned long)(&data);
  320. __SW((void*)pdata, 0xDEADBEEF);
  321. ASSERT_EQUAL(__LW((void*)pdata), 0xDEADBEEF);
  322. __SW((void*)(pdata + 4), 0xDEADBEAF);
  323. ASSERT_EQUAL(__LW((void*)(pdata + 4)), 0xDEADBEAF);
  324. }