Changeset View
Changeset View
Standalone View
Standalone View
sys/riscv/riscv/identcpu.c
Show First 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | |||||
SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD | CTLFLAG_CAPRD, machine, 0, | SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD | CTLFLAG_CAPRD, machine, 0, | ||||
"Machine class"); | "Machine class"); | ||||
/* 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; | |||||
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; | |||||
}; | }; | ||||
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 185 Lines • ▼ Show 20 Lines | while (i < len) { | ||||
i = parse_ext_version(isa, i, NULL, NULL); | i = parse_ext_version(isa, i, NULL, NULL); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
#ifdef FDT | #ifdef FDT | ||||
static void | static void | ||||
parse_mmu_fdt(struct cpu_desc *desc, phandle_t node) | |||||
{ | |||||
char mmu[16]; | |||||
desc->mmu_caps |= MMU_SV39; | |||||
if (OF_getprop(node, "mmu-type", mmu, sizeof(mmu)) > 0) { | |||||
if (strcmp(mmu, "riscv,sv48") == 0) | |||||
desc->mmu_caps |= MMU_SV48; | |||||
else if (strcmp(mmu, "riscv,sv57") == 0) | |||||
desc->mmu_caps |= MMU_SV48 | MMU_SV57; | |||||
} | |||||
} | |||||
static void | |||||
identify_cpu_features_fdt(u_int cpu, struct cpu_desc *desc) | identify_cpu_features_fdt(u_int cpu, struct cpu_desc *desc) | ||||
{ | { | ||||
char isa[1024]; | char isa[1024]; | ||||
phandle_t node; | phandle_t node; | ||||
ssize_t len; | ssize_t len; | ||||
pcell_t reg; | pcell_t reg; | ||||
u_int hart; | u_int hart; | ||||
Show All 31 Lines | for (node = OF_child(node); node > 0; node = OF_peer(node)) { | ||||
* The string is specified to be lowercase, but let's be | * The string is specified to be lowercase, but let's be | ||||
* certain. | * certain. | ||||
*/ | */ | ||||
for (int i = 0; i < len; i++) | for (int i = 0; i < len; i++) | ||||
isa[i] = tolower(isa[i]); | isa[i] = tolower(isa[i]); | ||||
if (parse_riscv_isa(desc, isa, len) != 0) | if (parse_riscv_isa(desc, isa, len) != 0) | ||||
return; | return; | ||||
/* Check MMU features. */ | |||||
parse_mmu_fdt(desc, node); | |||||
/* We are done. */ | /* We are done. */ | ||||
break; | break; | ||||
} | } | ||||
if (node <= 0) { | if (node <= 0) { | ||||
printf("%s: could not find FDT node for CPU %u, hart %u\n", | printf("%s: could not find FDT node for CPU %u, hart %u\n", | ||||
__func__, cpu, hart); | __func__, cpu, hart); | ||||
} | } | ||||
} | } | ||||
Show All 23 Lines | do { \ | ||||
} else { \ | } else { \ | ||||
(t) &= (v); \ | (t) &= (v); \ | ||||
} \ | } \ | ||||
} while (0) | } while (0) | ||||
/* 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. | |||||
*/ | |||||
UPDATE_CAP(mmu_caps, desc->mmu_caps); | |||||
#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 57 Lines • ▼ Show 20 Lines | printcpuinfo(u_int cpu) | ||||
/* Print details for boot CPU or if we want verbose output */ | /* Print details for boot CPU or if we want verbose output */ | ||||
if (cpu == 0 || bootverbose) { | if (cpu == 0 || bootverbose) { | ||||
/* Summary line. */ | /* Summary line. */ | ||||
printf("CPU %-3u: Vendor=%s Core=%s (Hart %u)\n", cpu, | printf("CPU %-3u: Vendor=%s Core=%s (Hart %u)\n", cpu, | ||||
desc->cpu_mvendor_name, desc->cpu_march_name, hart); | desc->cpu_mvendor_name, desc->cpu_march_name, hart); | ||||
printf(" marchid=%#lx, mimpid=%#lx\n", marchid, mimpid); | printf(" marchid=%#lx, mimpid=%#lx\n", marchid, mimpid); | ||||
printf(" MMU: %#b\n", desc->mmu_caps, | |||||
"\020" | |||||
"\01Sv39" | |||||
"\02Sv48" | |||||
"\03Sv57"); | |||||
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"); | ||||
} | } | ||||
} | } |