Module Name:    src
Committed By:   ryo
Date:           Mon May 25 05:13:17 UTC 2020

Modified Files:
        src/sys/arch/aarch64/aarch64: cpufunc.c
        src/sys/arch/aarch64/include: armreg.h cpufunc.h

Log Message:
cache information can be detected correctly on newer CPUs

- add VPIPT cache type
- adapt to 64-bit CCSIDR (ARMv8.3-CCIDX)
- CCSIDR:[WT,WB,PA,WA] are deprecated
- show number of cache lines when attaching cpu


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/aarch64/aarch64/cpufunc.c
cvs rdiff -u -r1.45 -r1.46 src/sys/arch/aarch64/include/armreg.h
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/aarch64/include/cpufunc.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/aarch64/aarch64/cpufunc.c
diff -u src/sys/arch/aarch64/aarch64/cpufunc.c:1.19 src/sys/arch/aarch64/aarch64/cpufunc.c:1.20
--- src/sys/arch/aarch64/aarch64/cpufunc.c:1.19	Sat May 23 18:08:58 2020
+++ src/sys/arch/aarch64/aarch64/cpufunc.c	Mon May 25 05:13:16 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpufunc.c,v 1.19 2020/05/23 18:08:58 ryo Exp $	*/
+/*	$NetBSD: cpufunc.c,v 1.20 2020/05/25 05:13:16 ryo Exp $	*/
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -30,7 +30,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.19 2020/05/23 18:08:58 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.20 2020/05/25 05:13:16 ryo Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -60,7 +60,7 @@ extract_cacheunit(int level, bool insn, 
     struct aarch64_cache_info *cacheinfo)
 {
 	struct aarch64_cache_unit *cunit;
-	uint32_t ccsidr;
+	uint64_t ccsidr, mmfr2;
 
 	/* select and extract level N data cache */
 	reg_csselr_el1_write(__SHIFTIN(level, CSSELR_LEVEL) |
@@ -68,6 +68,7 @@ extract_cacheunit(int level, bool insn, 
 	__asm __volatile ("isb");
 
 	ccsidr = reg_ccsidr_el1_read();
+	mmfr2 = reg_id_aa64mmfr2_el1_read();
 
 	if (insn)
 		cunit = &cacheinfo[level].icache;
@@ -76,19 +77,24 @@ extract_cacheunit(int level, bool insn, 
 
 	cunit->cache_type = cachetype;
 
-	cunit->cache_line_size = 1 << (__SHIFTOUT(ccsidr, CCSIDR_LINESIZE) + 4);
-	cunit->cache_ways = __SHIFTOUT(ccsidr, CCSIDR_ASSOC) + 1;
-	cunit->cache_sets = __SHIFTOUT(ccsidr, CCSIDR_NUMSET) + 1;
+	switch (__SHIFTOUT(mmfr2, ID_AA64MMFR2_EL1_CCIDX)) {
+	case ID_AA64MMFR2_EL1_CCIDX_32BIT:
+		cunit->cache_line_size =
+		    1 << (__SHIFTOUT(ccsidr, CCSIDR_LINESIZE) + 4);
+		cunit->cache_ways = __SHIFTOUT(ccsidr, CCSIDR_ASSOC) + 1;
+		cunit->cache_sets = __SHIFTOUT(ccsidr, CCSIDR_NUMSET) + 1;
+		break;
+	case ID_AA64MMFR2_EL1_CCIDX_64BIT:
+		cunit->cache_line_size =
+		    1 << (__SHIFTOUT(ccsidr, CCSIDR64_LINESIZE) + 4);
+		cunit->cache_ways = __SHIFTOUT(ccsidr, CCSIDR64_ASSOC) + 1;
+		cunit->cache_sets = __SHIFTOUT(ccsidr, CCSIDR64_NUMSET) + 1;
+		break;
+	}
 
 	/* calc waysize and whole size */
 	cunit->cache_way_size = cunit->cache_line_size * cunit->cache_sets;
 	cunit->cache_size = cunit->cache_way_size * cunit->cache_ways;
-
-	/* cache purging */
-	cunit->cache_purging = (ccsidr & CCSIDR_WT) ? CACHE_PURGING_WT : 0;
-	cunit->cache_purging |= (ccsidr & CCSIDR_WB) ? CACHE_PURGING_WB : 0;
-	cunit->cache_purging |= (ccsidr & CCSIDR_RA) ? CACHE_PURGING_RA : 0;
-	cunit->cache_purging |= (ccsidr & CCSIDR_WA) ? CACHE_PURGING_WA : 0;
 }
 
 void
@@ -125,6 +131,9 @@ aarch64_getcacheinfo(int unit)
 	 */
 	ctr = reg_ctr_el0_read();
 	switch (__SHIFTOUT(ctr, CTR_EL0_L1IP_MASK)) {
+	case CTR_EL0_L1IP_VPIPT:
+		cachetype = CACHE_TYPE_VPIPT;
+		break;
 	case CTR_EL0_L1IP_AIVIVT:
 		cachetype = CACHE_TYPE_VIVT;
 		break;
@@ -134,9 +143,6 @@ aarch64_getcacheinfo(int unit)
 	case CTR_EL0_L1IP_PIPT:
 		cachetype = CACHE_TYPE_PIPT;
 		break;
-	default:
-		cachetype = 0;
-		break;
 	}
 
 	/* remember maximum alignment */
@@ -224,7 +230,6 @@ static int
 prt_cache(device_t self, struct aarch64_cache_info *cinfo, int level)
 {
 	struct aarch64_cache_unit *cunit;
-	u_int purging;
 	int i;
 	const char *cacheable, *cachetype;
 
@@ -261,6 +266,9 @@ prt_cache(device_t self, struct aarch64_
 		}
 
 		switch (cunit->cache_type) {
+		case CACHE_TYPE_VPIPT:
+			cachetype = "VPIPT";
+			break;
 		case CACHE_TYPE_VIVT:
 			cachetype = "VIVT";
 			break;
@@ -275,17 +283,13 @@ prt_cache(device_t self, struct aarch64_
 			break;
 		}
 
-		purging = cunit->cache_purging;
 		aprint_verbose_dev(self,
-		    "L%d %dKB/%dB %d-way%s%s%s%s %s %s cache\n",
+		    "L%d %uKB/%uB*%uL*%uW %s %s cache\n",
 		    level + 1,
 		    cunit->cache_size / 1024,
 		    cunit->cache_line_size,
+		    cunit->cache_sets,
 		    cunit->cache_ways,
-		    (purging & CACHE_PURGING_WT) ? " write-through" : "",
-		    (purging & CACHE_PURGING_WB) ? " write-back" : "",
-		    (purging & CACHE_PURGING_RA) ? " read-allocate" : "",
-		    (purging & CACHE_PURGING_WA) ? " write-allocate" : "",
 		    cachetype, cacheable);
 
 		if (cinfo[level].cacheable != CACHE_CACHEABLE_IDCACHE)

Index: src/sys/arch/aarch64/include/armreg.h
diff -u src/sys/arch/aarch64/include/armreg.h:1.45 src/sys/arch/aarch64/include/armreg.h:1.46
--- src/sys/arch/aarch64/include/armreg.h:1.45	Sat May 23 18:08:59 2020
+++ src/sys/arch/aarch64/include/armreg.h	Mon May 25 05:13:16 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: armreg.h,v 1.45 2020/05/23 18:08:59 ryo Exp $ */
+/* $NetBSD: armreg.h,v 1.46 2020/05/25 05:13:16 ryo Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -189,6 +189,7 @@ AARCH64REG_READ_INLINE2(cbar_el1, s3_1_c
 
 AARCH64REG_READ_INLINE(ccsidr_el1)
 
+/* 32bit format CCSIDR_EL1 */
 #define	CCSIDR_WT		__BIT(31)	// OBSOLETE: Write-through supported
 #define	CCSIDR_WB		__BIT(30)	// OBSOLETE: Write-back supported
 #define	CCSIDR_RA		__BIT(29)	// OBSOLETE: Read-allocation supported
@@ -197,6 +198,11 @@ AARCH64REG_READ_INLINE(ccsidr_el1)
 #define	CCSIDR_ASSOC		__BITS(12,3)	// (Associativity of cache) - 1
 #define	CCSIDR_LINESIZE 	__BITS(2,0)	// Number of bytes in cache line
 
+/* 64bit format CCSIDR_EL1 (ARMv8.3-CCIDX is implemented) */
+#define	CCSIDR64_NUMSET		__BITS(55,32)	// (Number of sets in cache) - 1
+#define	CCSIDR64_ASSOC		__BITS(23,3)	// (Associativity of cache) - 1
+#define	CCSIDR64_LINESIZE 	__BITS(2,0)	// Number of bytes in cache line
+
 AARCH64REG_READ_INLINE(clidr_el1)
 
 #define	CLIDR_ICB		__BITS(32,30)	// Inner cache boundary

Index: src/sys/arch/aarch64/include/cpufunc.h
diff -u src/sys/arch/aarch64/include/cpufunc.h:1.14 src/sys/arch/aarch64/include/cpufunc.h:1.15
--- src/sys/arch/aarch64/include/cpufunc.h:1.14	Fri May 15 04:55:40 2020
+++ src/sys/arch/aarch64/include/cpufunc.h	Mon May 25 05:13:16 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpufunc.h,v 1.14 2020/05/15 04:55:40 ryo Exp $	*/
+/*	$NetBSD: cpufunc.h,v 1.15 2020/05/25 05:13:16 ryo Exp $	*/
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -36,7 +36,7 @@
 
 struct aarch64_cache_unit {
 	u_int cache_type;
-#define CACHE_TYPE_UNKNOWN	0
+#define CACHE_TYPE_VPIPT	0	/* VMID-aware PIPT */
 #define CACHE_TYPE_VIVT		1	/* ASID-tagged VIVT */
 #define CACHE_TYPE_VIPT		2
 #define CACHE_TYPE_PIPT		3
@@ -45,11 +45,6 @@ struct aarch64_cache_unit {
 	u_int cache_sets;
 	u_int cache_way_size;
 	u_int cache_size;
-	u_int cache_purging;
-#define CACHE_PURGING_WB	0x01
-#define CACHE_PURGING_WT	0x02
-#define CACHE_PURGING_RA	0x04
-#define CACHE_PURGING_WA	0x08
 };
 
 struct aarch64_cache_info {

Reply via email to