main.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. #include <stdio.h>
  2. #include "nuclei_sdk_soc.h"
  3. #define KB (1024)
  4. #define MB (KB * 1024)
  5. #define GB (MB * 1024)
  6. #define EXTENSION_NUM (26)
  7. #define POWER_FOR_TWO(n) (1UL << (n))
  8. #define LINESZ(n) ((n) > 0 ? POWER_FOR_TWO((n)-1) : 0)
  9. void show_safety_mechanism(unsigned long safetyMode)
  10. {
  11. switch (safetyMode) {
  12. case 0b00: printf(" No-Safety-Mechanism"); break;
  13. case 0b01: printf(" Lockstep"); break;
  14. case 0b10: printf(" Lockstep+SplitMode"); break;
  15. case 0b11: printf(" ASIL-B"); break;
  16. default: return;
  17. }
  18. }
  19. void show_vpu_degree(unsigned long degree)
  20. {
  21. switch (degree) {
  22. case 0b00: printf(" DLEN=VLEN/2"); break;
  23. case 0b01: printf(" DLEN=VLEN"); break;
  24. default: return;
  25. }
  26. }
  27. void print_size(unsigned long bytes)
  28. {
  29. if (bytes / GB) {
  30. printf(" %ld GB", bytes / GB);
  31. } else if (bytes / MB) {
  32. printf(" %ld MB", bytes / MB);
  33. } else if (bytes / KB) {
  34. printf(" %ld KB", bytes / KB);
  35. } else {
  36. printf(" %ld Byte", bytes);
  37. }
  38. }
  39. void show_cache_info(unsigned long set, unsigned long way, unsigned long lsize, unsigned long ecc)
  40. {
  41. print_size(set * way * lsize);
  42. printf("(set=%ld,", set);
  43. printf("way=%ld,", way);
  44. printf("lsize=%ld,", lsize);
  45. printf("ecc=%ld)\r\n", !!ecc);
  46. }
  47. void nuclei_cpuinfo(void)
  48. {
  49. CSR_MCFGINFO_Type mcfg;
  50. CSR_MICFGINFO_Type micfg;
  51. CSR_MDCFGINFO_Type mdcfg;
  52. CSR_MTLBCFGINFO_Type mtlbcfg;
  53. rv_csr_t iregion_base = 0;
  54. rv_csr_t csr_marchid = 0;
  55. rv_csr_t csr_mimpid = 0;
  56. rv_csr_t csr_misa = 0;
  57. rv_csr_t csr_mirgb = 0;
  58. rv_csr_t csr_mfiocfg = 0;
  59. rv_csr_t csr_mppicfg = 0;
  60. // CFG_CPU_NAME/CFG_CPU_VERSION/CPU_ISA are macros defined in cpufeature.h auto generated by nuclei_gen
  61. // nuclei_gen is our cpu ip generation tool
  62. #ifdef CFG_CPU_NAME
  63. printf("CPU NAME: %s\n", CFG_CPU_NAME);
  64. #endif
  65. #ifdef CFG_CPU_VERSION
  66. printf("CPU VERSION: %s\n", CFG_CPU_VERSION);
  67. #endif
  68. #ifdef CPU_ISA
  69. printf("CPU ISA: %s\n", CPU_ISA);
  70. #endif
  71. printf("\r\n-----Nuclei RISC-V CPU Configuration Information-----\r\n");
  72. /* ID and version */
  73. csr_marchid = __RV_CSR_READ(CSR_MARCHID);
  74. csr_mimpid = __RV_CSR_READ(CSR_MIMPID);
  75. printf(" MARCHID: 0x%lx\r\n", csr_marchid);
  76. printf(" MIMPID: 0x%lx\r\n", csr_mimpid);
  77. /* ISA */
  78. csr_misa = __RV_CSR_READ(CSR_MISA);
  79. printf(" ISA:");
  80. #if __RISCV_XLEN == 32
  81. printf(" RV32");
  82. #else
  83. printf(" RV64");
  84. #endif
  85. for (int i = 0; i < EXTENSION_NUM; i++) {
  86. if (csr_misa & BIT(i)) {
  87. if ('X' == ('A' + i)) {
  88. printf(" NICE");
  89. } else {
  90. printf(" %c", 'A' + i);
  91. }
  92. }
  93. }
  94. mcfg.d = __RV_CSR_READ(CSR_MCFG_INFO);
  95. if (mcfg.b.dsp_n1) {
  96. printf(" Xxldspn1x");
  97. }
  98. if (mcfg.b.dsp_n2) {
  99. printf(" Xxldspn2x");
  100. }
  101. if (mcfg.b.dsp_n3) {
  102. printf(" Xxldspn3x");
  103. }
  104. if (mcfg.b.zc_xlcz) {
  105. #if __RISCV_XLEN == 32
  106. printf(" Zc Xxlcz");
  107. #else
  108. printf(" Zc");
  109. #endif
  110. }
  111. if (mcfg.b.sec_mode) {
  112. printf(" Smwg");
  113. }
  114. printf("\r\n");
  115. /* Support */
  116. printf(" MCFG:");
  117. if (mcfg.b.tee) {
  118. printf(" TEE");
  119. }
  120. if (mcfg.b.ecc) {
  121. printf(" ECC");
  122. }
  123. if (mcfg.b.clic) {
  124. printf(" ECLIC");
  125. }
  126. if (mcfg.b.plic) {
  127. printf(" PLIC");
  128. }
  129. if (mcfg.b.fio) {
  130. printf(" FIO");
  131. }
  132. if (mcfg.b.ppi) {
  133. printf(" PPI");
  134. }
  135. if (mcfg.b.nice) {
  136. printf(" NICE");
  137. }
  138. if (mcfg.b.ilm) {
  139. printf(" ILM");
  140. }
  141. if (mcfg.b.dlm) {
  142. printf(" DLM");
  143. }
  144. if (mcfg.b.icache) {
  145. printf(" ICACHE");
  146. }
  147. if (mcfg.b.dcache) {
  148. printf(" DCACHE");
  149. }
  150. if (mcfg.b.smp) {
  151. printf(" SMP");
  152. }
  153. if (mcfg.b.dsp_n1) {
  154. printf(" DSP_N1");
  155. }
  156. if (mcfg.b.dsp_n2) {
  157. printf(" DSP_N2");
  158. }
  159. if (mcfg.b.dsp_n3) {
  160. printf(" DSP_N3");
  161. }
  162. if (mcfg.b.zc_xlcz) {
  163. #if __RISCV_XLEN == 32
  164. printf(" ZC_XLCZ_EXT");
  165. #else
  166. printf(" ZC_EXT");
  167. #endif
  168. }
  169. if (mcfg.b.iregion) {
  170. printf(" IREGION");
  171. }
  172. if (mcfg.b.sec_mode) {
  173. printf(" SEC_MODE");
  174. }
  175. if (mcfg.b.etrace) {
  176. printf(" ETRACE");
  177. }
  178. if (mcfg.b.vnice) {
  179. printf(" VNICE");
  180. }
  181. show_safety_mechanism(mcfg.b.safety_mecha);
  182. show_vpu_degree(mcfg.b.vpu_degree);
  183. printf("\r\n");
  184. /* ILM */
  185. if (mcfg.b.ilm) {
  186. micfg.d = __RV_CSR_READ(CSR_MICFG_INFO);
  187. printf(" ILM:");
  188. print_size(POWER_FOR_TWO(micfg.b.lm_size - 1) * 256);
  189. if (micfg.b.lm_xonly) {
  190. printf(" execute-only");
  191. }
  192. if (micfg.b.lm_ecc) {
  193. printf(" has-ecc");
  194. }
  195. printf("\r\n");
  196. }
  197. /* DLM */
  198. if (mcfg.b.dlm) {
  199. mdcfg.d = __RV_CSR_READ(CSR_MDCFG_INFO);
  200. printf(" DLM:");
  201. print_size(POWER_FOR_TWO(mdcfg.b.lm_size - 1) * 256);
  202. if (mdcfg.b.lm_ecc) {
  203. printf(" has-ecc");
  204. }
  205. printf("\r\n");
  206. }
  207. /* ICACHE */
  208. if (mcfg.b.icache) {
  209. micfg.d = __RV_CSR_READ(CSR_MICFG_INFO);
  210. printf(" ICACHE:");
  211. show_cache_info(POWER_FOR_TWO(micfg.b.set + 3), micfg.b.way + 1, POWER_FOR_TWO(micfg.b.lsize + 2), mcfg.b.ecc);
  212. }
  213. /* DCACHE */
  214. if (mcfg.b.dcache) {
  215. mdcfg.d = __RV_CSR_READ(CSR_MDCFG_INFO);
  216. printf(" DCACHE:");
  217. show_cache_info(POWER_FOR_TWO(mdcfg.b.set + 3), mdcfg.b.way + 1, POWER_FOR_TWO(mdcfg.b.lsize + 2), mcfg.b.ecc);
  218. }
  219. /* TLB only present with MMU, when PLIC present MMU will present */
  220. if (mcfg.b.plic) {
  221. mtlbcfg.d = __RV_CSR_READ(CSR_MTLBCFG_INFO);
  222. printf(" TLB:");
  223. printf(" MainTLB(set=%lu,way=%lu,entry=%lu,ecc=%lu) ITLB(entry=%lu) DTLB(entry=%lu)\r\n", \
  224. POWER_FOR_TWO(mtlbcfg.b.set + 3), mtlbcfg.b.way + 1, LINESZ(mtlbcfg.b.lsize), \
  225. mtlbcfg.b.ecc, LINESZ(mtlbcfg.b.i_size), LINESZ(mtlbcfg.b.d_size));
  226. }
  227. /* IREGION */
  228. if (mcfg.b.iregion) {
  229. rv_csr_t csr_mirgb = __RV_CSR_READ(CSR_MIRGB_INFO);
  230. printf(" IREGION:");
  231. iregion_base = csr_mirgb & (~0x3FF);
  232. printf(" %#lx", iregion_base);
  233. print_size(POWER_FOR_TWO(__RV_EXTRACT_FIELD(csr_mirgb, 0x1F << 1) - 1) * KB);
  234. printf("\r\n");
  235. printf(" Unit Size Address\r\n");
  236. printf(" INFO 64KB %#lx\r\n", iregion_base + IREGION_IINFO_OFS);
  237. printf(" DEBUG 64KB %#lx\r\n", iregion_base + IREGION_DEBUG_OFS);
  238. if (mcfg.b.clic) {
  239. printf(" ECLIC 64KB %#lx\r\n", iregion_base + IREGION_ECLIC_OFS);
  240. }
  241. printf(" TIMER 64KB %#lx\r\n", iregion_base + IREGION_TIMER_OFS);
  242. if (mcfg.b.smp) {
  243. printf(" SMP 64KB %#lx\r\n", iregion_base + IREGION_SMP_OFS);
  244. }
  245. rv_csr_t smp_cfg = *(rv_csr_t*)(iregion_base + 0x40004);
  246. if (mcfg.b.clic && (__RV_EXTRACT_FIELD(smp_cfg, 0x1F << 1) >= 2)) {
  247. printf(" CIDU 64KB %#lx\r\n", iregion_base + IREGION_IDU_OFS);
  248. }
  249. if (mcfg.b.plic) {
  250. printf(" PLIC 64MB %#lx\r\n", iregion_base + IREGION_PLIC_OFS);
  251. }
  252. /* SMP */
  253. if (mcfg.b.smp) {
  254. printf(" SMP_CFG:");
  255. printf(" CC_PRESENT=%ld", __RV_EXTRACT_FIELD(smp_cfg, 0x1));
  256. printf(" SMP_CORE_NUM=%ld", __RV_EXTRACT_FIELD(smp_cfg, 0x3F << 1));
  257. printf(" IOCP_NUM=%ld", __RV_EXTRACT_FIELD(smp_cfg, 0x3F << 7));
  258. printf(" PMON_NUM=%ld", __RV_EXTRACT_FIELD(smp_cfg, 0x3F << 13));
  259. printf("\r\n");
  260. }
  261. /* ECLIC */
  262. #if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
  263. if (mcfg.b.clic) {
  264. printf(" ECLIC:");
  265. printf(" VERSION=0x%x", (unsigned int)ECLIC_GetInfoVer());
  266. printf(" NUM_INTERRUPT=%u", (unsigned int)ECLIC_GetInfoNum());
  267. printf(" CLICINTCTLBITS=%u", (unsigned int)ECLIC_GetInfoCtlbits());
  268. printf(" MTH=%u", (unsigned int)ECLIC_GetMth());
  269. printf(" NLBITS=%u", (unsigned int)ECLIC_GetCfgNlbits());
  270. printf("\r\n");
  271. }
  272. #endif
  273. /* L2CACHE */
  274. if (smp_cfg & BIT(0)) {
  275. uint32_t cc_cfg = *(uint32_t *)(iregion_base + 0x40008);
  276. printf(" L2CACHE:");
  277. show_cache_info(POWER_FOR_TWO(__RV_EXTRACT_FIELD(cc_cfg, 0xF)), __RV_EXTRACT_FIELD(cc_cfg, 0xf << 4) + 1,
  278. POWER_FOR_TWO(__RV_EXTRACT_FIELD(cc_cfg, 0x7 << 8) + 2), cc_cfg & BIT(11));
  279. }
  280. /* INFO */
  281. printf(" INFO-Detail:\r\n");
  282. uint32_t mpasize = *(uint32_t *)(iregion_base);
  283. printf(" mpasize : %u\r\n", mpasize);
  284. uint32_t cmo_info = *(uint32_t*)(iregion_base + 4);
  285. if (cmo_info & BIT(0)) {
  286. printf(" cbozero : %uByte\r\n", (unsigned int)POWER_FOR_TWO(__RV_EXTRACT_FIELD(cmo_info, 0xF << 6) + 2));
  287. printf(" cmo : %uByte\r\n", (unsigned int)POWER_FOR_TWO(__RV_EXTRACT_FIELD(cmo_info, 0xF << 2) + 2));
  288. if (cmo_info & BIT(1)) {
  289. printf(" has_prefecth\r\n");
  290. }
  291. }
  292. uint32_t mcppi_cfg_lo = *(uint32_t *)(iregion_base + 0x80);
  293. uint32_t mcppi_cfg_hi = *(uint32_t *)(iregion_base + 0x84);
  294. if (mcppi_cfg_lo & 0x1) {
  295. #if __RISCV_XLEN == 32
  296. printf(" cppi : %#lx", mcppi_cfg_lo & (~0x3FF));
  297. #else
  298. printf(" cppi : %#lx", ((uint64_t)mcppi_cfg_hi << 32) | (mcppi_cfg_lo & (~0x3FF)));
  299. #endif
  300. print_size(POWER_FOR_TWO(__RV_EXTRACT_FIELD(mcppi_cfg_lo, 0x1F << 1) - 1) * KB);
  301. printf("\r\n");
  302. }
  303. }
  304. /* FIO */
  305. if (mcfg.b.fio) {
  306. csr_mfiocfg = __RV_CSR_READ(CSR_MFIOCFG_INFO);
  307. printf(" FIO:");
  308. printf(" %#lx", csr_mfiocfg & (~0x3FF));
  309. print_size(POWER_FOR_TWO(__RV_EXTRACT_FIELD(csr_mfiocfg, 0x1F << 1) - 1) * KB);
  310. printf("\r\n");
  311. }
  312. /* PPI */
  313. if (mcfg.b.ppi) {
  314. csr_mppicfg = __RV_CSR_READ(CSR_MPPICFG_INFO);
  315. printf(" PPI:");
  316. printf(" %#lx", csr_mppicfg & (~0x3FF));
  317. print_size(POWER_FOR_TWO(__RV_EXTRACT_FIELD(csr_mppicfg, 0x1F << 1) - 1) * KB);
  318. printf("\r\n");
  319. }
  320. printf("-----End of Nuclei CPU INFO-----\r\n");
  321. }
  322. int main(void)
  323. {
  324. nuclei_cpuinfo();
  325. return 0;
  326. }