33 */
44#include "cpuinfo.h"
55
6+ #include <string.h>
7+
68#define BIT (ofs ) (0x1U << (ofs))
79#define EXTENSION_NUM (26)
810#define POW2 (n ) (1U << (n))
3335#define SHOW_VALUE (reg , field ) \
3436 CIF_PRINTF(" %s=%u\r\n", #field, reg.b.field);
3537
38+ #define STRCAT_BUF (buf , fmt , ...) \
39+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt, ##__VA_ARGS__)
40+
41+ #define CHECK_STRCAT_BUF (reg , field , buf , fmt , ...) \
42+ do { \
43+ if (reg.b.field) { \
44+ STRCAT_BUF(buf, fmt, ##__VA_ARGS__); \
45+ } \
46+ } while (0)
47+
48+ #define BASIC_CPUINFO_FMT "Nuclei CPU Detected: marchid-0x%04x v%d.%d.%d, ISA: %s"
49+
50+ /** `BUF_SIZE` is the size of string buffer in `get_basic_cpuinfo`
51+ */
52+ #ifndef BUF_SIZE
53+ #define BUF_SIZE (1024)
54+ #endif
55+
3656static void show_isa (CIF_XLEN_Type xlen , U32_CSR_MISA_Type misa ,
3757 U32_CSR_MCFG_INFO_Type mcfg );
3858static void show_mcfg (const CPU_CSR_Group * csrs );
@@ -57,7 +77,13 @@ static void show_cmo(IINFO_Type *iinfo);
5777static void show_performance_cfg (IINFO_Type * iinfo );
5878static void show_misc_cfg (IINFO_Type * iinfo );
5979
60- static char * cvt_size (uint32_t size );
80+ /**
81+ * Convert to human readable size with option
82+ * \param size: size in bytes
83+ * \param lite: !=0 for lite version
84+ */
85+ static char * cvt_size_opt (uint32_t size , int lite );
86+ #define cvt_size (size ) cvt_size_opt(size, 0)
6187static void show_cache_info (uint32_t set , uint32_t way , uint32_t lsize ,
6288 uint32_t ecc );
6389
@@ -87,6 +113,88 @@ void show_cpuinfo(CIF_XLEN_Type xlen, const CPU_CSR_Group *csrs)
87113 CIF_PRINTF ("-----End of Nuclei CPU INFO-----\r\n" );
88114}
89115
116+ int get_basic_cpuinfo (const CPU_CSR_Group * csrs , char * str , unsigned long len )
117+ {
118+ if (str == NULL ) {
119+ return -1 ;
120+ }
121+
122+ static char buf [BUF_SIZE ] = {0 }; // features string buffer
123+ buf [0 ] = '\0' ; // clear the buffer each time call this function
124+ char isa [EXTENSION_NUM + 1 ];
125+
126+ /* construct ISA string */
127+ int pos = 0 ;
128+ for (int i = 0 ; i < EXTENSION_NUM ; ++ i ) {
129+ if (csrs -> misa .d & BIT (i )) {
130+ isa [pos ++ ] = 'A' + i ;
131+ }
132+ }
133+ isa [pos ] = '\0' ;
134+
135+ if (!csrs -> mcfg_exist ) {
136+ return snprintf (str , len , BASIC_CPUINFO_FMT , csrs -> marchid .d ,
137+ csrs -> mimpid .b .first_vernum , csrs -> mimpid .b .mid_vernum ,
138+ csrs -> mimpid .b .last_vernum , isa );
139+ }
140+
141+ /* construct features string */
142+ U32_CSR_MCFG_INFO_Type mcfg = csrs -> mcfginfo ;
143+ CHECK_STRCAT_BUF (mcfg , plic , buf , "MMU, PLIC, " );
144+ CHECK_STRCAT_BUF (mcfg , eclic , buf , "ECLIC, " );
145+ CHECK_STRCAT_BUF (mcfg , fio , buf , "FIO, " );
146+ CHECK_STRCAT_BUF (mcfg , ppi , buf , "PPI, " );
147+ CHECK_STRCAT_BUF (mcfg , nice , buf , "NICE, " );
148+ CHECK_STRCAT_BUF (mcfg , vnice , buf , "VNICE, " );
149+ CHECK_STRCAT_BUF (mcfg , etrace , buf , "ETRACE, " );
150+ CHECK_STRCAT_BUF (mcfg , ecc , buf , "ECC, " );
151+ CHECK_STRCAT_BUF (mcfg , tee , buf , "TEE, " );
152+ CHECK_STRCAT_BUF (mcfg , sec_mode , buf , "SMWG, " );
153+
154+ IINFO_ISA_SUPPORT0_Type isa_support0 ;
155+ isa_support0 .d = csrs -> iinfo -> isa_support0 ;
156+ CHECK_STRCAT_BUF (isa_support0 , svpbmt , buf , "Svpbmt, " );
157+
158+ IINFO_MCMO_INFO_Type cmo ;
159+ cmo .d = csrs -> iinfo -> cmo_info ;
160+ CHECK_STRCAT_BUF (cmo , cmo_cfg , buf , "CMO, " );
161+
162+ if (mcfg .b .smp ) {
163+ unsigned long iregion_base = csrs -> mirgbinfo .d & (~0x3FF );
164+ U32_CSR_SMP_CFG_Type smp_cfg =
165+ * (U32_CSR_SMP_CFG_Type * )(iregion_base + IREGION_SMP_OFS + 4 );
166+ STRCAT_BUF (buf , "SMPx%d, " , smp_cfg .b .smp_core_num + 1 );
167+ }
168+
169+ /* show local memory and cache info */
170+ U32_CSR_MICFG_INFO_Type micfg = csrs -> micfginfo ;
171+ U32_CSR_MDCFG_INFO_Type mdcfg = csrs -> mdcfginfo ;
172+ CHECK_STRCAT_BUF (mcfg , ilm , buf , "ILM-%s, " ,
173+ cvt_size_opt (POW2 (micfg .b .lm_size + 7 ), 1 ));
174+ CHECK_STRCAT_BUF (mcfg , dlm , buf , "DLM-%s, " ,
175+ cvt_size_opt (POW2 (mdcfg .b .lm_size + 7 ), 1 ));
176+ CHECK_STRCAT_BUF (
177+ mcfg , icache , buf , "IC-%s, " ,
178+ cvt_size_opt (POW2 (micfg .b .set + 3 ) * POW2 (micfg .b .lsize + 2 ) *
179+ (micfg .b .way + 1 ),
180+ 1 ));
181+ CHECK_STRCAT_BUF (
182+ mcfg , dcache , buf , "DC-%s, " ,
183+ cvt_size_opt (POW2 (mdcfg .b .set + 3 ) * POW2 (mdcfg .b .lsize + 2 ) *
184+ (mdcfg .b .way + 1 ),
185+ 1 ));
186+
187+ /* remove the comma at the end */
188+ if (strlen (buf ) > 0 && buf [strlen (buf ) - 2 ] == ',' ) {
189+ buf [strlen (buf ) - 2 ] = '\0' ;
190+ }
191+
192+ return snprintf (str , len , BASIC_CPUINFO_FMT ", Feature: %s" ,
193+ csrs -> marchid .d , csrs -> mimpid .b .first_vernum ,
194+ csrs -> mimpid .b .mid_vernum , csrs -> mimpid .b .last_vernum , isa ,
195+ buf );
196+ }
197+
90198static void show_isa (CIF_XLEN_Type xlen , U32_CSR_MISA_Type misa ,
91199 U32_CSR_MCFG_INFO_Type mcfg )
92200{
@@ -650,8 +758,7 @@ static void show_misc_cfg(IINFO_Type *iinfo)
650758 SHOW_VALUE (access_ctrl , pma_csr_access );
651759}
652760
653- /* Convert to human readable size */
654- static char * cvt_size (uint32_t size )
761+ static char * cvt_size_opt (uint32_t size , int lite )
655762{
656763 static char buf [32 ];
657764 char units [] = {'B' , 'K' , 'M' , 'G' };
@@ -660,7 +767,11 @@ static char *cvt_size(uint32_t size)
660767 size >>= 10 ;
661768 i ++ ;
662769 }
663- sprintf (buf , "%u %c%s" , size , units [i ], i > 0 ? "B" : "" );
770+ if (lite ) {
771+ sprintf (buf , "%u%c" , size , units [i ]);
772+ } else {
773+ sprintf (buf , "%u %c%s" , size , units [i ], i > 0 ? "B" : "" );
774+ }
664775 return buf ;
665776}
666777
0 commit comments