main.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "cpuinfo.h"
  4. #include "nuclei_sdk_soc.h"
  5. #define BUFSIZE 2048
  6. volatile int ille_ins_flag = 0;
  7. void illegal_instruction_handler(unsigned long mcause, unsigned long sp) {
  8. ille_ins_flag = 1;
  9. EXC_Frame_Type *exc_frame = (EXC_Frame_Type *)sp;
  10. // read csr is a 4 bytes instruction
  11. // so we just add 4 to mepc to return to the next instruction
  12. exc_frame->epc += 4;
  13. }
  14. int main(void)
  15. {
  16. static char cpufeatbuf[BUFSIZE];
  17. #ifdef CFG_CPU_NAME
  18. printf("CPU NAME: %s\n", CFG_CPU_NAME);
  19. #endif
  20. #ifdef CFG_CPU_VERSION
  21. printf("CPU VERSION: %s\n", CFG_CPU_VERSION);
  22. #endif
  23. #ifdef CPU_ISA
  24. printf("CPU ISA: %s\n", CPU_ISA);
  25. #endif
  26. CPU_INFO_Group cpuinfo;
  27. memset(&cpuinfo, 0, sizeof(cpuinfo)); // clear the struct
  28. cpuinfo.marchid.d = (uint32_t)__RV_CSR_READ(CSR_MARCHID);
  29. cpuinfo.mhartid = (uint32_t)__RV_CSR_READ(CSR_MHARTID);
  30. cpuinfo.mimpid.d = (uint32_t)__RV_CSR_READ(CSR_MIMPID);
  31. cpuinfo.misa.d = (uint32_t)__RV_CSR_READ(CSR_MISA);
  32. U32_CSR_MCFG_INFO_Type mcfg;
  33. if (cpuinfo.marchid.d == 0x80000022U && cpuinfo.mimpid.d == 0x100U) {
  34. cpuinfo.mcfg_exist = 0;
  35. mcfg.d = 0;
  36. } else {
  37. cpuinfo.mcfg_exist = 1;
  38. mcfg.d = (uint32_t)__RV_CSR_READ(CSR_MCFG_INFO);
  39. }
  40. // NOTE: workaround for n100, since the CSR mcfg_info not present in n100,
  41. // but eclic and iregion present
  42. #if defined(CPU_SERIES) && CPU_SERIES == 100
  43. mcfg.d = 0;
  44. // mirgb_info csr present for n100 with eclic, this csr will not be zero
  45. if (__RV_CSR_READ(CSR_MIRGB_INFO) != 0) {
  46. mcfg.b.iregion = 1;
  47. mcfg.b.eclic = 1;
  48. } else {
  49. cpuinfo.mcfg_exist = 0;
  50. }
  51. #endif
  52. cpuinfo.mcfginfo = mcfg;
  53. if (__RISCV_XLEN == 32) {
  54. cpuinfo.xlen = 32;
  55. if (mcfg.b.plic) {
  56. cpuinfo.mtlbcfginfo.d = (uint32_t)__RV_CSR_READ(CSR_MTLBCFG_INFO);
  57. }
  58. } else {
  59. cpuinfo.xlen = 64;
  60. /**
  61. * mtlbcfginfo has a `mapping` field at the highest bit.
  62. * For RV64, move the bit 63 to bit 31 to use the common
  63. * struct as RV32.
  64. */
  65. if (mcfg.b.plic) {
  66. uint64_t mtlbcfginfo = __RV_CSR_READ(CSR_MTLBCFG_INFO);
  67. cpuinfo.mtlbcfginfo.d =
  68. (uint32_t)mtlbcfginfo | (uint32_t)((mtlbcfginfo >> 63) << 31);
  69. }
  70. }
  71. if (mcfg.b.icache || mcfg.b.ilm) {
  72. cpuinfo.micfginfo.d = (uint32_t)__RV_CSR_READ(CSR_MICFG_INFO);
  73. }
  74. if (mcfg.b.dcache || mcfg.b.dlm) {
  75. cpuinfo.mdcfginfo.d = (uint32_t)__RV_CSR_READ(CSR_MDCFG_INFO);
  76. }
  77. if (mcfg.b.iregion) {
  78. cpuinfo.mirgbinfo.d = (uint64_t)__RV_CSR_READ(CSR_MIRGB_INFO);
  79. uint64_t iregion_base = cpuinfo.mirgbinfo.d & (~0x3FFULL);
  80. cpuinfo.iinfo = (CIF_IINFO_Type *)((unsigned long)iregion_base);
  81. cpuinfo.iregion_base = iregion_base;
  82. if (mcfg.b.smp) {
  83. cpuinfo.smpcfg.d = *(uint32_t *)((
  84. unsigned long)(iregion_base + CPUINFO_IRG_SMP_OFS + 0x4));
  85. }
  86. if (cpuinfo.smpcfg.b.cc) {
  87. cpuinfo.cccfg.d = *(uint32_t *)((
  88. unsigned long)(iregion_base + CPUINFO_IRG_SMP_OFS + 0x8));
  89. }
  90. if (mcfg.b.eclic) {
  91. cpuinfo.eclic = (CIF_ECLIC_Type *)((
  92. unsigned long)(iregion_base + CPUINFO_IRG_ECLIC_OFS));
  93. }
  94. }
  95. if (mcfg.b.ppi) {
  96. cpuinfo.mppicfginfo.d = (uint64_t)__RV_CSR_READ(CSR_MPPICFG_INFO);
  97. }
  98. if (mcfg.b.fio) {
  99. cpuinfo.mfiocfginfo.d = (uint64_t)__RV_CSR_READ(CSR_MFIOCFG_INFO);
  100. }
  101. CIF_IINFO_ISA_SUPPORT0_Type isa_support0;
  102. #if defined(CPU_SERIES) && CPU_SERIES == 100
  103. isa_support0.d = 0;
  104. #else
  105. isa_support0.d = cpuinfo.iinfo->isa_support0;
  106. #endif
  107. /* The init value of vlenb is 0, indicating that the vector extension is not supported */
  108. cpuinfo.vlenb = 0;
  109. /* misa.V only valid when the full vector extension is supported.
  110. * Judge vector extension existence from isa_support0.vector is more reliable */
  111. if (cpuinfo.misa.b.V || (isa_support0.b.exist && isa_support0.b.vector)) {
  112. /* Set mstatus.vs to enable vector extension, then read vlenb */
  113. __RV_CSR_SET(CSR_MSTATUS, MSTATUS_VS_INITIAL);
  114. cpuinfo.vlenb = __RV_CSR_READ(CSR_VLENB);
  115. }
  116. /* Get miscellaneous information */
  117. #if defined(CPU_SERIES) && CPU_SERIES == 100
  118. cpuinfo.misc.b.pma_macro = 0;
  119. cpuinfo.misc.b.misaligned_access = 1;
  120. cpuinfo.misc.b.cidu_exist = 0;
  121. #else
  122. /* Check PMA_MACRO by reading `mmacro_dev_en`, if no exception then PMA_MACRO is supported */
  123. unsigned long old_handler = Exception_Get_EXC(IlleIns_EXCn);
  124. ille_ins_flag = 0;
  125. Exception_Register_EXC(IlleIns_EXCn, (unsigned long)illegal_instruction_handler);
  126. rv_csr_t mmacro_dev_en = __RV_CSR_READ(CSR_MMACRO_DEV_EN);
  127. /* Restore the default exception handler */
  128. Exception_Register_EXC(IlleIns_EXCn, old_handler);
  129. cpuinfo.misc.b.pma_macro = !ille_ins_flag;
  130. /* Check MISALIGNED_ACCESS by reading mmisc_ctl register */
  131. CSR_MMISC_CTL_Type mmisc_ctl;
  132. mmisc_ctl.d = (uint32_t)__RV_CSR_READ(CSR_MMISC_CTL);
  133. cpuinfo.misc.b.misaligned_access = mmisc_ctl.b.misalign;
  134. /* Check CIDU by CIDU interrupt number */
  135. if (mcfg.b.iregion) {
  136. unsigned long cidu_addr = (unsigned long)cpuinfo.iregion_base + CPUINFO_IRG_IDU_OFS;
  137. const uint32_t *cidu_int_num_addr = (const uint32_t *)(cidu_addr + CIF_CIDU_INT_NUM_OFS);
  138. cpuinfo.misc.b.cidu_exist = !!(*cidu_int_num_addr);
  139. }
  140. #endif
  141. if (get_basic_cpuinfo(&cpuinfo, cpufeatbuf, BUFSIZE) > 0) {
  142. printf("%s\r\n", cpufeatbuf);
  143. }
  144. show_cpuinfo(&cpuinfo);
  145. return 0;
  146. }