[PATCH v2] lscpu: RISC-V: Print ISA information in summary

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The ISA information for RISC-V is important for understanding the
different extensions supported by the CPU. Print the ISA information in
the summary, with the Base ISA and single-letter extensions at the
beginning, followed by multi-letter extensions sorted in alphabetical
order. The information is the same as the cpuinfo information, except
that underscores are replaced by spaces and multi-letter extensions are
simply sorted instead of following any ISA string ordering rule.

The sample output below shows the difference between cpuinfo and lscpu.

cpuinfo output:
isa             : rv64imafdch_zicbom_zicboz_zicntr_zicsr_zifencei_zihintntl_zihintpause_zihpm_zawrs_zfa_zba_zbb_zbc_zbs_smaia_ssaia_sstc

lscpu output:
ISA:                rv64imafdch smaia ssaia sstc zawrs zba zbb zbc zbs zfa zicbom zicboz zicntr zicsr zifencei zihintntl zihintpause zihpm

Signed-off-by: Sunil V L <sunilvl@xxxxxxxxxxxxxxxx>
---
Changes in v2:
	1) Format the ISA string instead of simply printing the same
	   from cpuinfo. (Feedback from Andrew Jones).
---
 sys-utils/Makemodule.am   |  1 +
 sys-utils/lscpu-cputype.c |  1 +
 sys-utils/lscpu-riscv.c   | 57 +++++++++++++++++++++++++++++++++++++++
 sys-utils/lscpu.c         |  5 ++++
 sys-utils/lscpu.h         |  2 ++
 sys-utils/meson.build     |  1 +
 6 files changed, 67 insertions(+)
 create mode 100644 sys-utils/lscpu-riscv.c

diff --git a/sys-utils/Makemodule.am b/sys-utils/Makemodule.am
index 922cce5c5..1055312db 100644
--- a/sys-utils/Makemodule.am
+++ b/sys-utils/Makemodule.am
@@ -461,6 +461,7 @@ lscpu_SOURCES = sys-utils/lscpu.c \
 		sys-utils/lscpu-virt.c \
 		sys-utils/lscpu-arm.c \
 		sys-utils/lscpu-dmi.c \
+		sys-utils/lscpu-riscv.c \
 		sys-utils/lscpu.h
 lscpu_LDADD = $(LDADD) libcommon.la libsmartcols.la $(RTAS_LIBS)
 lscpu_CFLAGS = $(AM_CFLAGS) -I$(ul_libsmartcols_incdir)
diff --git a/sys-utils/lscpu-cputype.c b/sys-utils/lscpu-cputype.c
index 739dd99c5..bdb33ac78 100644
--- a/sys-utils/lscpu-cputype.c
+++ b/sys-utils/lscpu-cputype.c
@@ -233,6 +233,7 @@ static const struct cpuinfo_pattern type_patterns[] =
 	DEF_PAT_CPUTYPE( "family",		PAT_FAMILY,	family),
 	DEF_PAT_CPUTYPE( "features",		PAT_FEATURES,	flags),		/* s390 */
 	DEF_PAT_CPUTYPE( "flags",		PAT_FLAGS,	flags),		/* x86 */
+	DEF_PAT_CPUTYPE( "isa",			PAT_ISA,	isa),		/* riscv */
 	DEF_PAT_CPUTYPE( "marchid",		PAT_FAMILY,	family),	/* riscv */
 	DEF_PAT_CPUTYPE( "max thread id",	PAT_MAX_THREAD_ID, mtid),	/* s390 */
 	DEF_PAT_CPUTYPE( "mimpid",		PAT_MODEL,	model),		/* riscv */
diff --git a/sys-utils/lscpu-riscv.c b/sys-utils/lscpu-riscv.c
new file mode 100644
index 000000000..62f1ad7ab
--- /dev/null
+++ b/sys-utils/lscpu-riscv.c
@@ -0,0 +1,57 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Copyright (C) 2025 Ventana Micro Systems Inc.
+ *
+ */
+#include "lscpu.h"
+#include "strutils.h"
+#include "strv.h"
+
+static int riscv_cmp_func(const void *a, const void *b)
+{
+	return strcmp(*(const char **)a, *(const char **)b);
+}
+
+bool is_riscv(struct lscpu_cputype *ct)
+{
+	const char *base_isa[] = {"rv32", "rv64", "rv128"};
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(base_isa); i++) {
+		if (!strncasecmp(ct->isa, base_isa[i], strlen(base_isa[i])))
+			return true;
+	}
+
+	return false;
+}
+
+/*
+ * Reformat the isa string, but the length stays the same.
+ */
+void lscpu_format_isa_riscv(struct lscpu_cputype *ct)
+{
+	char **split;
+	size_t i;
+
+	split = strv_split(ct->isa, "_");
+
+	/* Sort multi-letter extensions alphabetically */
+	if (strv_length(split) > 1)
+		qsort(&split[1], strv_length(split) - 1, sizeof(char *), riscv_cmp_func);
+
+	/* Keep Base ISA and single-letter extensions at the start */
+	strcpy(ct->isa, split[0]);
+
+	for (i = 1; i < strv_length(split); i++) {
+		strcat(ct->isa, " ");
+		strcat(ct->isa, split[i]);
+	}
+
+	strv_free(split);
+}
diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c
index ffec37206..7b2f28e5e 100644
--- a/sys-utils/lscpu.c
+++ b/sys-utils/lscpu.c
@@ -954,6 +954,11 @@ print_summary_cputype(struct lscpu_cxt *cxt,
 
 	if (ct->flags)
 		add_summary_s(tb, sec, _("Flags:"), ct->flags);
+
+	if (ct->isa && is_riscv(ct)) {
+		lscpu_format_isa_riscv(ct);
+		add_summary_s(tb, sec, _("ISA:"), ct->isa);
+	}
 }
 
 /*
diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h
index 459fea84d..bd7b64cc5 100644
--- a/sys-utils/lscpu.h
+++ b/sys-utils/lscpu.h
@@ -278,6 +278,7 @@ struct lscpu_cxt {
 		 CPU_ISSET_S((_cpu)->logical_id, (_cxt)->setsize, (_cxt)->present))
 
 int is_arm(struct lscpu_cxt *cxt);
+bool is_riscv(struct lscpu_cputype *ct);
 
 struct lscpu_cputype *lscpu_new_cputype(void);
 void lscpu_ref_cputype(struct lscpu_cputype *ct);
@@ -320,6 +321,7 @@ int lscpu_create_cpus(struct lscpu_cxt *cxt, cpu_set_t *cpuset, size_t setsize);
 struct lscpu_cpu *lscpu_cpus_loopup_by_type(struct lscpu_cxt *cxt, struct lscpu_cputype *ct);
 
 void lscpu_decode_arm(struct lscpu_cxt *cxt);
+void lscpu_format_isa_riscv(struct lscpu_cputype *ct);
 
 int lookup(char *line, char *pattern, char **value);
 
diff --git a/sys-utils/meson.build b/sys-utils/meson.build
index 2fdcc6393..d9817f922 100644
--- a/sys-utils/meson.build
+++ b/sys-utils/meson.build
@@ -184,6 +184,7 @@ lscpu_sources = files(
   'lscpu-virt.c',
   'lscpu-arm.c',
   'lscpu-dmi.c',
+  'lscpu-riscv.c',
 )
 lscpu_manadocs = files('lscpu.1.adoc')
 
-- 
2.43.0





[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux