test_csr.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  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. CTEST(core, csr_swap)
  18. {
  19. __RV_CSR_WRITE(CSR_MSCRATCH, 0x12345678);
  20. ASSERT_EQUAL(__RV_CSR_SWAP(CSR_MSCRATCH, 0xABCDEF12), 0x12345678);
  21. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), 0xABCDEF12);
  22. rv_csr_t mscratch = 0xDEADBEAF;
  23. ASSERT_EQUAL(__RV_CSR_SWAP(CSR_MSCRATCH, mscratch), 0xABCDEF12);
  24. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), mscratch);
  25. }
  26. CTEST(core, csr_read)
  27. {
  28. __RV_CSR_WRITE(CSR_MSCRATCH, 0xDEADBEEF);
  29. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), 0xDEADBEEF);
  30. }
  31. CTEST(core, csr_write)
  32. {
  33. __RV_CSR_WRITE(CSR_MSCRATCH, 0xDEADBEEF);
  34. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), 0xDEADBEEF);
  35. rv_csr_t mscratch = 0x12376812;
  36. __RV_CSR_WRITE(CSR_MSCRATCH, mscratch);
  37. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), mscratch);
  38. }
  39. CTEST(core, csr_read_set)
  40. {
  41. __RV_CSR_WRITE(CSR_MSCRATCH, 0x0);
  42. ASSERT_EQUAL(__RV_CSR_READ_SET(CSR_MSCRATCH, 0xFF), 0x0);
  43. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), 0xFF);
  44. rv_csr_t random_val = __RV_CSR_READ(CSR_MCYCLE);
  45. __RV_CSR_WRITE(CSR_MSCRATCH, random_val);
  46. ASSERT_EQUAL(__RV_CSR_READ_SET(CSR_MSCRATCH, 0x12345678), random_val);
  47. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), 0x12345678 | random_val);
  48. }
  49. CTEST(core, csr_set)
  50. {
  51. __RV_CSR_WRITE(CSR_MSCRATCH, 0xFF003456);
  52. __RV_CSR_SET(CSR_MSCRATCH, 0x12EF);
  53. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), 0x12EF | 0xFF003456);
  54. rv_csr_t random_val = __RV_CSR_READ(CSR_MCYCLE);
  55. __RV_CSR_WRITE(CSR_MSCRATCH, random_val);
  56. __RV_CSR_SET(CSR_MSCRATCH, 0x12345678);
  57. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), 0x12345678 | random_val);
  58. }
  59. CTEST(core, csr_read_clear)
  60. {
  61. __RV_CSR_WRITE(CSR_MSCRATCH, 0xFF003456);
  62. ASSERT_EQUAL(__RV_CSR_READ_CLEAR(CSR_MSCRATCH, 0xFF), 0xFF003456);
  63. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), ~0xFF & 0xFF003456);
  64. rv_csr_t random_val = __RV_CSR_READ(CSR_MCYCLE);
  65. __RV_CSR_WRITE(CSR_MSCRATCH, random_val);
  66. ASSERT_EQUAL(__RV_CSR_READ_CLEAR(CSR_MSCRATCH, 0x12345678), random_val);
  67. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), ~0x12345678 & random_val);
  68. }
  69. CTEST(core, csr_clear)
  70. {
  71. __RV_CSR_WRITE(CSR_MSCRATCH, 0xFF003456);
  72. __RV_CSR_CLEAR(CSR_MSCRATCH, 0xFF);
  73. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), ~0xFF & 0xFF003456);
  74. rv_csr_t random_val = __RV_CSR_READ(CSR_MCYCLE);
  75. __RV_CSR_WRITE(CSR_MSCRATCH, random_val);
  76. __RV_CSR_READ_CLEAR(CSR_MSCRATCH, 0x12345678);
  77. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSCRATCH), ~0x12345678 & random_val);
  78. }
  79. CTEST(core, irq)
  80. {
  81. __enable_irq();
  82. ASSERT_NOT_EQUAL(__RV_CSR_READ(CSR_MSTATUS) & MSTATUS_MIE, 0);
  83. __disable_irq();
  84. ASSERT_EQUAL(__RV_CSR_READ(CSR_MSTATUS) & MSTATUS_MIE, 0);
  85. }
  86. CTEST(core, cycle)
  87. {
  88. uint64_t cycles = 0;
  89. #if __RISCV_XLEN == 32
  90. cycles = __RV_CSR_READ(CSR_MCYCLE) | ((uint64_t)__RV_CSR_READ(CSR_MCYCLEH) << 32);
  91. #elif __RISCV_XLEN == 64
  92. cycles = __RV_CSR_READ(CSR_MCYCLE);
  93. #endif
  94. ASSERT_EQUAL(__get_rv_cycle() > cycles, 1);
  95. }
  96. CTEST(core, instret)
  97. {
  98. uint64_t instret = 0;
  99. #if __RISCV_XLEN == 32
  100. instret = __RV_CSR_READ(CSR_MINSTRET) | ((uint64_t)__RV_CSR_READ(CSR_MINSTRETH) << 32);
  101. #elif __RISCV_XLEN == 64
  102. instret = __RV_CSR_READ(CSR_MINSTRET);
  103. #endif
  104. ASSERT_EQUAL(__get_rv_instret() > instret, 1);
  105. }
  106. CTEST(core, nop)
  107. {
  108. uint64_t instret = __RV_CSR_READ(CSR_MINSTRET);
  109. uint64_t diff = __RV_CSR_READ(CSR_MINSTRET) - instret;
  110. instret = __RV_CSR_READ(CSR_MINSTRET);
  111. __NOP();
  112. uint64_t diff2 = __RV_CSR_READ(CSR_MINSTRET) - instret;
  113. //CTEST_LOG("Diff: %d, %d\r\n", diff, diff2);
  114. ASSERT_EQUAL(diff2 > diff, 1);
  115. }
  116. void SOC_MTIMER_HANDLER(void)
  117. {
  118. // Clear Systimer pending flag by set compare value very large
  119. SysTimer_SetCompareValue(0xFFFFFFFFFFFFFFFFULL);
  120. ECLIC_ClearPendingIRQ(SysTimer_IRQn);
  121. ECLIC_DisableIRQ(SysTimer_IRQn);
  122. }
  123. CTEST(core, wfi)
  124. {
  125. __disable_irq();
  126. SysTick_Config(1000);
  127. SysTimer_Start();
  128. __WFI();
  129. // Should not enter interrupt handler
  130. #if defined(__NUCLEI_N_REV) && (__NUCLEI_N_REV < 0x0104)
  131. // For nuclei core version >= 1.4, the pending irq state
  132. // will be automatically cleared due to auto clear feature
  133. ASSERT_NOT_EQUAL(ECLIC_GetPendingIRQ(SysTimer_IRQn), 0);
  134. #endif
  135. ASSERT_NOT_EQUAL(ECLIC_GetEnableIRQ(SysTimer_IRQn), 0);
  136. ECLIC_DisableIRQ(SysTimer_IRQn);
  137. ECLIC_ClearPendingIRQ(SysTimer_IRQn);
  138. SysTick_Config(1000);
  139. SysTimer_Start();
  140. __enable_irq();
  141. __WFI();
  142. // Should enter interrupt handler first, then do following steps
  143. ASSERT_EQUAL(ECLIC_GetPendingIRQ(SysTimer_IRQn), 0);
  144. ASSERT_EQUAL(ECLIC_GetEnableIRQ(SysTimer_IRQn), 0);
  145. __disable_irq();
  146. }
  147. CTEST(core, wfe)
  148. {
  149. // TODO Not yet find a way to test it
  150. }
  151. static uint32_t ecall = 0;
  152. void ecall_handler(unsigned long mcause, unsigned long sp)
  153. {
  154. ecall = 1;
  155. EXC_Frame_Type *exc_frame = (EXC_Frame_Type *)sp;
  156. // mepc for ecall is the pc where ecall instruction located
  157. // so we just add 4 to mepc to return to the next instruction
  158. exc_frame->epc += 4;
  159. CTEST_LOG("__ECALL called\n");
  160. }
  161. CTEST(core, ecall)
  162. {
  163. ecall = 0;
  164. // working: ecall will not trigger the exception of machine mode ecall
  165. Exception_Register_EXC(MmodeEcall_EXCn, (unsigned long)ecall_handler);
  166. __ECALL();
  167. ASSERT_EQUAL(ecall, 1);
  168. }
  169. CTEST(core, sleepmode)
  170. {
  171. __disable_irq();
  172. SysTick_Config(1000);
  173. CTEST_LOG("Enter to Shallow Sleep Mode\r\n");
  174. __set_wfi_sleepmode(WFI_SHALLOW_SLEEP);
  175. __WFI();
  176. // Should not enter interrupt handler
  177. #if defined(__NUCLEI_N_REV) && (__NUCLEI_N_REV < 0x0104)
  178. // For nuclei core version >= 1.4, the pending irq state
  179. // will be automatically cleared due to auto clear feature
  180. ASSERT_NOT_EQUAL(ECLIC_GetPendingIRQ(SysTimer_IRQn), 0);
  181. #endif
  182. ASSERT_NOT_EQUAL(ECLIC_GetEnableIRQ(SysTimer_IRQn), 0);
  183. ECLIC_DisableIRQ(SysTimer_IRQn);
  184. ECLIC_ClearPendingIRQ(SysTimer_IRQn);
  185. SysTick_Config(1000);
  186. __enable_irq();
  187. // Uncomment the following line, the CPU will enter to deep sleep
  188. //CTEST_LOG("Enter to Deep Sleep Mode\r\n");
  189. //__set_wfi_sleepmode(WFI_DEEP_SLEEP);
  190. __WFI();
  191. // Should enter interrupt handler first, then do following steps
  192. ASSERT_EQUAL(ECLIC_GetPendingIRQ(SysTimer_IRQn), 0);
  193. ASSERT_EQUAL(ECLIC_GetEnableIRQ(SysTimer_IRQn), 0);
  194. __disable_irq();
  195. }
  196. CTEST(core, txevt)
  197. {
  198. CTEST_LOG("Send TXEVT\r\n");
  199. __TXEVT();
  200. }
  201. CTEST(core, mcycle_enable_disable)
  202. {
  203. CTEST_LOG("Disable MCYCLE Counter\r\n");
  204. __disable_mcycle_counter();
  205. ASSERT_EQUAL(__RV_CSR_READ(CSR_MCOUNTINHIBIT) & MCOUNTINHIBIT_CY, MCOUNTINHIBIT_CY);
  206. uint64_t cycle_b = __get_rv_cycle();
  207. __NOP();
  208. __NOP();
  209. __NOP();
  210. uint64_t cycle_a = __get_rv_cycle();
  211. ASSERT_EQUAL(cycle_b, cycle_a);
  212. CTEST_LOG("Enable MCYCLE Counter\r\n");
  213. __enable_mcycle_counter();
  214. ASSERT_NOT_EQUAL(__RV_CSR_READ(CSR_MCOUNTINHIBIT) & MCOUNTINHIBIT_CY, MCOUNTINHIBIT_CY);
  215. cycle_b = __get_rv_cycle();
  216. __NOP();
  217. __NOP();
  218. __NOP();
  219. cycle_a = __get_rv_cycle();
  220. ASSERT_EQUAL(cycle_a > cycle_b, 1);
  221. }
  222. CTEST(core, minstret_enable_disable)
  223. {
  224. CTEST_LOG("Disable MINSTRET Counter\r\n");
  225. __disable_minstret_counter();
  226. ASSERT_EQUAL(__RV_CSR_READ(CSR_MCOUNTINHIBIT) & MCOUNTINHIBIT_IR, MCOUNTINHIBIT_IR);
  227. uint64_t instret_b = __get_rv_instret();
  228. __NOP();
  229. __NOP();
  230. __NOP();
  231. uint64_t instret_a = __get_rv_instret();
  232. ASSERT_EQUAL(instret_b, instret_a);
  233. CTEST_LOG("Enable MINSTRET Counter\r\n");
  234. __enable_minstret_counter();
  235. ASSERT_NOT_EQUAL(__RV_CSR_READ(CSR_MCOUNTINHIBIT) & MCOUNTINHIBIT_IR, MCOUNTINHIBIT_IR);
  236. instret_b = __get_rv_instret();
  237. __NOP();
  238. __NOP();
  239. __NOP();
  240. instret_a = __get_rv_instret();
  241. ASSERT_EQUAL(instret_a > instret_b, 1);
  242. }
  243. CTEST(core, allcounter_enable_disable)
  244. {
  245. CTEST_LOG("Disable All Counter\r\n");
  246. __disable_all_counter();
  247. ASSERT_EQUAL(__RV_CSR_READ(CSR_MCOUNTINHIBIT) & (MCOUNTINHIBIT_IR | MCOUNTINHIBIT_CY), MCOUNTINHIBIT_IR | MCOUNTINHIBIT_CY);
  248. __disable_mcycle_counter();
  249. uint64_t cycle_b = __get_rv_cycle();
  250. __NOP();
  251. __NOP();
  252. __NOP();
  253. uint64_t cycle_a = __get_rv_cycle();
  254. ASSERT_EQUAL(cycle_b, cycle_a);
  255. uint64_t instret_b = __get_rv_instret();
  256. __NOP();
  257. __NOP();
  258. __NOP();
  259. uint64_t instret_a = __get_rv_instret();
  260. ASSERT_EQUAL(instret_b, instret_a);
  261. CTEST_LOG("Enable All Counter\r\n");
  262. __enable_all_counter();
  263. ASSERT_EQUAL(__RV_CSR_READ(CSR_MCOUNTINHIBIT) & (MCOUNTINHIBIT_IR | MCOUNTINHIBIT_CY), 0);
  264. instret_b = __get_rv_instret();
  265. __NOP();
  266. __NOP();
  267. __NOP();
  268. instret_a = __get_rv_instret();
  269. ASSERT_EQUAL(instret_a > instret_b, 1);
  270. cycle_b = __get_rv_cycle();
  271. __NOP();
  272. __NOP();
  273. __NOP();
  274. cycle_a = __get_rv_cycle();
  275. ASSERT_EQUAL(cycle_a > cycle_b, 1);
  276. }
  277. CTEST(core, fence)
  278. {
  279. __FENCE(rw, rw);
  280. __FENCE(iorw, rw);
  281. __FENCE_I();
  282. __RWMB();
  283. __RMB();
  284. __WMB();
  285. __SMP_RWMB();
  286. __SMP_RMB();
  287. __SMP_WMB();
  288. __CPU_RELAX();
  289. }
  290. CTEST(core, lb)
  291. {
  292. uint32_t data = 0x12345678;
  293. unsigned long pdata = (unsigned long)(&data);
  294. ASSERT_EQUAL(__LB((void*)pdata), 0x78);
  295. ASSERT_EQUAL(__LB((void*)(pdata + 1)), 0x56);
  296. ASSERT_EQUAL(__LB((void*)(pdata + 2)), 0x34);
  297. ASSERT_EQUAL(__LB((void*)(pdata + 3)), 0x12);
  298. }
  299. CTEST(core, sb)
  300. {
  301. uint32_t data = 0x12345678;
  302. unsigned long pdata = (unsigned long)(&data);
  303. __SB((void*)pdata, 0xAB);
  304. ASSERT_EQUAL(__LB((void*)pdata), 0xAB);
  305. __SB((void*)(pdata + 1), 0xCD);
  306. ASSERT_EQUAL(__LB((void*)(pdata + 1)), 0xCD);
  307. __SB((void*)(pdata + 2), 0xEF);
  308. ASSERT_EQUAL(__LB((void*)(pdata + 2)), 0xEF);
  309. __SB((void*)(pdata + 3), 0x00);
  310. ASSERT_EQUAL(__LB((void*)(pdata + 3)), 0x00);
  311. }
  312. CTEST(core, lh)
  313. {
  314. uint32_t data = 0x12345678;
  315. unsigned long pdata = (unsigned long)(&data);
  316. ASSERT_EQUAL(__LH((void*)pdata), 0x5678);
  317. ASSERT_EQUAL(__LH((void*)(pdata + 1)), 0x3456);
  318. ASSERT_EQUAL(__LH((void*)(pdata + 2)), 0x1234);
  319. }
  320. CTEST(core, sh)
  321. {
  322. uint32_t data = 0x12345678;
  323. unsigned long pdata = (unsigned long)(&data);
  324. __SH((void*)pdata, 0xABCD);
  325. ASSERT_EQUAL(__LH((void*)pdata), 0xABCD);
  326. __SH((void*)(pdata + 1), 0xCDEF);
  327. ASSERT_EQUAL(__LH((void*)(pdata + 1)), 0xCDEF);
  328. __SH((void*)(pdata + 2), 0xEF00);
  329. ASSERT_EQUAL(__LH((void*)(pdata + 2)), 0xEF00);
  330. }
  331. CTEST(core, lw)
  332. {
  333. uint32_t data[2] = {0x12345678, 0xABCDEF01};
  334. unsigned long pdata = (unsigned long)(&data);
  335. ASSERT_EQUAL(__LW((void*)pdata), 0x12345678);
  336. ASSERT_EQUAL(__LW((void*)(pdata + 1)), 0x01123456);
  337. ASSERT_EQUAL(__LW((void*)(pdata + 2)), 0xEF011234);
  338. ASSERT_EQUAL(__LW((void*)(pdata + 3)), 0xCDEF0112);
  339. ASSERT_EQUAL(__LW((void*)(pdata + 4)), 0xABCDEF01);
  340. }
  341. CTEST(core, sw)
  342. {
  343. uint32_t data[2] = {0x12345678, 0xABCDEF01};
  344. unsigned long pdata = (unsigned long)(&data);
  345. __SW((void*)pdata, 0xDEADBEEF);
  346. ASSERT_EQUAL(__LW((void*)pdata), 0xDEADBEEF);
  347. __SW((void*)(pdata + 1), 0xCDEF1234);
  348. ASSERT_EQUAL(__LW((void*)(pdata + 1)), 0xCDEF1234);
  349. __SW((void*)(pdata + 2), 0xEF007678);
  350. ASSERT_EQUAL(__LW((void*)(pdata + 2)), 0xEF007678);
  351. __SW((void*)(pdata + 3), 0x89282678);
  352. ASSERT_EQUAL(__LW((void*)(pdata + 3)), 0x89282678);
  353. __SW((void*)(pdata + 4), 0xDEADBEAF);
  354. ASSERT_EQUAL(__LW((void*)(pdata + 4)), 0xDEADBEAF);
  355. }
  356. #if __RISCV_XLEN == 64
  357. CTEST(core, ld)
  358. {
  359. uint32_t data[4] = {0x12345678, 0xABCDEF01, 0x87654321, 0x01FEDCBA};
  360. unsigned long pdata = (unsigned long)(&data);
  361. ASSERT_EQUAL(__LD((void*)pdata), 0xABCDEF0112345678);
  362. ASSERT_EQUAL(__LD((void*)(pdata + 1)), 0x21ABCDEF01123456);
  363. ASSERT_EQUAL(__LD((void*)(pdata + 2)), 0x4321ABCDEF011234);
  364. ASSERT_EQUAL(__LD((void*)(pdata + 3)), 0x654321ABCDEF0112);
  365. ASSERT_EQUAL(__LD((void*)(pdata + 4)), 0x87654321ABCDEF01);
  366. ASSERT_EQUAL(__LD((void*)(pdata + 8)), 0x01FEDCBA87654321);
  367. }
  368. CTEST(core, sd)
  369. {
  370. uint32_t data[4] = {0x12345678, 0xABCDEF01, 0x87654321, 0x01FEDCBA};
  371. unsigned long pdata = (unsigned long)(&data);
  372. __SD((void*)pdata, 0xDEADBEEFDEADBEEF);
  373. ASSERT_EQUAL(__LD((void*)pdata), 0xDEADBEEFDEADBEEF);
  374. __SD((void*)(pdata + 1), 0xCDEF123443219876);
  375. ASSERT_EQUAL(__LD((void*)(pdata + 1)), 0xCDEF123443219876);
  376. __SD((void*)(pdata + 2), 0xEF00767887665776);
  377. ASSERT_EQUAL(__LD((void*)(pdata + 2)), 0xEF00767887665776);
  378. __SD((void*)(pdata + 3), 0x8928267890892912);
  379. ASSERT_EQUAL(__LD((void*)(pdata + 3)), 0x8928267890892912);
  380. __SD((void*)(pdata + 4), 0xDEADBEAFBEEFDEAD);
  381. ASSERT_EQUAL(__LD((void*)(pdata + 4)), 0xDEADBEAFBEEFDEAD);
  382. __SD((void*)(pdata + 8), 0xBEEFDEADDEADBEAF);
  383. ASSERT_EQUAL(__LD((void*)(pdata + 8)), 0xBEEFDEADDEADBEAF);
  384. }
  385. #endif
  386. #if defined(__ICACHE_PRESENT) && __ICACHE_PRESENT == 1
  387. CTEST(core, icache)
  388. {
  389. EnableICache();
  390. ASSERT_NOT_EQUAL(__RV_CSR_READ(CSR_MCACHE_CTL) & CSR_MCACHE_CTL_IE, 0);
  391. DisableICache();
  392. ASSERT_EQUAL(__RV_CSR_READ(CSR_MCACHE_CTL) & CSR_MCACHE_CTL_IE, 0);
  393. }
  394. #endif
  395. CTEST(core, csrcontext)
  396. {
  397. SAVE_IRQ_CSR_CONTEXT();
  398. RESTORE_IRQ_CSR_CONTEXT();
  399. }
  400. CTEST(core, hpmevent)
  401. {
  402. for (unsigned long i = 0; i < 32; i ++) {
  403. __set_hpm_event(i, 0xA5A5A5A5);
  404. __get_hpm_event(i);
  405. }
  406. }
  407. CTEST(core, hpmcounter)
  408. {
  409. for (unsigned long i = 0; i < 32; i ++) {
  410. __set_hpm_counter(i, 0xA5A5A5A5A5A5A5A5ULL);
  411. __get_hpm_counter(i);
  412. __enable_mhpm_counter(i);
  413. __disable_mhpm_counter(i);
  414. __enable_mhpm_counters(1<<i);
  415. __disable_mhpm_counters(1<<i);
  416. }
  417. }