1295041Sbr/*- 2295041Sbr * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> 3295041Sbr * All rights reserved. 4295041Sbr * 5295041Sbr * Portions of this software were developed by SRI International and the 6295041Sbr * University of Cambridge Computer Laboratory under DARPA/AFRL contract 7295041Sbr * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. 8295041Sbr * 9295041Sbr * Portions of this software were developed by the University of Cambridge 10295041Sbr * Computer Laboratory as part of the CTSRD Project, with support from the 11295041Sbr * UK Higher Education Innovation Fund (HEIF). 12295041Sbr * 13295041Sbr * Redistribution and use in source and binary forms, with or without 14295041Sbr * modification, are permitted provided that the following conditions 15295041Sbr * are met: 16295041Sbr * 1. Redistributions of source code must retain the above copyright 17295041Sbr * notice, this list of conditions and the following disclaimer. 18295041Sbr * 2. Redistributions in binary form must reproduce the above copyright 19295041Sbr * notice, this list of conditions and the following disclaimer in the 20295041Sbr * documentation and/or other materials provided with the distribution. 21295041Sbr * 22295041Sbr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23295041Sbr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24295041Sbr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25295041Sbr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26295041Sbr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27295041Sbr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28295041Sbr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29295041Sbr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30295041Sbr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31295041Sbr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32295041Sbr * SUCH DAMAGE. 33295041Sbr */ 34295041Sbr 35295041Sbr#include <sys/cdefs.h> 36295041Sbr__FBSDID("$FreeBSD: releng/11.0/sys/riscv/riscv/identcpu.c 295041 2016-01-29 15:12:31Z br $"); 37295041Sbr 38295041Sbr#include <sys/param.h> 39295041Sbr#include <sys/pcpu.h> 40295041Sbr#include <sys/sysctl.h> 41295041Sbr#include <sys/systm.h> 42295041Sbr 43295041Sbr#include <machine/cpu.h> 44295041Sbr#include <machine/cpufunc.h> 45295041Sbr#include <machine/trap.h> 46295041Sbr 47295041Sbrchar machine[] = "riscv"; 48295041Sbr 49295041SbrSYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, 50295041Sbr "Machine class"); 51295041Sbr 52295041Sbrstruct cpu_desc { 53295041Sbr u_int cpu_impl; 54295041Sbr u_int cpu_part_num; 55295041Sbr const char *cpu_impl_name; 56295041Sbr const char *cpu_part_name; 57295041Sbr}; 58295041Sbr 59295041Sbrstruct cpu_desc cpu_desc[MAXCPU]; 60295041Sbr 61295041Sbrstruct cpu_parts { 62295041Sbr u_int part_id; 63295041Sbr const char *part_name; 64295041Sbr}; 65295041Sbr#define CPU_PART_NONE { -1, "Unknown Processor" } 66295041Sbr 67295041Sbrstruct cpu_implementers { 68295041Sbr u_int impl_id; 69295041Sbr const char *impl_name; 70295041Sbr /* 71295041Sbr * Part number is implementation defined 72295041Sbr * so each vendor will have its own set of values and names. 73295041Sbr */ 74295041Sbr const struct cpu_parts *cpu_parts; 75295041Sbr}; 76295041Sbr#define CPU_IMPLEMENTER_NONE { 0, "Unknown Implementer", cpu_parts_none } 77295041Sbr 78295041Sbr/* 79295041Sbr * Per-implementer table of (PartNum, CPU Name) pairs. 80295041Sbr */ 81295041Sbr/* UC Berkeley */ 82295041Sbrstatic const struct cpu_parts cpu_parts_ucb[] = { 83295041Sbr { CPU_PART_RV32I, "RV32I" }, 84295041Sbr { CPU_PART_RV32E, "RV32E" }, 85295041Sbr { CPU_PART_RV64I, "RV64I" }, 86295041Sbr { CPU_PART_RV128I, "RV128I" }, 87295041Sbr CPU_PART_NONE, 88295041Sbr}; 89295041Sbr 90295041Sbr/* Unknown */ 91295041Sbrstatic const struct cpu_parts cpu_parts_none[] = { 92295041Sbr CPU_PART_NONE, 93295041Sbr}; 94295041Sbr 95295041Sbr/* 96295041Sbr * Implementers table. 97295041Sbr */ 98295041Sbrconst struct cpu_implementers cpu_implementers[] = { 99295041Sbr { CPU_IMPL_UCB_ROCKET, "UC Berkeley Rocket", cpu_parts_ucb }, 100295041Sbr CPU_IMPLEMENTER_NONE, 101295041Sbr}; 102295041Sbr 103295041Sbrvoid 104295041Sbridentify_cpu(void) 105295041Sbr{ 106295041Sbr const struct cpu_parts *cpu_partsp; 107295041Sbr uint32_t part_id; 108295041Sbr uint32_t impl_id; 109295041Sbr uint64_t mimpid; 110295041Sbr uint64_t mcpuid; 111295041Sbr u_int cpu; 112295041Sbr size_t i; 113295041Sbr 114295041Sbr cpu_partsp = NULL; 115295041Sbr 116295041Sbr mimpid = machine_command(ECALL_MIMPID_GET, 0); 117295041Sbr mcpuid = machine_command(ECALL_MCPUID_GET, 0); 118295041Sbr 119295041Sbr /* SMPTODO: use mhartid ? */ 120295041Sbr cpu = PCPU_GET(cpuid); 121295041Sbr 122295041Sbr impl_id = CPU_IMPL(mimpid); 123295041Sbr for (i = 0; i < nitems(cpu_implementers); i++) { 124295041Sbr if (impl_id == cpu_implementers[i].impl_id || 125295041Sbr cpu_implementers[i].impl_id == 0) { 126295041Sbr cpu_desc[cpu].cpu_impl = impl_id; 127295041Sbr cpu_desc[cpu].cpu_impl_name = cpu_implementers[i].impl_name; 128295041Sbr cpu_partsp = cpu_implementers[i].cpu_parts; 129295041Sbr break; 130295041Sbr } 131295041Sbr } 132295041Sbr 133295041Sbr part_id = CPU_PART(mcpuid); 134295041Sbr for (i = 0; &cpu_partsp[i] != NULL; i++) { 135295041Sbr if (part_id == cpu_partsp[i].part_id || 136295041Sbr cpu_partsp[i].part_id == -1) { 137295041Sbr cpu_desc[cpu].cpu_part_num = part_id; 138295041Sbr cpu_desc[cpu].cpu_part_name = cpu_partsp[i].part_name; 139295041Sbr break; 140295041Sbr } 141295041Sbr } 142295041Sbr 143295041Sbr /* Print details for boot CPU or if we want verbose output */ 144295041Sbr if (cpu == 0 || bootverbose) { 145295041Sbr printf("CPU(%d): %s %s\n", cpu, 146295041Sbr cpu_desc[cpu].cpu_impl_name, 147295041Sbr cpu_desc[cpu].cpu_part_name); 148295041Sbr } 149295041Sbr} 150