Page MenuHomeFreeBSD

D35366.id106522.diff
No OneTemporary

D35366.id106522.diff

Index: sys/arm64/arm64/identcpu.c
===================================================================
--- sys/arm64/arm64/identcpu.c
+++ sys/arm64/arm64/identcpu.c
@@ -49,6 +49,7 @@
static void print_cpu_midr(struct sbuf *sb, u_int cpu);
static void print_cpu_features(u_int cpu);
+static void print_cpu_caches(u_int);
#ifdef COMPAT_FREEBSD32
static u_long parse_cpu_features_hwcap32(void);
#endif
@@ -103,6 +104,8 @@
SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD,
cpu_model, sizeof(cpu_model), "Machine model");
+#define MAX_CACHES 8 /* Maximum number of caches supported
+ architecturally. */
/*
* Per-CPU affinity as provided in MPIDR_EL1
* Indexed by CPU number in logical order selected by the system.
@@ -135,6 +138,8 @@
uint64_t mvfr0;
uint64_t mvfr1;
#endif
+ uint64_t clidr;
+ uint32_t ccsidr[MAX_CACHES][2]; /* 2 possible types. */
};
static struct cpu_desc cpu_desc[MAXCPU];
@@ -1805,6 +1810,7 @@
/* Fill in cpu_model for the hw.model sysctl */
sbuf_new(&sb, cpu_model, sizeof(cpu_model), SBUF_FIXEDLEN);
print_cpu_midr(&sb, 0);
+
sbuf_finish(&sb);
sbuf_delete(&sb);
}
@@ -1978,6 +1984,59 @@
cpu_part_name, CPU_VAR(midr), CPU_REV(midr));
}
+static void
+print_cpu_cache(struct sbuf *sb, int level, uint64_t ccs, bool icache, bool unified)
+{
+ size_t cache_size;
+
+ /*
+ * Calculate cache size (sets * ways * line size). There are different
+ * formats depending on the FEAT_CCIDX bit in ID_AA64MMFR2 feature
+ * register.
+ */
+ if ((READ_SPECIALREG(id_aa64mmfr2_el1) & ID_AA64MMFR2_CCIDX_64))
+ cache_size = (CCSIDR_NSETS_64(ccs) + 1) *
+ (CCSIDR_ASSOC_64(ccs) + 1);
+ else
+ cache_size = (CCSIDR_NSETS(ccs) + 1) * (CCSIDR_ASSOC(ccs) + 1);
+
+ if (icache)
+ cache_size *= icache_line_size;
+ else
+ cache_size *= dcache_line_size;
+ sbuf_printf(sb, " L%d cache: %zuKB (%s)\n", level, cache_size / 1024,
+ icache ? "instruction" : unified ? "unified" : "data");
+}
+
+static void
+print_cpu_caches(u_int cpu)
+{
+ struct sbuf *sb;
+
+ /* Print out each cache combination */
+ uint64_t clidr;
+ int i = 1;
+ clidr = cpu_desc[cpu].clidr;
+
+ sb = sbuf_new_auto();
+ sbuf_printf(sb, "CPU caches:\n");
+ for (i = 0; (clidr & 0x7) != 0; i++, clidr >>= 3) {
+ int j = 0;
+ if ((clidr & 0x1)) {
+ print_cpu_cache(sb, i + 1, cpu_desc[cpu].ccsidr[i][j++],
+ true, false);
+ }
+ if ((clidr & 0x6) == 0)
+ continue;
+ WRITE_SPECIALREG(csselr_el1, i << 1);
+ print_cpu_cache(sb, i + 1, cpu_desc[cpu].ccsidr[i][j],
+ false, (clidr & 0x4));
+
+ }
+ sbuf_finish(sb);
+ printf("%s\n", sbuf_data(sb));
+}
+
static void
print_cpu_features(u_int cpu)
{
@@ -2107,6 +2166,7 @@
print_id_register(sb, "AArch32 Media and VFP Features 1",
cpu_desc[cpu].mvfr1, mvfr1_fields);
#endif
+ print_cpu_caches(cpu);
sbuf_delete(sb);
sb = NULL;
@@ -2170,6 +2230,28 @@
cpu_desc[cpu].id_aa64mmfr2 = READ_SPECIALREG(id_aa64mmfr2_el1);
cpu_desc[cpu].id_aa64pfr0 = READ_SPECIALREG(id_aa64pfr0_el1);
cpu_desc[cpu].id_aa64pfr1 = READ_SPECIALREG(id_aa64pfr1_el1);
+
+ {
+ uint64_t clidr;
+ int i;
+ cpu_desc[cpu].clidr = READ_SPECIALREG(clidr_el1);
+
+ clidr = cpu_desc[cpu].clidr;
+
+ for (i = 0; (clidr & 0x7) != 0; i++, clidr >>= 3) {
+ int j = 0;
+ if ((clidr & 0x1)) {
+ WRITE_SPECIALREG(csselr_el1, (i << 1) | 1);
+ cpu_desc[cpu].ccsidr[i][j++] =
+ READ_SPECIALREG(ccsidr_el1);
+ }
+ if ((clidr & 0x6) == 0)
+ continue;
+ WRITE_SPECIALREG(csselr_el1, i << 1);
+ cpu_desc[cpu].ccsidr[i][j] =
+ READ_SPECIALREG(ccsidr_el1);
+ }
+ }
#ifdef COMPAT_FREEBSD32
/* Only read aarch32 SRs if EL0-32 is available */
if (ID_AA64PFR0_EL0_VAL(cpu_desc[cpu].id_aa64pfr0) ==
Index: sys/arm64/include/armreg.h
===================================================================
--- sys/arm64/include/armreg.h
+++ sys/arm64/include/armreg.h
@@ -69,6 +69,24 @@
#define UL(x) UINT64_C(x)
+/* CCSIDR_EL1 - Cache Size ID Register */
+#define CCSIDR_EL1_NumSets_M 0x0FFFE000
+#define CCSIDR_EL1_NumSets64_M 0x00FFFFFFFE000
+#define CCSIDR_EL1_NumSets_S 13
+#define CCSIDR_EL1_NumSets64_S 32
+#define CCSIDR_EL1_Assoc_M 0x00001FF8
+#define CCSIDR_EL1_Assoc64_M 0x0000000000FFFFF8
+#define CCSIDR_EL1_Assoc_S 3
+#define CCSIDR_EL1_Assoc64_S 3
+#define CCSIDR_NSETS(idr) \
+ (((idr) & CCSIDR_EL1_NumSets_M) >> CCSIDR_EL1_NumSets_S)
+#define CCSIDR_ASSOC(idr) \
+ (((idr) & CCSIDR_EL1_Assoc_M) >> CCSIDR_EL1_Assoc_S)
+#define CCSIDR_NSETS_64(idr) \
+ (((idr) & CCSIDR_EL1_NumSets64_M) >> CCSIDR_EL1_NumSets64_S)
+#define CCSIDR_ASSOC_64(idr) \
+ (((idr) & CCSIDR_EL1_Assoc64_M) >> CCSIDR_EL1_Assoc64_S)
+
/* 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 */

File Metadata

Mime Type
text/plain
Expires
Wed, Oct 22, 8:04 AM (3 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24049804
Default Alt Text
D35366.id106522.diff (4 KB)

Event Timeline