Changeset View
Changeset View
Standalone View
Standalone View
sys/riscv/riscv/identcpu.c
/*- | /*- | ||||
* SPDX-License-Identifier: BSD-2-Clause | |||||
* | |||||
* Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com> | * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com> | ||||
* All rights reserved. | * All rights reserved. | ||||
* Copyright (c) 2022 Mitchell Horne <mhorne@FreeBSD.org> | |||||
* Copyright (c) 2023 The FreeBSD Foundation | |||||
* | * | ||||
* Portions of this software were developed by SRI International and the | * Portions of this software were developed by SRI International and the | ||||
* University of Cambridge Computer Laboratory under DARPA/AFRL contract | * University of Cambridge Computer Laboratory under DARPA/AFRL contract | ||||
* FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. | * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. | ||||
* | * | ||||
* Portions of this software were developed by the University of Cambridge | * Portions of this software were developed by the University of Cambridge | ||||
* Computer Laboratory as part of the CTSRD Project, with support from the | * Computer Laboratory as part of the CTSRD Project, with support from the | ||||
* UK Higher Education Innovation Fund (HEIF). | * UK Higher Education Innovation Fund (HEIF). | ||||
* | * | ||||
* Portions of this software were developed by Mitchell Horne | |||||
* <mhorne@FreeBSD.org> under sponsorship from the FreeBSD Foundation. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
* notice, this list of conditions and the following disclaimer. | * notice, this list of conditions and the following disclaimer. | ||||
* 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | ||||
* notice, this list of conditions and the following disclaimer in the | * notice, this list of conditions and the following disclaimer in the | ||||
* documentation and/or other materials provided with the distribution. | * documentation and/or other materials provided with the distribution. | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
/* Hardware implementation info. These values may be empty. */ | /* Hardware implementation info. These values may be empty. */ | ||||
register_t mvendorid; /* The CPU's JEDEC vendor ID */ | register_t mvendorid; /* The CPU's JEDEC vendor ID */ | ||||
register_t marchid; /* The architecture ID */ | register_t marchid; /* The architecture ID */ | ||||
register_t mimpid; /* The implementation ID */ | register_t mimpid; /* The implementation ID */ | ||||
u_int mmu_caps; | u_int mmu_caps; | ||||
/* Supervisor-mode extension support. */ | |||||
bool __read_frequently has_sstc; | |||||
bool __read_frequently has_sscofpmf; | |||||
struct cpu_desc { | struct cpu_desc { | ||||
const char *cpu_mvendor_name; | const char *cpu_mvendor_name; | ||||
const char *cpu_march_name; | const char *cpu_march_name; | ||||
u_int isa_extensions; /* Single-letter extensions. */ | u_int isa_extensions; /* Single-letter extensions. */ | ||||
u_int mmu_caps; | u_int mmu_caps; | ||||
u_int smode_extensions; | |||||
#define SV_SSTC (1 << 0) | |||||
#define SV_SVNAPOT (1 << 1) | |||||
#define SV_SVPBMT (1 << 2) | |||||
#define SV_SVINVAL (1 << 3) | |||||
#define SV_SSCOFPMF (1 << 4) | |||||
}; | }; | ||||
struct cpu_desc cpu_desc[MAXCPU]; | struct cpu_desc cpu_desc[MAXCPU]; | ||||
/* | /* | ||||
* Micro-architecture tables. | * Micro-architecture tables. | ||||
*/ | */ | ||||
struct marchid_entry { | struct marchid_entry { | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* The format is described in detail by the "ISA Extension Naming Conventions" | * The format is described in detail by the "ISA Extension Naming Conventions" | ||||
* chapter of the unprivileged spec. | * chapter of the unprivileged spec. | ||||
*/ | */ | ||||
#define ISA_PREFIX ("rv" __XSTRING(__riscv_xlen)) | #define ISA_PREFIX ("rv" __XSTRING(__riscv_xlen)) | ||||
#define ISA_PREFIX_LEN (sizeof(ISA_PREFIX) - 1) | #define ISA_PREFIX_LEN (sizeof(ISA_PREFIX) - 1) | ||||
static __inline int | static __inline int | ||||
parse_ext_s(struct cpu_desc *desc __unused, char *isa, int idx, int len) | parse_ext_s(struct cpu_desc *desc, char *isa, int idx, int len) | ||||
{ | { | ||||
#define CHECK_S_EXT(str, flag) \ | |||||
do { \ | |||||
if (strncmp(&isa[idx], (str), \ | |||||
MIN(strlen(str), len - idx)) == 0) { \ | |||||
desc->smode_extensions |= flag; \ | |||||
return (idx + strlen(str)); \ | |||||
} \ | |||||
} while (0) | |||||
/* Check for known/supported extensions. */ | |||||
CHECK_S_EXT("sstc", SV_SSTC); | |||||
CHECK_S_EXT("svnapot", SV_SVNAPOT); | |||||
CHECK_S_EXT("svpbmt", SV_SVPBMT); | |||||
CHECK_S_EXT("svinval", SV_SVINVAL); | |||||
CHECK_S_EXT("sscofpmf", SV_SSCOFPMF); | |||||
#undef CHECK_S_EXT | |||||
/* | /* | ||||
* Proceed to the next multi-letter extension or the end of the | * Proceed to the next multi-letter extension or the end of the | ||||
* string. | * string. | ||||
* | |||||
* TODO: parse these once we gain support | |||||
*/ | */ | ||||
while (isa[idx] != '_' && idx < len) { | while (isa[idx] != '_' && idx < len) { | ||||
idx++; | idx++; | ||||
} | } | ||||
return (idx); | return (idx); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 227 Lines • ▼ Show 20 Lines | #define UPDATE_CAP(t, v) \ | ||||
/* Update the capabilities exposed to userspace via AT_HWCAP. */ | /* Update the capabilities exposed to userspace via AT_HWCAP. */ | ||||
UPDATE_CAP(elf_hwcap, (u_long)desc->isa_extensions); | UPDATE_CAP(elf_hwcap, (u_long)desc->isa_extensions); | ||||
/* | /* | ||||
* MMU capabilities, e.g. Sv48. | * MMU capabilities, e.g. Sv48. | ||||
*/ | */ | ||||
UPDATE_CAP(mmu_caps, desc->mmu_caps); | UPDATE_CAP(mmu_caps, desc->mmu_caps); | ||||
/* Supervisor-mode extension support. */ | |||||
UPDATE_CAP(has_sstc, (desc->smode_extensions & SV_SSTC) != 0); | |||||
UPDATE_CAP(has_sscofpmf, (desc->smode_extensions & SV_SSCOFPMF) != 0); | |||||
#undef UPDATE_CAP | #undef UPDATE_CAP | ||||
} | } | ||||
static void | static void | ||||
identify_cpu_ids(struct cpu_desc *desc) | identify_cpu_ids(struct cpu_desc *desc) | ||||
{ | { | ||||
const struct marchid_entry *table = NULL; | const struct marchid_entry *table = NULL; | ||||
int i; | int i; | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | #define SHOULD_PRINT(_field) \ | ||||
if (SHOULD_PRINT(isa_extensions)) { | if (SHOULD_PRINT(isa_extensions)) { | ||||
printf(" ISA: %#b\n", desc->isa_extensions, | printf(" ISA: %#b\n", desc->isa_extensions, | ||||
"\020" | "\020" | ||||
"\01Atomic" | "\01Atomic" | ||||
"\03Compressed" | "\03Compressed" | ||||
"\04Double" | "\04Double" | ||||
"\06Float" | "\06Float" | ||||
"\15Mult/Div"); | "\15Mult/Div"); | ||||
} | |||||
if (SHOULD_PRINT(smode_extensions)) { | |||||
printf(" S-mode Extensions: %#b\n", desc->smode_extensions, | |||||
"\020" | |||||
"\01Sstc" | |||||
"\02Svnapot" | |||||
"\03Svpbmt" | |||||
"\04Svinval" | |||||
"\05Sscofpmf"); | |||||
} | } | ||||
#undef SHOULD_PRINT | #undef SHOULD_PRINT | ||||
} | } |