From: kettenis Date: Sat, 25 Aug 2018 20:45:28 +0000 (+0000) Subject: Add code to print the characteristics of the caches that can be discovered X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=6f69320d8d6aa375dfee64a7131c46365edb2f6e;p=openbsd Add code to print the characteristics of the caches that can be discovered through the CLIDR_EL1 register. ok patrick@ --- diff --git a/sys/arch/arm64/arm64/cpu.c b/sys/arch/arm64/arm64/cpu.c index d833d7cd968..539259d6195 100644 --- a/sys/arch/arm64/arm64/cpu.c +++ b/sys/arch/arm64/arm64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.23 2018/08/18 11:34:08 kettenis Exp $ */ +/* $OpenBSD: cpu.c,v 1.24 2018/08/25 20:45:28 kettenis Exp $ */ /* * Copyright (c) 2016 Dale Rahn @@ -130,8 +130,12 @@ void cpu_identify(struct cpu_info *ci) { uint64_t midr, impl, part; - char *impl_name = NULL; - char *part_name = NULL; + uint64_t clidr; + uint32_t ctr, ccsidr, sets, ways, line; + const char *impl_name = NULL; + const char *part_name = NULL; + const char *il1p_name = NULL; + const char *sep; struct cpu_cores *coreselecter = cpu_cores_none; int i; @@ -169,6 +173,62 @@ cpu_identify(struct cpu_info *ci) snprintf(cpu_model, sizeof(cpu_model), "Unknown"); } + /* Print cache information. */ + + ctr = READ_SPECIALREG(ctr_el0); + switch (ctr & CTR_IL1P_MASK) { + case CTR_IL1P_AIVIVT: + il1p_name = "AIVIVT "; + break; + case CTR_IL1P_VIPT: + il1p_name = "VIPT "; + break; + case CTR_IL1P_PIPT: + il1p_name = "PIPT "; + break; + } + + clidr = READ_SPECIALREG(clidr_el1); + for (i = 0; i < 7; i++) { + if ((clidr & CLIDR_CTYPE_MASK) == 0) + break; + printf("\n%s:", ci->ci_dev->dv_xname); + sep = ""; + if (clidr & CLIDR_CTYPE_INSN) { + WRITE_SPECIALREG(csselr_el1, + i << CSSELR_LEVEL_SHIFT | CSSELR_IND); + ccsidr = READ_SPECIALREG(ccsidr_el1); + sets = CCSIDR_SETS(ccsidr); + ways = CCSIDR_WAYS(ccsidr); + line = CCSIDR_LINE_SIZE(ccsidr); + printf("%s %dKB %db/line %d-way L%d %sI-cache", sep, + (sets * ways * line) / 1024, line, ways, (i + 1), + il1p_name); + il1p_name = ""; + sep = ","; + } + if (clidr & CLIDR_CTYPE_DATA) { + WRITE_SPECIALREG(csselr_el1, i << CSSELR_LEVEL_SHIFT); + ccsidr = READ_SPECIALREG(ccsidr_el1); + sets = CCSIDR_SETS(ccsidr); + ways = CCSIDR_WAYS(ccsidr); + line = CCSIDR_LINE_SIZE(ccsidr); + printf("%s %dKB %db/line %d-way L%d D-cache", sep, + (sets * ways * line) / 1024, line, ways, (i + 1)); + sep = ","; + } + if (clidr & CLIDR_CTYPE_UNIFIED) { + WRITE_SPECIALREG(csselr_el1, i << CSSELR_LEVEL_SHIFT); + ccsidr = READ_SPECIALREG(ccsidr_el1); + sets = CCSIDR_SETS(ccsidr); + ways = CCSIDR_WAYS(ccsidr); + line = CCSIDR_LINE_SIZE(ccsidr); + printf("%s %dKB %db/line %d-way L%d cache", sep, + (sets * ways * line) / 1024, line, ways, (i + 1)); + } + clidr >>= 3; + } + /* * Some ARM processors are vulnerable to branch target * injection attacks (CVE-2017-5715). diff --git a/sys/arch/arm64/include/armreg.h b/sys/arch/arm64/include/armreg.h index 3700c3c8792..a2365e68cae 100644 --- a/sys/arch/arm64/include/armreg.h +++ b/sys/arch/arm64/include/armreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: armreg.h,v 1.6 2018/08/03 18:36:01 kettenis Exp $ */ +/* $OpenBSD: armreg.h,v 1.7 2018/08/25 20:45:28 kettenis Exp $ */ /*- * Copyright (c) 2013, 2014 Andrew Turner * Copyright (c) 2015 The FreeBSD Foundation @@ -44,7 +44,25 @@ #define WRITE_SPECIALREG(reg, val) \ __asm __volatile("msr " __STRING(reg) ", %0" : : "r"((uint64_t)val)) -/* CNTHCTL_EL2 - Counter-timer Hypervisor Control register */ +/* CCSIDR_EL1 - Current Cache Size ID Register */ +#define CCSIDR_SETS_MASK 0x0fffe000 +#define CCSIDR_SETS_SHIFT 13 +#define CCSIDR_SETS(reg) \ + ((((reg) & CCSIDR_SETS_MASK) >> CCSIDR_SETS_SHIFT) + 1) +#define CCSIDR_WAYS_MASK 0x00001ff8 +#define CCSIDR_WAYS_SHIFT 3 +#define CCSIDR_WAYS(reg) \ + ((((reg) & CCSIDR_WAYS_MASK) >> CCSIDR_WAYS_SHIFT) + 1) +#define CCSIDR_LINE_MASK 0x00000007 +#define CCSIDR_LINE_SIZE(reg) (1 << (((reg) & CCSIDR_LINE_MASK) + 4)) + +/* CLIDR_EL1 - Cache Level ID Register */ +#define CLIDR_CTYPE_MASK 0x7 +#define CLIDR_CTYPE_INSN 0x1 +#define CLIDR_CTYPE_DATA 0x2 +#define CLIDR_CTYPE_UNIFIED 0x4 + +/* CNTHCTL_EL2 - Counter-timer Hypervisor Control Register */ #define CNTHCTL_EVNTI_MASK (0xf << 4) /* Bit to trigger event stream */ #define CNTHCTL_EVNTDIR (1 << 3) /* Control transition trigger bit */ #define CNTHCTL_EVNTEN (1 << 2) /* Enable event stream */ @@ -59,10 +77,19 @@ #define CPACR_FPEN_TRAP_NONE (0x3 << 20) /* No traps */ #define CPACR_TTA (0x1 << 28) +/* CSSELR_EL1 - Cache Size Selection Register */ +#define CSSELR_IND (1 << 0) +#define CSSELR_LEVEL_SHIFT 1 + /* CTR_EL0 - Cache Type Register */ #define CTR_DLINE_SHIFT 16 #define CTR_DLINE_MASK (0xf << CTR_DLINE_SHIFT) #define CTR_DLINE_SIZE(reg) (((reg) & CTR_DLINE_MASK) >> CTR_DLINE_SHIFT) +#define CTR_IL1P_SHIFT 14 +#define CTR_IL1P_MASK (0x3 << CTR_IL1P_SHIFT) +#define CTR_IL1P_AIVIVT (0x1 << CTR_IL1P_SHIFT) +#define CTR_IL1P_VIPT (0x2 << CTR_IL1P_SHIFT) +#define CTR_IL1P_PIPT (0x3 << CTR_IL1P_SHIFT) #define CTR_ILINE_SHIFT 0 #define CTR_ILINE_MASK (0xf << CTR_ILINE_SHIFT) #define CTR_ILINE_SIZE(reg) (((reg) & CTR_ILINE_MASK) >> CTR_ILINE_SHIFT)