]> git.baikalelectronics.ru Git - kernel.git/commitdiff
RISC-V: Add mvendorid, marchid, and mimpid to /proc/cpuinfo output
authorAnup Patel <apatel@ventanamicro.com>
Wed, 27 Jul 2022 04:38:29 +0000 (10:08 +0530)
committerPalmer Dabbelt <palmer@rivosinc.com>
Tue, 4 Oct 2022 01:55:47 +0000 (18:55 -0700)
Identifying the underlying RISC-V implementation can be important
for some of the user space applications. For example, the perf tool
uses arch specific CPU implementation id (i.e. CPUID) to select a
JSON file describing custom perf events on a CPU.

Currently, there is no way to identify RISC-V implementation so we
add mvendorid, marchid, and mimpid to /proc/cpuinfo output.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Tested-by: Nikita Shubin <n.shubin@yadro.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20220727043829.151794-1-apatel@ventanamicro.com/
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/kernel/cpu.c

index 0be8a2403212d4a2b9a8a30af78437bc5b597b5f..250220e2ccebf38d5a77535dbc58c30ac0bbb2d9 100644 (file)
@@ -3,10 +3,13 @@
  * Copyright (C) 2012 Regents of the University of California
  */
 
+#include <linux/cpu.h>
 #include <linux/init.h>
 #include <linux/seq_file.h>
 #include <linux/of.h>
+#include <asm/csr.h>
 #include <asm/hwcap.h>
+#include <asm/sbi.h>
 #include <asm/smp.h>
 #include <asm/pgtable.h>
 
@@ -68,6 +71,50 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
 }
 
 #ifdef CONFIG_PROC_FS
+
+struct riscv_cpuinfo {
+       unsigned long mvendorid;
+       unsigned long marchid;
+       unsigned long mimpid;
+};
+static DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
+
+static int riscv_cpuinfo_starting(unsigned int cpu)
+{
+       struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
+
+#if IS_ENABLED(CONFIG_RISCV_SBI)
+       ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
+       ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
+       ci->mimpid = sbi_spec_is_0_1() ? 0 : sbi_get_mimpid();
+#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
+       ci->mvendorid = csr_read(CSR_MVENDORID);
+       ci->marchid = csr_read(CSR_MARCHID);
+       ci->mimpid = csr_read(CSR_MIMPID);
+#else
+       ci->mvendorid = 0;
+       ci->marchid = 0;
+       ci->mimpid = 0;
+#endif
+
+       return 0;
+}
+
+static int __init riscv_cpuinfo_init(void)
+{
+       int ret;
+
+       ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "riscv/cpuinfo:starting",
+                               riscv_cpuinfo_starting, NULL);
+       if (ret < 0) {
+               pr_err("cpuinfo: failed to register hotplug callbacks.\n");
+               return ret;
+       }
+
+       return 0;
+}
+device_initcall(riscv_cpuinfo_init);
+
 #define __RISCV_ISA_EXT_DATA(UPROP, EXTID) \
        {                                                       \
                .uprop = #UPROP,                                \
@@ -185,6 +232,7 @@ static int c_show(struct seq_file *m, void *v)
 {
        unsigned long cpu_id = (unsigned long)v - 1;
        struct device_node *node = of_get_cpu_node(cpu_id, NULL);
+       struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id);
        const char *compat, *isa;
 
        seq_printf(m, "processor\t: %lu\n", cpu_id);
@@ -195,6 +243,9 @@ static int c_show(struct seq_file *m, void *v)
        if (!of_property_read_string(node, "compatible", &compat)
            && strcmp(compat, "riscv"))
                seq_printf(m, "uarch\t\t: %s\n", compat);
+       seq_printf(m, "mvendorid\t: 0x%lx\n", ci->mvendorid);
+       seq_printf(m, "marchid\t\t: 0x%lx\n", ci->marchid);
+       seq_printf(m, "mimpid\t\t: 0x%lx\n", ci->mimpid);
        seq_puts(m, "\n");
        of_node_put(node);