diff --git a/sys/riscv/include/cpu.h b/sys/riscv/include/cpu.h --- a/sys/riscv/include/cpu.h +++ b/sys/riscv/include/cpu.h @@ -52,27 +52,36 @@ #ifdef _KERNEL /* - * 0x0000 CPU ID unimplemented - * 0x0001 UC Berkeley Rocket repo - * 0x0002­0x7FFE Reserved for open-source repos - * 0x7FFF Reserved for extension - * 0x8000 Reserved for anonymous source - * 0x8001­0xFFFE Reserved for proprietary implementations - * 0xFFFF Reserved for extension + * Core manufacturer IDs, as reported by the mvendorid CSR. */ +#define MVENDORID_UNIMPL 0x0 +#define MVENDORID_SIFIVE 0x489 +#define MVENDORID_THEAD 0x5b7 -#define CPU_IMPL_SHIFT 0 -#define CPU_IMPL_MASK (0xffff << CPU_IMPL_SHIFT) -#define CPU_IMPL(mimpid) ((mimpid & CPU_IMPL_MASK) >> CPU_IMPL_SHIFT) -#define CPU_IMPL_UNIMPLEMEN 0x0 -#define CPU_IMPL_UCB_ROCKET 0x1 +/* + * Micro-architecture ID register, marchid. + * + * IDs for open-source implementations are allocated globally. Commercial IDs + * will have the most-significant bit set. + */ +#define MARCHID_UNIMPL 0x0 +#define MARCHID_MSB (1ul << (XLEN - 1)) +#define MARCHID_OPENSOURCE(v) (v) +#define MARCHID_COMMERCIAL(v) (MARCHID_MSB | (v)) +#define MARCHID_IS_OPENSOURCE(m) (((m) & MARCHID_MSB) == 0) + +/* + * Open-source marchid values. + * + * https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md + */ +#define MARCHID_UCB_ROCKET MARCHID_OPENSOURCE(1) +#define MARCHID_UCB_BOOM MARCHID_OPENSOURCE(2) +#define MARCHID_UCB_SPIKE MARCHID_OPENSOURCE(5) +#define MARCHID_UCAM_RVBS MARCHID_OPENSOURCE(10) -#define CPU_PART_SHIFT 62 -#define CPU_PART_MASK (0x3ul << CPU_PART_SHIFT) -#define CPU_PART(misa) ((misa & CPU_PART_MASK) >> CPU_PART_SHIFT) -#define CPU_PART_RV32 0x1 -#define CPU_PART_RV64 0x2 -#define CPU_PART_RV128 0x3 +/* SiFive marchid values */ +#define MARCHID_SIFIVE_U7 MARCHID_COMMERCIAL(7) extern char btext[]; extern char etext[]; diff --git a/sys/riscv/riscv/identcpu.c b/sys/riscv/riscv/identcpu.c --- a/sys/riscv/riscv/identcpu.c +++ b/sys/riscv/riscv/identcpu.c @@ -67,42 +67,47 @@ register_t mimpid; /* The implementation ID */ struct cpu_desc { - u_int cpu_impl; - u_int cpu_part_num; - const char *cpu_impl_name; - const char *cpu_part_name; + const char *cpu_mvendor_name; + const char *cpu_march_name; }; struct cpu_desc cpu_desc[MAXCPU]; -struct cpu_parts { - u_int part_id; - const char *part_name; +/* + * Micro-architecture tables. + */ +struct marchid_entry { + register_t march_id; + const char *march_name; }; -#define CPU_PART_NONE { -1, "Unknown Processor" } -struct cpu_implementers { - u_int impl_id; - const char *impl_name; +#define MARCHID_END { -1ul, NULL } + +/* Open-source RISC-V architecture IDs; globally allocated. */ +static const struct marchid_entry global_marchids[] = { + { MARCHID_UCB_ROCKET, "UC Berkeley Rocket" }, + { MARCHID_UCB_BOOM, "UC Berkeley Boom" }, + { MARCHID_UCB_SPIKE, "UC Berkeley Spike" }, + { MARCHID_UCAM_RVBS, "University of Cambridge RVBS" }, + MARCHID_END }; -#define CPU_IMPLEMENTER_NONE { 0, "Unknown Implementer" } -/* - * CPU base - */ -static const struct cpu_parts cpu_parts_std[] = { - { CPU_PART_RV32, "RV32" }, - { CPU_PART_RV64, "RV64" }, - { CPU_PART_RV128, "RV128" }, - CPU_PART_NONE, +static const struct marchid_entry sifive_marchids[] = { + { MARCHID_SIFIVE_U7, "6/7/P200/X200-Series Processor" }, + MARCHID_END }; /* - * Implementers table. + * Known CPU vendor/manufacturer table. */ -const struct cpu_implementers cpu_implementers[] = { - { CPU_IMPL_UCB_ROCKET, "UC Berkeley Rocket" }, - CPU_IMPLEMENTER_NONE, +static const struct { + register_t mvendor_id; + const char *mvendor_name; + const struct marchid_entry *marchid_table; +} mvendor_ids[] = { + { MVENDORID_UNIMPL, "Unspecified", NULL }, + { MVENDORID_SIFIVE, "SiFive", sifive_marchids }, + { MVENDORID_THEAD, "T-Head", NULL }, }; /* @@ -319,48 +324,63 @@ SYSINIT(identcpu, SI_SUB_CPU, SI_ORDER_ANY, fill_elf_hwcap, NULL); #endif -void -identify_cpu(void) +static void +identify_cpu_ids(struct cpu_desc *desc) { - const struct cpu_parts *cpu_partsp; - uint32_t part_id; - uint32_t impl_id; - uint64_t misa; - u_int cpu; - size_t i; - - cpu_partsp = NULL; + const struct marchid_entry *table = NULL; + int i; - /* TODO: can we get misa somewhere ? */ - misa = 0; + desc->cpu_mvendor_name = "Unknown"; + desc->cpu_march_name = "Unknown"; - cpu = PCPU_GET(cpuid); - - impl_id = CPU_IMPL(mimpid); - for (i = 0; i < nitems(cpu_implementers); i++) { - if (impl_id == cpu_implementers[i].impl_id || - cpu_implementers[i].impl_id == 0) { - cpu_desc[cpu].cpu_impl = impl_id; - cpu_desc[cpu].cpu_impl_name = cpu_implementers[i].impl_name; - cpu_partsp = cpu_parts_std; + /* + * Search for a recognized vendor, and possibly obtain the secondary + * table for marchid lookup. + */ + for (i = 0; i < nitems(mvendor_ids); i++) { + if (mvendorid == mvendor_ids[i].mvendor_id) { + desc->cpu_mvendor_name = mvendor_ids[i].mvendor_name; + table = mvendor_ids[i].marchid_table; break; } } - part_id = CPU_PART(misa); - for (i = 0; &cpu_partsp[i] != NULL; i++) { - if (part_id == cpu_partsp[i].part_id || - cpu_partsp[i].part_id == -1) { - cpu_desc[cpu].cpu_part_num = part_id; - cpu_desc[cpu].cpu_part_name = cpu_partsp[i].part_name; + if (marchid == MARCHID_UNIMPL) { + desc->cpu_march_name = "Unspecified"; + return; + } + + if (MARCHID_IS_OPENSOURCE(marchid)) { + table = global_marchids; + } else if (table == NULL) + return; + + for (i = 0; table[i].march_name != NULL; i++) { + if (marchid == table[i].march_id) { + desc->cpu_march_name = table[i].march_name; break; } } +} + +void +identify_cpu(void) +{ + struct cpu_desc *desc; + u_int cpu, hart; + + cpu = PCPU_GET(cpuid); + hart = PCPU_GET(hart); + desc = &cpu_desc[cpu]; + + identify_cpu_ids(desc); /* Print details for boot CPU or if we want verbose output */ if (cpu == 0 || bootverbose) { - printf("CPU(%d): %s %s\n", cpu, - cpu_desc[cpu].cpu_impl_name, - cpu_desc[cpu].cpu_part_name); + /* Summary line. */ + printf("CPU %-3u: Vendor=%s Core=%s (Hart %u)\n", cpu, + desc->cpu_mvendor_name, desc->cpu_march_name, hart); + + printf(" marchid=%#lx, mimpid=%#lx\n", marchid, mimpid); } }