Skip to content

Commit a9b2026

Browse files
atishp04palmer-dabbelt
authored andcommitted
RISC-V: Improve /proc/cpuinfo output for ISA extensions
Currently, the /proc/cpuinfo outputs the entire riscv,isa string which is not ideal when we have multiple ISA extensions present in the ISA string. Some of them may not be enabled in kernel as well. Same goes for the single letter extensions as well which prints the entire ISA string. Some of they may not be valid ISA extensions as well (e.g 'su') Parse only the valid & enabled ISA extension and print them. Tested-by: Heiko Stuebner <heiko@sntech.de> Signed-off-by: Atish Patra <atishp@rivosinc.com> Reviewed-by: Anup Patel <anup@brainfault.org> Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
1 parent 3f96db1 commit a9b2026

2 files changed

Lines changed: 70 additions & 2 deletions

File tree

arch/riscv/include/asm/hwcap.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ enum riscv_isa_ext_id {
5454
RISCV_ISA_EXT_ID_MAX = RISCV_ISA_EXT_MAX,
5555
};
5656

57+
struct riscv_isa_ext_data {
58+
/* Name of the extension displayed to userspace via /proc/cpuinfo */
59+
char uprop[RISCV_ISA_EXT_NAME_LEN_MAX];
60+
/* The logical ISA extension ID */
61+
unsigned int isa_ext_id;
62+
};
63+
5764
unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap);
5865

5966
#define riscv_isa_extension_mask(ext) BIT_MASK(RISCV_ISA_EXT_##ext)

arch/riscv/kernel/cpu.c

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <linux/init.h>
77
#include <linux/seq_file.h>
88
#include <linux/of.h>
9+
#include <asm/hwcap.h>
910
#include <asm/smp.h>
1011
#include <asm/pgtable.h>
1112

@@ -63,12 +64,72 @@ int riscv_of_parent_hartid(struct device_node *node)
6364
}
6465

6566
#ifdef CONFIG_PROC_FS
67+
#define __RISCV_ISA_EXT_DATA(UPROP, EXTID) \
68+
{ \
69+
.uprop = #UPROP, \
70+
.isa_ext_id = EXTID, \
71+
}
72+
/**
73+
* Here are the ordering rules of extension naming defined by RISC-V
74+
* specification :
75+
* 1. All extensions should be separated from other multi-letter extensions
76+
* from other multi-letter extensions by an underscore.
77+
* 2. The first letter following the 'Z' conventionally indicates the most
78+
* closely related alphabetical extension category, IMAFDQLCBKJTPVH.
79+
* If multiple 'Z' extensions are named, they should be ordered first
80+
* by category, then alphabetically within a category.
81+
* 3. Standard supervisor-level extensions (starts with 'S') should be
82+
* listed after standard unprivileged extensions. If multiple
83+
* supervisor-level extensions are listed, they should be ordered
84+
* alphabetically.
85+
* 4. Non-standard extensions (starts with 'X') must be listed after all
86+
* standard extensions. They must be separated from other multi-letter
87+
* extensions by an underscore.
88+
*/
89+
static struct riscv_isa_ext_data isa_ext_arr[] = {
90+
__RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX),
91+
};
92+
93+
static void print_isa_ext(struct seq_file *f)
94+
{
95+
struct riscv_isa_ext_data *edata;
96+
int i = 0, arr_sz;
97+
98+
arr_sz = ARRAY_SIZE(isa_ext_arr) - 1;
99+
100+
/* No extension support available */
101+
if (arr_sz <= 0)
102+
return;
103+
104+
for (i = 0; i <= arr_sz; i++) {
105+
edata = &isa_ext_arr[i];
106+
if (!__riscv_isa_extension_available(NULL, edata->isa_ext_id))
107+
continue;
108+
seq_printf(f, "_%s", edata->uprop);
109+
}
110+
}
111+
112+
/**
113+
* These are the only valid base (single letter) ISA extensions as per the spec.
114+
* It also specifies the canonical order in which it appears in the spec.
115+
* Some of the extension may just be a place holder for now (B, K, P, J).
116+
* This should be updated once corresponding extensions are ratified.
117+
*/
118+
static const char base_riscv_exts[13] = "imafdqcbkjpvh";
66119

67120
static void print_isa(struct seq_file *f, const char *isa)
68121
{
69-
/* Print the entire ISA as it is */
122+
int i;
123+
70124
seq_puts(f, "isa\t\t: ");
71-
seq_write(f, isa, strlen(isa));
125+
/* Print the rv[64/32] part */
126+
seq_write(f, isa, 4);
127+
for (i = 0; i < sizeof(base_riscv_exts); i++) {
128+
if (__riscv_isa_extension_available(NULL, base_riscv_exts[i] - 'a'))
129+
/* Print only enabled the base ISA extensions */
130+
seq_write(f, &base_riscv_exts[i], 1);
131+
}
132+
print_isa_ext(f);
72133
seq_puts(f, "\n");
73134
}
74135

0 commit comments

Comments
 (0)