-/* $OpenBSD: cpu.c,v 1.111 2024/03/17 13:05:40 kettenis Exp $ */
+/* $OpenBSD: cpu.c,v 1.112 2024/03/18 18:35:21 kettenis Exp $ */
/*
* Copyright (c) 2016 Dale Rahn <drahn@dalerahn.com>
static uint64_t prev_id_aa64pfr0;
static uint64_t prev_id_aa64pfr1;
uint64_t midr, impl, part;
- uint64_t clidr, id;
- uint32_t ctr, ccsidr, sets, ways, line;
+ uint64_t clidr, ccsidr, id;
+ uint32_t ctr, 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 ccidx;
int i;
midr = READ_SPECIALREG(midr_el1);
break;
}
+ id = READ_SPECIALREG(id_aa64mmfr2_el1);
clidr = READ_SPECIALREG(clidr_el1);
+ if (ID_AA64MMFR2_CCIDX(id) > ID_AA64MMFR2_CCIDX_IMPL) {
+ /* Reserved value. Don't print cache information. */
+ clidr = 0;
+ } else if (ID_AA64MMFR2_CCIDX(id) == ID_AA64MMFR2_CCIDX_IMPL) {
+ /* CCSIDR_EL1 uses the new 64-bit format. */
+ ccidx = 1;
+ } else {
+ /* CCSIDR_EL1 uses the old 32-bit format. */
+ ccidx = 0;
+ }
for (i = 0; i < 7; i++) {
if ((clidr & CLIDR_CTYPE_MASK) == 0)
break;
i << CSSELR_LEVEL_SHIFT | CSSELR_IND);
__asm volatile("isb");
ccsidr = READ_SPECIALREG(ccsidr_el1);
- sets = CCSIDR_SETS(ccsidr);
- ways = CCSIDR_WAYS(ccsidr);
- line = CCSIDR_LINE_SIZE(ccsidr);
+ if (ccidx) {
+ sets = CCSIDR_CCIDX_SETS(ccsidr);
+ ways = CCSIDR_CCIDX_WAYS(ccsidr);
+ line = CCSIDR_CCIDX_LINE_SIZE(ccsidr);
+ } else {
+ 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);
WRITE_SPECIALREG(csselr_el1, i << CSSELR_LEVEL_SHIFT);
__asm volatile("isb");
ccsidr = READ_SPECIALREG(ccsidr_el1);
- sets = CCSIDR_SETS(ccsidr);
- ways = CCSIDR_WAYS(ccsidr);
- line = CCSIDR_LINE_SIZE(ccsidr);
+ if (ccidx) {
+ sets = CCSIDR_CCIDX_SETS(ccsidr);
+ ways = CCSIDR_CCIDX_WAYS(ccsidr);
+ line = CCSIDR_CCIDX_LINE_SIZE(ccsidr);
+ } else {
+ 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 = ",";
WRITE_SPECIALREG(csselr_el1, i << CSSELR_LEVEL_SHIFT);
__asm volatile("isb");
ccsidr = READ_SPECIALREG(ccsidr_el1);
- sets = CCSIDR_SETS(ccsidr);
- ways = CCSIDR_WAYS(ccsidr);
- line = CCSIDR_LINE_SIZE(ccsidr);
+ if (ccidx) {
+ sets = CCSIDR_CCIDX_SETS(ccsidr);
+ ways = CCSIDR_CCIDX_WAYS(ccsidr);
+ line = CCSIDR_CCIDX_LINE_SIZE(ccsidr);
+ } else {
+ 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));
}
-/* $OpenBSD: armreg.h,v 1.32 2024/03/17 13:05:40 kettenis Exp $ */
+/* $OpenBSD: armreg.h,v 1.33 2024/03/18 18:35:21 kettenis Exp $ */
/*-
* Copyright (c) 2013, 2014 Andrew Turner
* Copyright (c) 2015 The FreeBSD Foundation
#define CCSIDR_LINE_MASK 0x00000007
#define CCSIDR_LINE_SIZE(reg) (1 << (((reg) & CCSIDR_LINE_MASK) + 4))
+#define CCSIDR_CCIDX_SETS_MASK 0x00ffffff00000000ULL
+#define CCSIDR_CCIDX_SETS_SHIFT 32
+#define CCSIDR_CCIDX_SETS(reg) \
+ ((((reg) & CCSIDR_CCIDX_SETS_MASK) >> CCSIDR_CCIDX_SETS_SHIFT) + 1)
+#define CCSIDR_CCIDX_WAYS_MASK 0x0000000000fffff8ULL
+#define CCSIDR_CCIDX_WAYS_SHIFT 3
+#define CCSIDR_CCIDX_WAYS(reg) \
+ ((((reg) & CCSIDR_CCIDX_WAYS_MASK) >> CCSIDR_CCIDX_WAYS_SHIFT) + 1)
+#define CCSIDR_CCIDX_LINE_MASK 0x0000000000000007ULL
+#define CCSIDR_CCIDX_LINE_SIZE(reg) \
+ (1 << (((reg) & CCSIDR_CCIDX_LINE_MASK) + 4))
+
/* CLIDR_EL1 - Cache Level ID Register */
#define CLIDR_CTYPE_MASK 0x7
#define CLIDR_CTYPE_INSN 0x1
#define ID_AA64MMFR1_ECBHB_NONE (0x0ULL << ID_AA64MMFR1_ECBHB_SHIFT)
#define ID_AA64MMFR1_ECBHB_IMPL (0x1ULL << ID_AA64MMFR1_ECBHB_SHIFT)
+/* ID_AA64MMFR2_EL1 */
+#define ID_AA64MMFR2_MASK 0xffff0fffffffffffULL
+#define ID_AA64MMFR2_CCIDX_SHIFT 20
+#define ID_AA64MMFR2_CCIDX_MASK (0xfULL << ID_AA64MMFR2_CCIDX_SHIFT)
+#define ID_AA64MMFR2_CCIDX(x) ((x) & ID_AA64MMFR2_CCIDX_MASK)
+#define ID_AA64MMFR2_CCIDX_IMPL (0x1ULL << ID_AA64MMFR2_CCIDX_SHIFT)
+
/* ID_AA64PFR0_EL1 */
#define ID_AA64PFR0_MASK 0xff0fffffffffffffULL
#define ID_AA64PFR0_EL0_SHIFT 0