cpuinfo.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  1. #include "cpuinfo.h"
  2. #include "cpuinfo_cfg.h"
  3. #include <string.h>
  4. #define BIT(ofs) (0x1U << (ofs))
  5. #define EXTENSION_NUM (26)
  6. #define POW2(n) (1U << (n))
  7. #define LINESZ(n) ((n) > 0U ? POW2((n) - 1) : 0)
  8. /* Check register field with default field name print */
  9. #define CHECK_FIELD_DFT(reg, field) \
  10. if (reg.b.field) { \
  11. CIF_PRINTF(" %s", #field); \
  12. }
  13. /* Check register field with string specified */
  14. #define CHECK_FIELD(reg, field, str) \
  15. if (reg.b.field) { \
  16. CIF_PRINTF(" %s", str); \
  17. }
  18. /* Show register value */
  19. #define SHOW_VALUE(reg, field) \
  20. CIF_PRINTF(" %s=%u\r\n", #field, reg.b.field);
  21. #define STRCAT_BUF(buf, fmt, ...) \
  22. snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt, ##__VA_ARGS__)
  23. #define CHECK_STRCAT_BUF(reg, field, buf, fmt, ...) \
  24. do { \
  25. if (reg.b.field) { \
  26. STRCAT_BUF(buf, fmt, ##__VA_ARGS__); \
  27. } \
  28. } while (0)
  29. #define BASIC_CPUINFO_FMT "Nuclei CPU Detected: mhartid-0x%x marchid-0x%04x v%d.%d.%d, ISA: RV%d%s"
  30. /** `BUF_SIZE` is the size of string buffer in `get_basic_cpuinfo`
  31. */
  32. #ifndef BUF_SIZE
  33. #define BUF_SIZE (1024)
  34. #endif
  35. static void show_isa(uint32_t xlen, U32_CSR_MISA_Type misa,
  36. U32_CSR_MCFG_INFO_Type mcfg);
  37. static void show_mcfg(const CPU_INFO_Group *cpuinfo);
  38. static void show_feature(const CPU_INFO_Group *cpuinfo);
  39. static void show_micfg_mdcfg(U32_CSR_MCFG_INFO_Type mcfg,
  40. U32_CSR_MICFG_INFO_Type micfg,
  41. U32_CSR_MDCFG_INFO_Type mdcfg);
  42. static void show_mtlbcfg(U32_CSR_MCFG_INFO_Type mcfg,
  43. U32_CSR_MTLBCFG_INFO_Type mtlbcfg);
  44. static void show_iregion(const CPU_INFO_Group *cpuinfo);
  45. static void show_mfiocfg(U32_CSR_MCFG_INFO_Type mcfg,
  46. U64_CSR_MFIOCFG_INFO_Type mfiocfg);
  47. static void show_mppicfg(U32_CSR_MCFG_INFO_Type mcfg,
  48. U64_CSR_MPPICFG_INFO_Type mppicfg);
  49. static void show_prefetch_cfg(CIF_IINFO_Type *iinfo);
  50. static void show_isa_support(CIF_IINFO_Type *iinfo);
  51. static void show_mvlm_cfg(CIF_IINFO_Type *iinfo);
  52. static void show_flash_bus(CIF_IINFO_Type *iinfo);
  53. static void show_mem_region_cfg(CIF_IINFO_Type *iinfo);
  54. static void show_mcppi_cfg(CIF_IINFO_Type *iinfo);
  55. static void show_cmo(CIF_IINFO_Type *iinfo);
  56. static void show_performance_cfg(CIF_IINFO_Type *iinfo);
  57. static void show_misc_cfg(CIF_IINFO_Type *iinfo);
  58. static void show_sec_cfg(CIF_IINFO_Type *iinfo);
  59. /**
  60. * Convert to human readable size with option
  61. * \param size: size in bytes
  62. * \param lite: !=0 for lite version
  63. */
  64. static char *cvt_size_opt(uint32_t size, int lite);
  65. #define cvt_size(size) cvt_size_opt(size, 0)
  66. static void show_cache_info(uint32_t set, uint32_t way, uint32_t lsize,
  67. uint32_t ecc);
  68. void show_cpuinfo(const CPU_INFO_Group *cpuinfo)
  69. {
  70. if (cpuinfo == NULL) {
  71. return;
  72. }
  73. if (cpuinfo->misa.d == 0) {
  74. CIF_PRINTF("\r\n-----Invalid RISC-V MISA CSR found, no CPU Information could be dumped-----\r\n");
  75. return;
  76. }
  77. CIF_PRINTF("\r\n-----Nuclei RISC-V CPU Configuration Information-----\r\n");
  78. /* ID and version */
  79. CIF_PRINTF(" MARCHID: 0x%04x\r\n", cpuinfo->marchid.d);
  80. CIF_PRINTF(" MHARTID: 0x%x\r\n", cpuinfo->mhartid);
  81. CIF_PRINTF(" MIMPID: 0x%06x\r\n", cpuinfo->mimpid.d);
  82. /* ISA */
  83. show_isa(cpuinfo->xlen, cpuinfo->misa, cpuinfo->mcfginfo);
  84. /* Support */
  85. show_mcfg(cpuinfo);
  86. /* Features */
  87. show_feature(cpuinfo);
  88. /* ILM, DLM, I/D Cache */
  89. show_micfg_mdcfg(cpuinfo->mcfginfo, cpuinfo->micfginfo, cpuinfo->mdcfginfo);
  90. /* TLB */
  91. show_mtlbcfg(cpuinfo->mcfginfo, cpuinfo->mtlbcfginfo);
  92. /* FIO */
  93. show_mfiocfg(cpuinfo->mcfginfo, cpuinfo->mfiocfginfo);
  94. /* PPI */
  95. show_mppicfg(cpuinfo->mcfginfo, cpuinfo->mppicfginfo);
  96. /* IREGION */
  97. show_iregion(cpuinfo);
  98. CIF_PRINTF("-----End of Nuclei CPU INFO-----\r\n");
  99. }
  100. int get_basic_cpuinfo(const CPU_INFO_Group *cpuinfo, char *str, unsigned long len)
  101. {
  102. if (str == NULL || cpuinfo == NULL) {
  103. return -1;
  104. }
  105. if (cpuinfo->misa.d == 0) {
  106. return -1;
  107. }
  108. char isa[EXTENSION_NUM + 1];
  109. /* construct ISA string */
  110. int pos = 0;
  111. for (int i = 0; i < EXTENSION_NUM; ++i) {
  112. if (cpuinfo->misa.d & BIT(i)) {
  113. isa[pos++] = 'A' + i;
  114. }
  115. }
  116. isa[pos] = '\0';
  117. /* get features string */
  118. const char *features = get_cpu_feature(cpuinfo);
  119. if (strlen(features) == 0) {
  120. goto simple;
  121. }
  122. return snprintf(str, len, BASIC_CPUINFO_FMT ", Feature: %s", cpuinfo->mhartid,
  123. cpuinfo->marchid.d, cpuinfo->mimpid.b.first_vernum,
  124. cpuinfo->mimpid.b.mid_vernum, cpuinfo->mimpid.b.last_vernum,
  125. cpuinfo->xlen, isa, features);
  126. simple:
  127. return snprintf(str, len, BASIC_CPUINFO_FMT, cpuinfo->mhartid, cpuinfo->marchid.d,
  128. cpuinfo->mimpid.b.first_vernum, cpuinfo->mimpid.b.mid_vernum,
  129. cpuinfo->mimpid.b.last_vernum, cpuinfo->xlen, isa);
  130. }
  131. const char *get_cpu_feature(const CPU_INFO_Group *cpuinfo)
  132. {
  133. static char buf[BUF_SIZE] = {0}; // features string buffer
  134. buf[0] = '\0'; // clear the buffer each time call this function
  135. U32_CSR_MCFG_INFO_Type mcfg = cpuinfo->mcfginfo;
  136. U32_CSR_MISA_Type misa = cpuinfo->misa;
  137. U32_CSR_MARCHID_Type marchid = cpuinfo->marchid;
  138. CIF_MISC_Type misc = cpuinfo->misc;
  139. const CIF_ECLIC_Type *eclic = cpuinfo->eclic;
  140. const CIF_IINFO_Type *iinfo = cpuinfo->iinfo;
  141. CIF_IINFO_ISA_SUPPORT0_Type isa_support0;
  142. CIF_IINFO_SEC_CFG_INFO_Type sec_cfg;
  143. CIF_IINFO_PERFORMANCE_CFG1_Type performance_cfg1;
  144. if (marchid.d == 0x100U) {
  145. // N100 has no iregion info registers
  146. isa_support0.d = 0;
  147. sec_cfg.d = 0;
  148. performance_cfg1.d = 0;
  149. // eclic present with systimer
  150. if (mcfg.b.eclic) {
  151. STRCAT_BUF(buf, "ECLIC-v%d, ", eclic->info.b.version);
  152. STRCAT_BUF(buf, "SYSTIMER, ");
  153. // N100 has EXCP along with eclic
  154. STRCAT_BUF(buf, "EXCP, ");
  155. } else {
  156. STRCAT_BUF(buf, "IRQC, ");
  157. STRCAT_BUF(buf, "TIMER, ");
  158. }
  159. // N100 has no PMA
  160. } else {
  161. isa_support0.d = iinfo->isa_support0;
  162. sec_cfg.d = iinfo->sec_cfg_info;
  163. performance_cfg1.d = iinfo->performance_cfg1;
  164. // ECLIC v1/v2
  165. CHECK_STRCAT_BUF(mcfg, eclic, buf, "ECLIC-v%d, ",
  166. eclic->info.b.version);
  167. // SYSTIMER is always present except N100
  168. STRCAT_BUF(buf, "SYSTIMER, ");
  169. // EXCP is always present except N100
  170. STRCAT_BUF(buf, "EXCP, ");
  171. // PMA is always present except N100
  172. STRCAT_BUF(buf, "PMA, ");
  173. }
  174. // SMPCC
  175. CHECK_STRCAT_BUF(mcfg, smp, buf, "SMPCC, ");
  176. // PMP
  177. if (misa.b.S || misa.b.U) {
  178. STRCAT_BUF(buf, "PMP, ");
  179. }
  180. // SMEPMP
  181. if (isa_support0.b.exist) {
  182. CHECK_STRCAT_BUF(isa_support0, smepmp, buf, "SMEPMP, ");
  183. }
  184. // NICE
  185. CHECK_STRCAT_BUF(mcfg, nice, buf, "NICE, ");
  186. // VNICE
  187. CHECK_STRCAT_BUF(mcfg, vnice, buf, "VNICE, ");
  188. // ILM
  189. CHECK_STRCAT_BUF(mcfg, ilm, buf, "ILM, ");
  190. // DLM
  191. CHECK_STRCAT_BUF(mcfg, dlm, buf, "DLM, ");
  192. // ICACHE
  193. CHECK_STRCAT_BUF(mcfg, icache, buf, "ICACHE, ");
  194. // DCACHE
  195. CHECK_STRCAT_BUF(mcfg, dcache, buf, "DCACHE, ");
  196. // UMODE
  197. CHECK_STRCAT_BUF(misa, U, buf, "UMODE, ");
  198. // STACK_CHECK
  199. if (sec_cfg.b.security) {
  200. CHECK_STRCAT_BUF(sec_cfg, stack_check, buf, "STACK_CHECK, ");
  201. }
  202. // AMO
  203. CHECK_STRCAT_BUF(misa, A, buf, "AMO, ");
  204. // ECC
  205. CHECK_STRCAT_BUF(mcfg, ecc, buf, "ECC, ");
  206. // HPM v1/v2
  207. if (performance_cfg1.b.exist) {
  208. CHECK_STRCAT_BUF(performance_cfg1, hpm_ver, buf, "HPM-v%d, ",
  209. performance_cfg1.b.hpm_ver);
  210. }
  211. // CCM
  212. if (mcfg.b.icache || mcfg.b.dcache) {
  213. STRCAT_BUF(buf, "CCM, ");
  214. }
  215. // TEE and SMPU, if TEE is present, SMPU is also present
  216. CHECK_STRCAT_BUF(mcfg, tee, buf, "TEE, SMPU, ");
  217. // SSTC
  218. CHECK_STRCAT_BUF(mcfg, sstc, buf, "SSTC, ");
  219. // SMODE
  220. CHECK_STRCAT_BUF(misa, S, buf, "SMODE, ");
  221. // PLIC
  222. CHECK_STRCAT_BUF(mcfg, plic, buf, "PLIC, ");
  223. // PMA_MACRO
  224. CHECK_STRCAT_BUF(misc, pma_macro, buf, "PMA_MACRO, ");
  225. // MISALIGNED_ACCESS
  226. CHECK_STRCAT_BUF(misc, misaligned_access, buf, "MISALIGNED_ACCESS, ");
  227. // CIDU exist when CIDU interrupt number > 0
  228. CHECK_STRCAT_BUF(misc, cidu_exist, buf, "CIDU, ");
  229. /* remove the comma at the end */
  230. size_t buf_len = strlen(buf);
  231. if (buf_len > 1 && buf[buf_len - 2] == ',') {
  232. buf[buf_len - 2] = '\0';
  233. }
  234. return buf;
  235. }
  236. static void show_isa(uint32_t xlen, U32_CSR_MISA_Type misa,
  237. U32_CSR_MCFG_INFO_Type mcfg)
  238. {
  239. CIF_PRINTF(" ISA:");
  240. CIF_PRINTF(" RV%d", xlen);
  241. for (int i = 0; i < EXTENSION_NUM; i++) {
  242. if (misa.d & BIT(i)) {
  243. if ('X' == ('A' + i)) {
  244. CIF_PRINTF(" NICE");
  245. } else {
  246. CIF_PRINTF(" %c", 'A' + i);
  247. }
  248. }
  249. }
  250. CHECK_FIELD(mcfg, dsp_n1, "Xxldspn1x");
  251. CHECK_FIELD(mcfg, dsp_n2, "Xxldspn2x");
  252. CHECK_FIELD(mcfg, dsp_n3, "Xxldspn3x");
  253. if (mcfg.b.zc_xlcz) {
  254. if (mcfg.b.xlcz == 0) {
  255. CIF_PRINTF(" Zc Xxlcz");
  256. } else {
  257. CIF_PRINTF(" Zc");
  258. }
  259. }
  260. CHECK_FIELD(mcfg, zilsd, "Zilsd");
  261. CIF_PRINTF("\r\n");
  262. }
  263. static void show_mcfg(const CPU_INFO_Group *cpuinfo)
  264. {
  265. if (!cpuinfo->mcfg_exist) {
  266. return;
  267. }
  268. U32_CSR_MCFG_INFO_Type mcfg = cpuinfo->mcfginfo;
  269. CIF_PRINTF(" MCFG:");
  270. CHECK_FIELD(mcfg, tee, "TEE")
  271. CHECK_FIELD(mcfg, ecc, "ECC")
  272. CHECK_FIELD(mcfg, eclic, "ECLIC")
  273. CHECK_FIELD(mcfg, plic, "PLIC")
  274. CHECK_FIELD(mcfg, fio, "FIO")
  275. CHECK_FIELD(mcfg, ppi, "PPI")
  276. CHECK_FIELD(mcfg, nice, "NICE")
  277. CHECK_FIELD(mcfg, ilm, "ILM")
  278. CHECK_FIELD(mcfg, dlm, "DLM")
  279. CHECK_FIELD(mcfg, icache, "ICACHE")
  280. CHECK_FIELD(mcfg, dcache, "DCACHE")
  281. CHECK_FIELD(mcfg, smp, "SMP")
  282. CHECK_FIELD(mcfg, iregion, "IREGION")
  283. CHECK_FIELD(mcfg, sec_mode, "SMWG")
  284. CHECK_FIELD(mcfg, etrace, "ETRACE")
  285. CHECK_FIELD(mcfg, vnice, "VNICE")
  286. CHECK_FIELD(mcfg, sstc, "SSTC")
  287. switch (mcfg.b.safety_mecha) {
  288. case 0b00:
  289. CIF_PRINTF(" No-Safety-Mechanism");
  290. break;
  291. case 0b01:
  292. CIF_PRINTF(" Lockstep");
  293. break;
  294. case 0b10:
  295. CIF_PRINTF(" Lockstep+SplitMode");
  296. break;
  297. case 0b11:
  298. CIF_PRINTF(" ASIL-B");
  299. break;
  300. default:
  301. break;
  302. }
  303. if (cpuinfo->vlenb >0) {
  304. switch (mcfg.b.vpu_degree) {
  305. case 0b00:
  306. CIF_PRINTF(" DLEN=VLEN/2");
  307. break;
  308. case 0b01:
  309. CIF_PRINTF(" DLEN=VLEN");
  310. break;
  311. default:
  312. break;
  313. }
  314. CIF_PRINTF(" VLEN=%u", cpuinfo->vlenb * 8);
  315. }
  316. CIF_PRINTF("\r\n");
  317. }
  318. static void show_feature(const CPU_INFO_Group *cpuinfo)
  319. {
  320. const char *features= get_cpu_feature(cpuinfo);
  321. if (strlen(features) > 0) {
  322. CIF_PRINTF(" FEATURE: %s\r\n", features);
  323. }
  324. }
  325. static void show_micfg_mdcfg(U32_CSR_MCFG_INFO_Type mcfg,
  326. U32_CSR_MICFG_INFO_Type micfg,
  327. U32_CSR_MDCFG_INFO_Type mdcfg)
  328. {
  329. /* ILM */
  330. if (mcfg.b.ilm) {
  331. CIF_PRINTF(" ILM:");
  332. CIF_PRINTF(" %s", cvt_size(POW2(micfg.b.lm_size + 7)));
  333. CHECK_FIELD(micfg, lm_xonly, "execute-only");
  334. CHECK_FIELD(micfg, lm_ecc, "has-ecc");
  335. CHECK_FIELD(micfg, i_share_dlm, "share-dlm");
  336. CIF_PRINTF("\r\n");
  337. }
  338. /* DLM */
  339. if (mcfg.b.dlm) {
  340. CIF_PRINTF(" DLM:");
  341. CIF_PRINTF(" %s", cvt_size(POW2(mdcfg.b.lm_size + 7)));
  342. CHECK_FIELD(mdcfg, lm_ecc, "has-ecc");
  343. CIF_PRINTF("\r\n");
  344. }
  345. /* ICACHE */
  346. if (mcfg.b.icache) {
  347. CIF_PRINTF(" ICACHE:");
  348. show_cache_info(POW2(micfg.b.set + 3), micfg.b.way + 1,
  349. POW2(micfg.b.lsize + 2), mcfg.b.ecc);
  350. }
  351. /* DCACHE */
  352. if (mcfg.b.dcache) {
  353. CIF_PRINTF(" DCACHE:");
  354. show_cache_info(POW2(mdcfg.b.set + 3), mdcfg.b.way + 1,
  355. POW2(mdcfg.b.lsize + 2), mcfg.b.ecc);
  356. }
  357. }
  358. static void show_mtlbcfg(U32_CSR_MCFG_INFO_Type mcfg,
  359. U32_CSR_MTLBCFG_INFO_Type mtlbcfg)
  360. {
  361. /* TLB only present with MMU, when PLIC present MMU will present */
  362. if (mcfg.b.plic) {
  363. if (mtlbcfg.nb.mapping == 1) {
  364. CIF_PRINTF(" TLB:");
  365. CIF_PRINTF(" MainTLB(entry=%u,way=%u,ecc=%u)",
  366. POW2(mtlbcfg.nb.set + 3), mtlbcfg.nb.way + 1,
  367. mtlbcfg.nb.ecc);
  368. CIF_PRINTF(" ITLB(entry=%u) DTLB(entry=%u)\r\n",
  369. mtlbcfg.nb.i_size + 1, mtlbcfg.nb.d_size + 1);
  370. } else {
  371. CIF_PRINTF(" TLB:");
  372. CIF_PRINTF(" MainTLB(entry=%u,way=%u,ecc=%u)",
  373. POW2(mtlbcfg.b.set + 3), mtlbcfg.b.way + 1,
  374. mtlbcfg.b.ecc);
  375. CIF_PRINTF(" ITLB(entry=%u) DTLB(entry=%u)\r\n",
  376. LINESZ(mtlbcfg.b.i_size), LINESZ(mtlbcfg.b.d_size));
  377. }
  378. }
  379. }
  380. static void show_iregion(const CPU_INFO_Group *cpuinfo)
  381. {
  382. U32_CSR_MCFG_INFO_Type mcfg = cpuinfo->mcfginfo;
  383. if (!mcfg.b.iregion) {
  384. return;
  385. }
  386. CIF_PRINTF(" IREGION:");
  387. U64_CSR_MIRGB_INFO_Type mirgb = cpuinfo->mirgbinfo;
  388. uint64_t iregion_base = cpuinfo->iregion_base;
  389. CIF_PRINTF(" %#" CIF_PRIxADDR "", (addr_t)iregion_base);
  390. CIF_PRINTF(" %s\r\n", cvt_size(POW2(mirgb.b.iregion_size + 9)));
  391. CIF_PRINTF(" Unit Size Address\r\n");
  392. CIF_PRINTF(" IINFO 64KB 0x%" CIF_PRIxADDR "\r\n",
  393. (addr_t)iregion_base + CPUINFO_IRG_IINFO_OFS);
  394. CIF_PRINTF(" DEBUG 64KB %#" CIF_PRIxADDR "\r\n",
  395. (addr_t)iregion_base + CPUINFO_IRG_DEBUG_OFS);
  396. if (mcfg.b.eclic) {
  397. CIF_PRINTF(" ECLIC 64KB %#" CIF_PRIxADDR "\r\n",
  398. (addr_t)iregion_base + CPUINFO_IRG_ECLIC_OFS);
  399. }
  400. CIF_PRINTF(" TIMER 64KB %#" CIF_PRIxADDR "\r\n",
  401. (addr_t)iregion_base + CPUINFO_IRG_TIMER_OFS);
  402. if (mcfg.b.smp) {
  403. CIF_PRINTF(" SMP 64KB %#" CIF_PRIxADDR "\r\n",
  404. (addr_t)iregion_base + CPUINFO_IRG_SMP_OFS);
  405. }
  406. U32_SMP_CFG_Type smp_cfg = cpuinfo->smpcfg;
  407. /* If has eclic and has equal or more than 1 core, CIDU will present
  408. * The actual core number is `smp_core_num + 1` */
  409. if (mcfg.b.eclic && (smp_cfg.b.smp_core_num >= 1)) {
  410. CIF_PRINTF(" CIDU 64KB %#" CIF_PRIxADDR "\r\n",
  411. (addr_t)iregion_base + CPUINFO_IRG_IDU_OFS);
  412. }
  413. if (mcfg.b.plic) {
  414. CIF_PRINTF(" PLIC 64MB %#" CIF_PRIxADDR "\r\n",
  415. (addr_t)iregion_base + CPUINFO_IRG_PLIC_OFS);
  416. }
  417. /* SMP */
  418. if (mcfg.b.smp) {
  419. CIF_PRINTF(" SMP_CFG:");
  420. CIF_PRINTF(" CC_PRESENT=%d", smp_cfg.b.cc);
  421. CIF_PRINTF(" SMP_NUM=%d", smp_cfg.b.smp_core_num + 1);
  422. CIF_PRINTF(" IOCP_NUM=%d", smp_cfg.b.iocp_num);
  423. CIF_PRINTF(" PMON_NUM=%d", smp_cfg.b.pmon_num);
  424. CIF_PRINTF("\r\n");
  425. }
  426. /* ECLIC */
  427. if (mcfg.b.eclic) {
  428. CIF_ECLIC_Type *eclic = cpuinfo->eclic;
  429. U32_ECLIC_INFO_Type eclic_info = eclic->info;
  430. CIF_PRINTF(" ECLIC:");
  431. CIF_PRINTF(" VERSION=0x%x", eclic_info.b.version);
  432. CIF_PRINTF(" NUM_INTERRUPT=%u", eclic_info.b.num_interrupt);
  433. CIF_PRINTF(" CLICINTCTLBITS=%u", eclic_info.b.clicintctlbits);
  434. CIF_PRINTF(" MTH=%u", eclic->mth);
  435. CIF_PRINTF(" NLBITS=%u", (eclic->cfg & 0x1E) >> 1);
  436. CIF_PRINTF("\r\n");
  437. }
  438. /* L2CACHE */
  439. if (smp_cfg.b.cc) {
  440. U32_CC_CFG_Type cc_cfg = cpuinfo->cccfg;
  441. CIF_PRINTF(" L2CACHE:");
  442. show_cache_info(POW2(cc_cfg.b.set), cc_cfg.b.way + 1,
  443. POW2(cc_cfg.b.lsize + 2), cc_cfg.b.ecc);
  444. }
  445. // NOTE: mpasize always have, and is PA_SIZE of RTL configuration
  446. // if it is 0, it means it dont have IINFO region
  447. if (cpuinfo->iinfo->mpasize == 0) {
  448. return;
  449. }
  450. /* IREGION INFO */
  451. CIF_PRINTF(" INFO-Detail:\r\n");
  452. /* MPASIZE */
  453. uint32_t mpasize = cpuinfo->iinfo->mpasize;
  454. CIF_PRINTF(" mpasize : %u\r\n", mpasize);
  455. /* prefetch related registers */
  456. show_prefetch_cfg(cpuinfo->iinfo);
  457. /* ISA_SUPPORT VPU_CFG_INFO */
  458. show_isa_support(cpuinfo->iinfo);
  459. /* MVLM_CFG */
  460. show_mvlm_cfg(cpuinfo->iinfo);
  461. /* FLASH_BASE_ADDR */
  462. show_flash_bus(cpuinfo->iinfo);
  463. /* MEM_REGION_CFG */
  464. show_mem_region_cfg(cpuinfo->iinfo);
  465. /* MCPPI_CFG */
  466. show_mcppi_cfg(cpuinfo->iinfo);
  467. /* CMO_INFO */
  468. show_cmo(cpuinfo->iinfo);
  469. /* PERFORMANCE_CFG */
  470. show_performance_cfg(cpuinfo->iinfo);
  471. /* SEC_CFG_INFO */
  472. show_sec_cfg(cpuinfo->iinfo);
  473. /* MERGEL1DCTRL and ACCESS_CTRL */
  474. show_misc_cfg(cpuinfo->iinfo);
  475. }
  476. static void show_mfiocfg(U32_CSR_MCFG_INFO_Type mcfg,
  477. U64_CSR_MFIOCFG_INFO_Type mfiocfg)
  478. {
  479. if (mcfg.b.fio) {
  480. CIF_PRINTF(" FIO:");
  481. CIF_PRINTF(" %#" CIF_PRIxADDR "", (addr_t)((uint64_t)mfiocfg.d & (~0x3FFULL)));
  482. CIF_PRINTF(" %s\r\n", cvt_size(POW2(mfiocfg.b.fio_size + 9)));
  483. }
  484. }
  485. static void show_mppicfg(U32_CSR_MCFG_INFO_Type mcfg,
  486. U64_CSR_MPPICFG_INFO_Type mppicfg)
  487. {
  488. if (mcfg.b.ppi) {
  489. CIF_PRINTF(" PPI:");
  490. CIF_PRINTF(" %#" CIF_PRIxADDR "", (addr_t)((uint64_t)mppicfg.d & (~0x3FFULL)));
  491. CIF_PRINTF(" %s\r\n", cvt_size(POW2(mppicfg.b.ppi_size + 9)));
  492. }
  493. }
  494. static void show_prefetch_cfg(CIF_IINFO_Type *iinfo)
  495. {
  496. CIF_IINFO_PFL1INFO_Type pfl1info;
  497. pfl1info.d = iinfo->pfl1info;
  498. if (pfl1info.b.pf_cfg) {
  499. CIF_PRINTF(" prefetch: present\r\n");
  500. const char *pf_cfg[] = {"none", "normal", "high performance"};
  501. if (pfl1info.b.pf_cfg < 3) {
  502. CIF_PRINTF(" prefetch_mode: %s\r\n",
  503. pf_cfg[pfl1info.b.pf_cfg]);
  504. }
  505. if (iinfo->pfl1dctrl4 & BIT(0)) {
  506. CIF_PRINTF(" status: enable\r\n");
  507. } else {
  508. CIF_PRINTF(" status: disable\r\n");
  509. }
  510. if (pfl1info.b.pf_ver) {
  511. CIF_PRINTF(" version=%u\r\n",
  512. pfl1info.b.pf_ver);
  513. }
  514. /* prefetch config */
  515. CIF_IINFO_PFL1DCTRL1_Type pfl1dctrl1;
  516. CIF_IINFO_PFL1DCTRL2_Type pfl1dctrl2;
  517. CIF_IINFO_PFL1DCTRL3_Type pfl1dctrl3;
  518. pfl1dctrl1.d = iinfo->pfl1dctrl1;
  519. pfl1dctrl2.d = iinfo->pfl1dctrl2;
  520. pfl1dctrl3.d = iinfo->pfl1dctrl3;
  521. SHOW_VALUE(pfl1info, l2_pf_lbuf_num);
  522. SHOW_VALUE(pfl1info, l2_pf_dbuf_num);
  523. SHOW_VALUE(pfl1dctrl1, l1d_ena);
  524. SHOW_VALUE(pfl1dctrl1, cc_ena);
  525. SHOW_VALUE(pfl1dctrl1, scalar_ena);
  526. SHOW_VALUE(pfl1dctrl1, vector_ena);
  527. SHOW_VALUE(pfl1dctrl1, write_pref_ena);
  528. SHOW_VALUE(pfl1dctrl1, cross_page_pref_ena);
  529. SHOW_VALUE(pfl1dctrl1, pref_conflict_stop_th);
  530. SHOW_VALUE(pfl1dctrl1, pref_conflict_decr_sel);
  531. SHOW_VALUE(pfl1dctrl2, degree_incr_th);
  532. SHOW_VALUE(pfl1dctrl2, degree_decr_th);
  533. SHOW_VALUE(pfl1dctrl2, next_line_ena_th);
  534. SHOW_VALUE(pfl1dctrl2, write_noalloc_l1_th);
  535. SHOW_VALUE(pfl1dctrl2, write_noalloc_l2_th);
  536. SHOW_VALUE(pfl1dctrl3, max_stream_l1_degree);
  537. SHOW_VALUE(pfl1dctrl3, max_stream_l2_degree);
  538. SHOW_VALUE(pfl1dctrl3, max_stride_cplx_l1_degree);
  539. SHOW_VALUE(pfl1dctrl3, max_stride_cplx_l2_degree);
  540. } else {
  541. CIF_PRINTF(" prefetch: absent\r\n");
  542. }
  543. }
  544. static void show_isa_support(CIF_IINFO_Type *iinfo)
  545. {
  546. CIF_IINFO_ISA_SUPPORT0_Type isa_support0;
  547. CIF_IINFO_ISA_SUPPORT1_Type isa_support1;
  548. isa_support0.d = iinfo->isa_support0;
  549. isa_support1.d = iinfo->isa_support1;
  550. if (isa_support0.b.exist || isa_support1.b.exist) {
  551. CIF_PRINTF(" isa supported: present\r\n");
  552. CIF_PRINTF(" extension_list:");
  553. if (isa_support0.b.exist) {
  554. CHECK_FIELD_DFT(isa_support0, vector);
  555. CHECK_FIELD_DFT(isa_support0, smepmp);
  556. CHECK_FIELD_DFT(isa_support0, sscofpmf);
  557. CHECK_FIELD_DFT(isa_support0, zfh);
  558. CHECK_FIELD_DFT(isa_support0, zfhmin);
  559. CHECK_FIELD_DFT(isa_support0, zfa);
  560. CHECK_FIELD_DFT(isa_support0, svnapot);
  561. CHECK_FIELD_DFT(isa_support0, svpbmt);
  562. CHECK_FIELD_DFT(isa_support0, svinval);
  563. CHECK_FIELD_DFT(isa_support0, bf16);
  564. CHECK_FIELD_DFT(isa_support0, zimop);
  565. CHECK_FIELD_DFT(isa_support0, zcmop);
  566. CHECK_FIELD_DFT(isa_support0, zicond);
  567. CHECK_FIELD_DFT(isa_support0, zihintntl);
  568. CHECK_FIELD_DFT(isa_support0, zihintpause);
  569. CHECK_FIELD_DFT(isa_support0, smrnmi);
  570. CHECK_FIELD_DFT(isa_support0, zihpm);
  571. CHECK_FIELD_DFT(isa_support0, smcntrpmf);
  572. CHECK_FIELD_DFT(isa_support0, zicntr);
  573. CHECK_FIELD_DFT(isa_support0, zawrs);
  574. }
  575. if (isa_support1.b.exist) {
  576. CHECK_FIELD_DFT(isa_support1, ssqosid);
  577. CHECK_FIELD_DFT(isa_support1, zicflip);
  578. CHECK_FIELD_DFT(isa_support1, zicfiss);
  579. CHECK_FIELD_DFT(isa_support1, smctr);
  580. CHECK_FIELD_DFT(isa_support1, zacas);
  581. CHECK_FIELD_DFT(isa_support1, zabha);
  582. CHECK_FIELD_DFT(isa_support1, smdbltrp);
  583. CHECK_FIELD_DFT(isa_support1, ssdbltrp);
  584. CHECK_FIELD_DFT(isa_support1, smcdeleg);
  585. CHECK_FIELD_DFT(isa_support1, smmpm);
  586. CHECK_FIELD_DFT(isa_support1, smnpm);
  587. CHECK_FIELD_DFT(isa_support1, ssnpm);
  588. CHECK_FIELD_DFT(isa_support1, smstateen);
  589. CHECK_FIELD_DFT(isa_support1, sstateen);
  590. CHECK_FIELD_DFT(isa_support1, smcsrind);
  591. CHECK_FIELD_DFT(isa_support1, sscsrind);
  592. CHECK_FIELD_DFT(isa_support1, svadu);
  593. }
  594. CIF_PRINTF("\r\n");
  595. } else {
  596. CIF_PRINTF(" isa supported: absent\r\n");
  597. }
  598. /* VPU related extensions */
  599. if (isa_support0.b.exist && isa_support0.b.vector) {
  600. CIF_PRINTF(" vpu: present\r\n");
  601. CIF_PRINTF(" vpu_extension_list:");
  602. CHECK_FIELD_DFT(isa_support0, vector_b);
  603. CHECK_FIELD_DFT(isa_support0, vector_k);
  604. CHECK_FIELD_DFT(isa_support0, zve32x);
  605. CHECK_FIELD_DFT(isa_support0, zve32f);
  606. CHECK_FIELD_DFT(isa_support0, zve64x);
  607. CHECK_FIELD_DFT(isa_support0, zve64f);
  608. CHECK_FIELD_DFT(isa_support0, zve64d);
  609. CHECK_FIELD_DFT(isa_support0, zvfh);
  610. CHECK_FIELD_DFT(isa_support0, zvfhmin);
  611. CIF_PRINTF("\r\n");
  612. uint32_t vpu_cfg_info = iinfo->vpu_cfg_info;
  613. CIF_PRINTF(" noseg_noshuf=%u\r\n",
  614. (unsigned int)(vpu_cfg_info & BIT(0)));
  615. CIF_PRINTF(" elen64=%u\r\n",
  616. (unsigned int)(vpu_cfg_info & BIT(1)) >> 1);
  617. } else {
  618. CIF_PRINTF(" vpu: absent\r\n");
  619. }
  620. }
  621. static void show_mvlm_cfg(CIF_IINFO_Type *iinfo)
  622. {
  623. CIF_IINFO_MVLM_CFG_LO_Type mvlm_cfg_lo;
  624. mvlm_cfg_lo.d = iinfo->mvlm_cfg_lo;
  625. if (mvlm_cfg_lo.b.vlm) {
  626. CIF_PRINTF(" vlm: present\r\n");
  627. CIF_IINFO_MVLM_CFG_HI_Type mvlm_cfg_hi = iinfo->mvlm_cfg_hi;
  628. uint64_t vlm_base =
  629. (uint64_t)mvlm_cfg_hi << 32 | (mvlm_cfg_lo.d & (~0x3FFULL));
  630. CIF_PRINTF(" base=0x%" CIF_PRIxADDR "\r\n", (addr_t)vlm_base);
  631. CIF_PRINTF(" size=%s\r\n",
  632. cvt_size(POW2(mvlm_cfg_lo.b.vlm_size + 9)));
  633. } else {
  634. CIF_PRINTF(" vlm: absent\r\n");
  635. }
  636. }
  637. static void show_flash_bus(CIF_IINFO_Type *iinfo)
  638. {
  639. CIF_IINFO_FLASH_BASE_ADDR_LO_Type addr_lo;
  640. addr_lo.d = iinfo->flash_base_addr_lo;
  641. if (addr_lo.b.flash) {
  642. CIF_PRINTF(" flash bus: present\r\n");
  643. CIF_IINFO_FLASH_BASE_ADDR_HI_Type addr_hi = iinfo->flash_base_addr_hi;
  644. uint64_t flash_base =
  645. (uint64_t)addr_hi << 32 | (addr_lo.d & (~0x3FFULL));
  646. CIF_PRINTF(" base=0x%" CIF_PRIxADDR "\r\n", (addr_t)flash_base);
  647. CIF_PRINTF(" size=%s\r\n",
  648. cvt_size(addr_lo.b.flash_size + 9));
  649. } else {
  650. CIF_PRINTF(" flash bus: absent\r\n");
  651. }
  652. }
  653. static void show_mem_region_cfg(CIF_IINFO_Type *iinfo)
  654. {
  655. CIF_IINFO_MEM_REGION_CFG_LO_Type region_lo;
  656. uint64_t region_base;
  657. region_lo.d = iinfo->mem_region0_cfg_lo;
  658. if (region_lo.b.exist) {
  659. CIF_PRINTF(" mem_region0: present\r\n");
  660. CIF_IINFO_MEM_REGION_CFG_HI_Type region_hi = iinfo->mem_region0_cfg_hi;
  661. region_base = (uint64_t)region_hi << 32 | (region_lo.d & (~0x3FFULL));
  662. if (region_lo.b.mem_region_ena) {
  663. CIF_PRINTF(" status: enable\r\n");
  664. } else {
  665. CIF_PRINTF(" status: disable\r\n");
  666. }
  667. CIF_PRINTF(" base=0x%" CIF_PRIxADDR "\r\n", (addr_t)region_base);
  668. CIF_PRINTF(" size=%s\r\n",
  669. cvt_size(region_lo.b.mem_region_size + 9));
  670. } else {
  671. CIF_PRINTF(" mem_region0: absent\r\n");
  672. }
  673. region_lo.d = iinfo->mem_region1_cfg_lo;
  674. if (region_lo.b.exist) {
  675. CIF_PRINTF(" mem_region1: present\r\n");
  676. CIF_IINFO_MEM_REGION_CFG_HI_Type region_hi = iinfo->mem_region1_cfg_hi;
  677. region_base = (uint64_t)region_hi << 32 | (region_lo.d & (~0x3FFULL));
  678. if (region_lo.b.mem_region_ena) {
  679. CIF_PRINTF(" status: enable\r\n");
  680. } else {
  681. CIF_PRINTF(" status: disable\r\n");
  682. }
  683. CIF_PRINTF(" base=0x%" CIF_PRIxADDR "\r\n", (addr_t)region_base);
  684. CIF_PRINTF(" size=%s\r\n",
  685. cvt_size(region_lo.b.mem_region_size + 9));
  686. } else {
  687. CIF_PRINTF(" mem_region1: absent\r\n");
  688. }
  689. }
  690. static void show_mcppi_cfg(CIF_IINFO_Type *iinfo)
  691. {
  692. CIF_IINFO_MCPPI_CFG_LO_Type mcppi_lo;
  693. mcppi_lo.d = iinfo->mcppi_cfg_lo;
  694. if (mcppi_lo.b.exist) {
  695. CIF_PRINTF(" cppi: present\r\n");
  696. CIF_IINFO_MCPPI_CFG_HI_Type mcppi_hi = iinfo->mcppi_cfg_hi;
  697. uint64_t mcppi_base =
  698. (uint64_t)mcppi_hi << 32 | (mcppi_lo.d & (~0x3FFULL));
  699. if (mcppi_lo.b.cppi_ena) {
  700. CIF_PRINTF(" status: enable\r\n");
  701. } else {
  702. CIF_PRINTF(" status: disable\r\n");
  703. }
  704. CIF_PRINTF(" base=0x%" CIF_PRIxADDR "\r\n", (addr_t)mcppi_base);
  705. CIF_PRINTF(" size=%s\r\n",
  706. cvt_size(mcppi_lo.b.cppi_size + 9));
  707. } else {
  708. CIF_PRINTF(" cppi: absent\r\n");
  709. }
  710. }
  711. static void show_cmo(CIF_IINFO_Type *iinfo)
  712. {
  713. CIF_IINFO_MCMO_INFO_Type cmo_info;
  714. cmo_info.d = iinfo->cmo_info;
  715. if (cmo_info.b.cmo_cfg) {
  716. CIF_PRINTF(" cmo: present\r\n");
  717. CIF_PRINTF(" cbozero_size: %u Bytes\r\n",
  718. POW2(cmo_info.b.cbozero_size + 2));
  719. CIF_PRINTF(" cmo_size: %u Bytes\r\n",
  720. POW2(cmo_info.b.cmo_size + 2));
  721. CIF_PRINTF(" cmo_prefetch=%u\r\n",
  722. cmo_info.b.cmo_pft);
  723. } else {
  724. CIF_PRINTF(" cmo: absent\r\n");
  725. }
  726. }
  727. static void show_performance_cfg(CIF_IINFO_Type *iinfo)
  728. {
  729. CIF_IINFO_PERFORMANCE_CFG0_Type performance_cfg0;
  730. CIF_IINFO_PERFORMANCE_CFG1_Type performance_cfg1;
  731. performance_cfg0.d = iinfo->performance_cfg0;
  732. performance_cfg1.d = iinfo->performance_cfg1;
  733. if (performance_cfg0.b.exist || performance_cfg1.b.exist) {
  734. CIF_PRINTF(" hw performance: present\r\n");
  735. if (performance_cfg0.b.exist) {
  736. const char *bus[] = {"ICB", "AXI", "AHBL"};
  737. if (performance_cfg0.b.bus_type < 3) {
  738. CIF_PRINTF(" bus: %s\r\n",
  739. bus[performance_cfg0.b.bus_type]);
  740. }
  741. SHOW_VALUE(performance_cfg0, fpu_cycle);
  742. SHOW_VALUE(performance_cfg0, high_div);
  743. SHOW_VALUE(performance_cfg0, dcache_2stage);
  744. SHOW_VALUE(performance_cfg0, delay_branch_flush);
  745. SHOW_VALUE(performance_cfg0, dual_issue);
  746. SHOW_VALUE(performance_cfg0, cross_4k);
  747. SHOW_VALUE(performance_cfg0, dlm_2stage);
  748. SHOW_VALUE(performance_cfg0, lsu_cut_fwd);
  749. SHOW_VALUE(performance_cfg0, dsp_cycle);
  750. SHOW_VALUE(performance_cfg0, ifu_cut_timing);
  751. SHOW_VALUE(performance_cfg0, mem_cut_timing);
  752. SHOW_VALUE(performance_cfg0, dcache_prefetch);
  753. SHOW_VALUE(performance_cfg0, dcache_lbuf_num);
  754. SHOW_VALUE(performance_cfg0, mul_cyc);
  755. }
  756. if (performance_cfg1.b.exist) {
  757. SHOW_VALUE(performance_cfg1, vfpu_cyc);
  758. SHOW_VALUE(performance_cfg1, bht_entry_width);
  759. SHOW_VALUE(performance_cfg1, high_performance);
  760. SHOW_VALUE(performance_cfg1, agu_quick_forward);
  761. SHOW_VALUE(performance_cfg1, cau_fwd);
  762. SHOW_VALUE(performance_cfg1, hpm_ver);
  763. }
  764. } else {
  765. CIF_PRINTF(" hw performance: absent\r\n");
  766. }
  767. }
  768. static void show_misc_cfg(CIF_IINFO_Type *iinfo)
  769. {
  770. CIF_IINFO_MERGEL1DCTRL_Type mergel1dctrl;
  771. CIF_IINFO_SAFETY_CTRL_Type safety_ctrl;
  772. CIF_IINFO_ACCESS_CTRL_Type access_ctrl;
  773. mergel1dctrl.d = iinfo->mergel1dctrl;
  774. safety_ctrl.d = iinfo->safety_ctrl;
  775. access_ctrl.d = iinfo->access_ctrl;
  776. CIF_PRINTF(" misc: \r\n");
  777. SHOW_VALUE(mergel1dctrl, ws_tmout_max);
  778. SHOW_VALUE(mergel1dctrl, nc_tmout_max);
  779. SHOW_VALUE(mergel1dctrl, dev_store_early_ret);
  780. SHOW_VALUE(safety_ctrl, reg_prot_chck_en);
  781. SHOW_VALUE(access_ctrl, pf_access);
  782. SHOW_VALUE(access_ctrl, cache_csr_access);
  783. SHOW_VALUE(access_ctrl, pma_csr_access);
  784. }
  785. static void show_sec_cfg(CIF_IINFO_Type *iinfo)
  786. {
  787. CIF_IINFO_SEC_CFG_INFO_Type sec_cfg;
  788. sec_cfg.d = iinfo->sec_cfg_info;
  789. if (sec_cfg.b.security) {
  790. CIF_PRINTF(" sec_cfg: present\r\n");
  791. SHOW_VALUE(sec_cfg, sec_debug);
  792. SHOW_VALUE(sec_cfg, arcg);
  793. SHOW_VALUE(sec_cfg, remap);
  794. SHOW_VALUE(sec_cfg, parity_protection);
  795. SHOW_VALUE(sec_cfg, trwb);
  796. SHOW_VALUE(sec_cfg, ppi_lock);
  797. SHOW_VALUE(sec_cfg, cct);
  798. SHOW_VALUE(sec_cfg, cache_froze);
  799. SHOW_VALUE(sec_cfg, sec_mon_bus);
  800. SHOW_VALUE(sec_cfg, exe_monitor);
  801. SHOW_VALUE(sec_cfg, key_state_clear);
  802. SHOW_VALUE(sec_cfg, data_polarity);
  803. SHOW_VALUE(sec_cfg, random_ins_insert);
  804. SHOW_VALUE(sec_cfg, power_disturb);
  805. SHOW_VALUE(sec_cfg, stack_check);
  806. SHOW_VALUE(sec_cfg, bjp_random_flush);
  807. SHOW_VALUE(sec_cfg, parity_mode);
  808. SHOW_VALUE(sec_cfg, mpu_num);
  809. SHOW_VALUE(sec_cfg, bbox_num);
  810. } else {
  811. CIF_PRINTF(" sec_cfg: absent\r\n");
  812. }
  813. }
  814. static char *cvt_size_opt(uint32_t size, int lite)
  815. {
  816. static char buf[32];
  817. char units[] = {'B', 'K', 'M', 'G'};
  818. int i = 0;
  819. while (size >= 1024 && i < 3) {
  820. size >>= 10;
  821. i++;
  822. }
  823. if (lite) {
  824. sprintf(buf, "%u%c", size, units[i]);
  825. } else {
  826. sprintf(buf, "%u %c%s", size, units[i], i > 0 ? "B" : "");
  827. }
  828. return buf;
  829. }
  830. static void show_cache_info(uint32_t set, uint32_t way, uint32_t lsize,
  831. uint32_t ecc)
  832. {
  833. CIF_PRINTF(" %s", cvt_size(set * way * lsize));
  834. CIF_PRINTF("(set=%d,", set);
  835. CIF_PRINTF("way=%d,", way);
  836. CIF_PRINTF("lsize=%d,", lsize);
  837. CIF_PRINTF("ecc=%d)\r\n", !!ecc);
  838. }