]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lscpu: RISC-V: Print ISA information in summary
authorSunil V L <sunilvl@ventanamicro.com>
Tue, 11 Mar 2025 16:06:46 +0000 (21:36 +0530)
committerKarel Zak <kzak@redhat.com>
Mon, 17 Mar 2025 09:57:52 +0000 (10:57 +0100)
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@ventanamicro.com>
sys-utils/Makemodule.am
sys-utils/lscpu-cputype.c
sys-utils/lscpu-riscv.c [new file with mode: 0644]
sys-utils/lscpu.c
sys-utils/lscpu.h
sys-utils/meson.build

index 922cce5c52f0c8c8ed51980750f6a07dafc8574f..1055312db4b4576d13a4a66c26dc38cfef6c1dd9 100644 (file)
@@ -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)
index 739dd99c595f4cb309a1e38510867ba890a59309..bdb33ac783b961d578911932f40660d83f11e6f5 100644 (file)
@@ -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 (file)
index 0000000..62f1ad7
--- /dev/null
@@ -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);
+}
index ffec37206587aff100830b6717a13d82c9ead686..7b2f28e5ef1bcba254267e046e9acfb32e68106f 100644 (file)
@@ -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);
+       }
 }
 
 /*
index 459fea84d42d7a582b4073a46432e69653008874..bd7b64cc57c7d247d9a09414ccf6579680b568f4 100644 (file)
@@ -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);
 
index 2fdcc6393e51d3a675378b1da0fae637106545f1..d9817f922cab62bf7912a80bb2f4bd1a93b1d4e7 100644 (file)
@@ -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')