Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148651145
D35366.1787893057.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D35366.1787893057.diff
View Options
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,64 @@
cpu_part_name, CPU_VAR(midr), CPU_REV(midr));
}
+static void
+print_cpu_cache(u_int cpu, struct sbuf *sb, uint64_t ccs, bool icache, bool unified)
+{
+ size_t cache_size;
+ size_t line_size;
+
+ /* LineSize is Log2(S) - 4. */
+ line_size = 1 << ((ccs & CCSIDR_EL1_LineSize_M) + 4);
+ /*
+ * Calculate cache size (sets * ways * line size). There are different
+ * formats depending on the FEAT_CCIDX bit in ID_AA64MMFR2 feature
+ * register.
+ */
+ if ((cpu_desc[cpu].id_aa64mmfr2 & 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);
+
+ cache_size *= line_size;
+ sbuf_printf(sb, "%zuKB (%s)", 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();
+ for (i = 0; (clidr & CLIDR_CTYPE_M) != 0; i++, clidr >>= 3) {
+ int j = 0;
+ int ctype_m = (clidr & CLIDR_CTYPE_M);
+
+ sbuf_printf(sb, "L%d cache: ", i + 1);
+ if ((clidr & CLIDR_CTYPE_IO)) {
+ print_cpu_cache(cpu, sb, cpu_desc[cpu].ccsidr[i][j++],
+ true, false);
+ /* If there's more, add to the line. */
+ if ((ctype_m & ~CLIDR_CTYPE_IO) != 0)
+ sbuf_printf(sb, ", ");
+ }
+ if ((ctype_m & ~CLIDR_CTYPE_IO) != 0) {
+ print_cpu_cache(cpu, sb, cpu_desc[cpu].ccsidr[i][j],
+ false, (clidr & CLIDR_CTYPE_UNIFIED));
+ }
+ sbuf_printf(sb, "\n");
+
+ }
+ sbuf_finish(sb);
+ printf("%s", sbuf_data(sb));
+}
+
static void
print_cpu_features(u_int cpu)
{
@@ -2107,6 +2171,8 @@
print_id_register(sb, "AArch32 Media and VFP Features 1",
cpu_desc[cpu].mvfr1, mvfr1_fields);
#endif
+ if (bootverbose)
+ print_cpu_caches(cpu);
sbuf_delete(sb);
sb = NULL;
@@ -2170,6 +2236,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,32 @@
#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_EL1_LineSize_M 0x7
+#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)
+
+/* CLIDR_EL1 - Cache level ID register */
+#define CLIDR_CTYPE_M 0x7 /* Cache type mask bits */
+#define CLIDR_CTYPE_IO 0x1 /* Instruction only */
+#define CLIDR_CTYPE_DO 0x2 /* Data only */
+#define CLIDR_CTYPE_ID 0x3 /* Split instruction and data */
+#define CLIDR_CTYPE_UNIFIED 0x4 /* Unified */
+
/* 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
Details
Attached
Mime Type
text/plain
Expires
Fri, Aug 28, 4:57 AM (20 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29475876
Default Alt Text
D35366.1787893057.diff (5 KB)
Attached To
Mode
D35366: arm64: Print per-CPU cache summary
Attached
Detach File
Event Timeline
Log In to Comment