Skip to content

Commit 2e3bed1

Browse files
committed
application: add get_basic_cpuinfo in cpuinfo
Signed-off-by: qiujiandong <[email protected]>
1 parent 7ea39b0 commit 2e3bed1

File tree

2 files changed

+127
-4
lines changed

2 files changed

+127
-4
lines changed

application/baremetal/cpuinfo/cpuinfo.c

Lines changed: 115 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
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))
@@ -33,6 +35,24 @@
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+
3656
static void show_isa(CIF_XLEN_Type xlen, U32_CSR_MISA_Type misa,
3757
U32_CSR_MCFG_INFO_Type mcfg);
3858
static void show_mcfg(const CPU_CSR_Group *csrs);
@@ -57,7 +77,13 @@ static void show_cmo(IINFO_Type *iinfo);
5777
static void show_performance_cfg(IINFO_Type *iinfo);
5878
static 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)
6187
static 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+
90198
static 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

application/baremetal/cpuinfo/cpuinfo.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,18 @@ typedef uint32_t IINFO_MCPPI_CFG_HI_Type;
635635
*/
636636
void show_cpuinfo(CIF_XLEN_Type xlen, const CPU_CSR_Group *csrs);
637637

638+
/**
639+
* \brief Get basic CPU information in a single line.
640+
* This function is **not reentrant** because it uses
641+
* a shared static buffer.
642+
* \param csrs: pointer to CPU_CSR_Group
643+
* \param str: pointer to string buffer
644+
* \param len: length of string buffer
645+
* \return actual length of result string or '-1' for `str == NULL`,
646+
* it is same as the return value of `snprintf`
647+
*/
648+
int get_basic_cpuinfo(const CPU_CSR_Group *csrs, char *str, unsigned long len);
649+
638650
#ifdef __cplusplus
639651
}
640652
#endif

0 commit comments

Comments
 (0)