Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Jul 2022 07:37:27 GMT
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 66687da66633 - stable/13 - Decode the arm64 SVE ID register
Message-ID:  <202207190737.26J7bR38021627@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=66687da66633c432744c2a687b253188eeed0ab1

commit 66687da66633c432744c2a687b253188eeed0ab1
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2022-06-28 11:44:49 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2022-07-19 07:03:31 +0000

    Decode the arm64 SVE ID register
    
    The field values are only valid when the ID_AA64PFR0_EL1.SVE or
    ID_AA64PFR1_EL1.SME vields are non-zero. When this is not the case
    the register is reserved as zero so is safe to read, but the SVEver
    field will be incorrect so only print the decoded register when
    the SVE or SME fields indicate it is valid.
    
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit cb91f112a3dc6cb68fe618623f59cee576ce4d14)
---
 sys/arm64/arm64/identcpu.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++
 sys/arm64/include/armreg.h | 56 +++++++++++++++++++++++++++
 2 files changed, 150 insertions(+)

diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c
index 514671837015..93c7dd973c66 100644
--- a/sys/arm64/arm64/identcpu.c
+++ b/sys/arm64/arm64/identcpu.c
@@ -132,6 +132,7 @@ struct cpu_desc {
 	uint64_t	id_aa64mmfr2;
 	uint64_t	id_aa64pfr0;
 	uint64_t	id_aa64pfr1;
+	uint64_t	id_aa64zfr0;
 	uint64_t	ctr;
 #ifdef COMPAT_FREEBSD32
 	uint64_t	id_isar5;
@@ -140,6 +141,7 @@ struct cpu_desc {
 #endif
 	uint64_t	clidr;
 	uint32_t	ccsidr[MAX_CACHES][2]; /* 2 possible types. */
+	bool		have_sve;
 };
 
 static struct cpu_desc cpu_desc[MAXCPU];
@@ -157,6 +159,7 @@ static u_int cpu_print_regs;
 #define	PRINT_ID_AA64_MMFR2	0x00004000
 #define	PRINT_ID_AA64_PFR0	0x00010000
 #define	PRINT_ID_AA64_PFR1	0x00020000
+#define	PRINT_ID_AA64_ZFR0	0x00100000
 #ifdef COMPAT_FREEBSD32
 #define	PRINT_ID_ISAR5		0x01000000
 #define	PRINT_MVFR0		0x02000000
@@ -1227,6 +1230,70 @@ static struct mrs_field id_aa64pfr1_fields[] = {
 	MRS_FIELD_END,
 };
 
+
+/* ID_AA64ZFR0_EL1 */
+static struct mrs_field_value id_aa64zfr0_f64mm[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_AA64ZFR0, F64MM, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value id_aa64zfr0_f32mm[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_AA64ZFR0, F32MM, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value id_aa64zfr0_i8mm[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_AA64ZFR0, I8MM, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value id_aa64zfr0_sm4[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_AA64ZFR0, SM4, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value id_aa64zfr0_sha3[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_AA64ZFR0, SHA3, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value id_aa64zfr0_bf16[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_AA64ZFR0, BF16, NONE, BASE),
+	MRS_FIELD_VALUE(ID_AA64ZFR0_BF16_EBF, "BF16+EBF"),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value id_aa64zfr0_bitperm[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_AA64ZFR0, BitPerm, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value id_aa64zfr0_aes[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_AA64ZFR0, AES, NONE, BASE),
+	MRS_FIELD_VALUE(ID_AA64ZFR0_AES_PMULL, "AES+PMULL"),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value id_aa64zfr0_svever[] = {
+	MRS_FIELD_VALUE(ID_AA64ZFR0_SVEver_SVE1, "SVE1"),
+	MRS_FIELD_VALUE(ID_AA64ZFR0_SVEver_SVE2, "SVE2"),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field id_aa64zfr0_fields[] = {
+	MRS_FIELD(ID_AA64ZFR0, F64MM, false, MRS_EXACT, id_aa64zfr0_f64mm),
+	MRS_FIELD(ID_AA64ZFR0, F32MM, false, MRS_EXACT, id_aa64zfr0_f32mm),
+	MRS_FIELD(ID_AA64ZFR0, I8MM, false, MRS_EXACT, id_aa64zfr0_i8mm),
+	MRS_FIELD(ID_AA64ZFR0, SM4, false, MRS_EXACT, id_aa64zfr0_sm4),
+	MRS_FIELD(ID_AA64ZFR0, SHA3, false, MRS_EXACT, id_aa64zfr0_sha3),
+	MRS_FIELD(ID_AA64ZFR0, BF16, false, MRS_EXACT, id_aa64zfr0_bf16),
+	MRS_FIELD(ID_AA64ZFR0, BitPerm, false, MRS_EXACT, id_aa64zfr0_bitperm),
+	MRS_FIELD(ID_AA64ZFR0, AES, false, MRS_EXACT, id_aa64zfr0_aes),
+	MRS_FIELD(ID_AA64ZFR0, SVEver, false, MRS_EXACT, id_aa64zfr0_svever),
+	MRS_FIELD_END,
+};
+
+
 #ifdef COMPAT_FREEBSD32
 /* ID_ISAR5_EL1 */
 static struct mrs_field_value id_isar5_vcma[] = {
@@ -2129,6 +2196,12 @@ print_cpu_features(u_int cpu)
 		print_id_register(sb, "Auxiliary Features 1",
 		    cpu_desc[cpu].id_aa64afr1, id_aa64afr1_fields);
 
+	/* AArch64 SVE Feature Register 0 */
+	/* We check the cpu == 0 case when setting PRINT_ID_AA64_ZFR0 */
+	if ((cpu_print_regs & PRINT_ID_AA64_ZFR0) != 0)
+		print_id_register(sb, "SVE Features 0",
+		    cpu_desc[cpu].id_aa64zfr0, id_aa64zfr0_fields);
+
 #ifdef COMPAT_FREEBSD32
 	/* AArch32 Instruction Set Attribute Register 5 */
 	if (cpu == 0 || (cpu_print_regs & PRINT_ID_ISAR5) != 0)
@@ -2213,6 +2286,16 @@ identify_cpu(u_int cpu)
 	cpu_desc[cpu].id_aa64pfr0 = READ_SPECIALREG(id_aa64pfr0_el1);
 	cpu_desc[cpu].id_aa64pfr1 = READ_SPECIALREG(id_aa64pfr1_el1);
 
+	/*
+	 * ID_AA64ZFR0_EL1 is only valid when at least one of:
+	 *  - ID_AA64PFR0_EL1.SVE is non-zero
+	 *  - ID_AA64PFR1_EL1.SME is non-zero
+	 * In other cases it is zero, but still safe to read
+	 */
+	cpu_desc[cpu].have_sve =
+	    (ID_AA64PFR0_SVE_VAL(cpu_desc[cpu].id_aa64pfr0) != 0);
+	cpu_desc[cpu].id_aa64zfr0 = READ_SPECIALREG(ID_AA64ZFR0_EL1_REG);
+
 	cpu_desc[cpu].clidr = READ_SPECIALREG(clidr_el1);
 
 	clidr = cpu_desc[cpu].clidr;
@@ -2296,6 +2379,17 @@ check_cpu_regs(u_int cpu)
 	if (cpu_desc[cpu].id_aa64pfr1 != cpu_desc[0].id_aa64pfr1)
 		cpu_print_regs |= PRINT_ID_AA64_PFR1;
 
+	/* Only print if ID_AA64ZFR0_EL1 is valid */
+	if (cpu_desc[cpu].have_sve) {
+		/* Print if the value changed */
+		if (cpu_desc[cpu].id_aa64zfr0 != cpu_desc[0].id_aa64zfr0) {
+			cpu_print_regs |= PRINT_ID_AA64_ZFR0;
+		/* Print if it didn't, but the previous CPU was invalid */
+		} else if (cpu > 0 && !cpu_desc[cpu - 1].have_sve) {
+			cpu_print_regs |= PRINT_ID_AA64_ZFR0;
+		}
+	}
+
 	if (cpu_desc[cpu].ctr != cpu_desc[0].ctr) {
 		/*
 		 * If the cache type register is different we may
diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h
index 27ae55f2743c..2d80c0cacb3d 100644
--- a/sys/arm64/include/armreg.h
+++ b/sys/arm64/include/armreg.h
@@ -915,6 +915,62 @@
 #define	 ID_AA64PFR1_RAS_frac_V1	(UL(0x0) << ID_AA64PFR1_RAS_frac_SHIFT)
 #define	 ID_AA64PFR1_RAS_frac_V2	(UL(0x1) << ID_AA64PFR1_RAS_frac_SHIFT)
 
+/* ID_AA64ZFR0_EL1 */
+#define	ID_AA64ZFR0_EL1			MRS_REG(ID_AA64ZFR0_EL1)
+#define	ID_AA64ZFR0_EL1_REG		MRS_REG_ALT_NAME(ID_AA64ZFR0_EL1)
+#define	ID_AA64ZFR0_EL1_op0		3
+#define	ID_AA64ZFR0_EL1_op1		0
+#define	ID_AA64ZFR0_EL1_CRn		0
+#define	ID_AA64ZFR0_EL1_CRm		4
+#define	ID_AA64ZFR0_EL1_op2		4
+#define	ID_AA64ZFR0_SVEver_SHIFT	0
+#define	ID_AA64ZFR0_SVEver_MASK		(UL(0xf) << ID_AA64ZFR0_SVEver_SHIFT)
+#define	ID_AA64ZFR0_SVEver_VAL(x)	((x) & ID_AA64ZFR0_SVEver_MASK
+#define	ID_AA64ZFR0_SVEver_SVE1		(UL(0x0) << ID_AA64ZFR0_SVEver_SHIFT)
+#define	ID_AA64ZFR0_SVEver_SVE2		(UL(0x1) << ID_AA64ZFR0_SVEver_SHIFT)
+#define	ID_AA64ZFR0_AES_SHIFT		4
+#define	ID_AA64ZFR0_AES_MASK		(UL(0xf) << ID_AA64ZFR0_AES_SHIFT)
+#define	ID_AA64ZFR0_AES_VAL(x)		((x) & ID_AA64ZFR0_AES_MASK
+#define	ID_AA64ZFR0_AES_NONE		(UL(0x0) << ID_AA64ZFR0_AES_SHIFT)
+#define	ID_AA64ZFR0_AES_BASE		(UL(0x1) << ID_AA64ZFR0_AES_SHIFT)
+#define	ID_AA64ZFR0_AES_PMULL		(UL(0x2) << ID_AA64ZFR0_AES_SHIFT)
+#define	ID_AA64ZFR0_BitPerm_SHIFT	16
+#define	ID_AA64ZFR0_BitPerm_MASK	(UL(0xf) << ID_AA64ZFR0_BitPerm_SHIFT)
+#define	ID_AA64ZFR0_BitPerm_VAL(x)	((x) & ID_AA64ZFR0_BitPerm_MASK
+#define	ID_AA64ZFR0_BitPerm_NONE	(UL(0x0) << ID_AA64ZFR0_BitPerm_SHIFT)
+#define	ID_AA64ZFR0_BitPerm_IMPL	(UL(0x1) << ID_AA64ZFR0_BitPerm_SHIFT)
+#define	ID_AA64ZFR0_BF16_SHIFT		20
+#define	ID_AA64ZFR0_BF16_MASK		(UL(0xf) << ID_AA64ZFR0_BF16_SHIFT)
+#define	ID_AA64ZFR0_BF16_VAL(x)		((x) & ID_AA64ZFR0_BF16_MASK
+#define	ID_AA64ZFR0_BF16_NONE		(UL(0x0) << ID_AA64ZFR0_BF16_SHIFT)
+#define	ID_AA64ZFR0_BF16_BASE		(UL(0x1) << ID_AA64ZFR0_BF16_SHIFT)
+#define	ID_AA64ZFR0_BF16_EBF		(UL(0x1) << ID_AA64ZFR0_BF16_SHIFT)
+#define	ID_AA64ZFR0_SHA3_SHIFT		32
+#define	ID_AA64ZFR0_SHA3_MASK		(UL(0xf) << ID_AA64ZFR0_SHA3_SHIFT)
+#define	ID_AA64ZFR0_SHA3_VAL(x)		((x) & ID_AA64ZFR0_SHA3_MASK
+#define	ID_AA64ZFR0_SHA3_NONE		(UL(0x0) << ID_AA64ZFR0_SHA3_SHIFT)
+#define	ID_AA64ZFR0_SHA3_IMPL		(UL(0x1) << ID_AA64ZFR0_SHA3_SHIFT)
+#define	ID_AA64ZFR0_SM4_SHIFT		40
+#define	ID_AA64ZFR0_SM4_MASK		(UL(0xf) << ID_AA64ZFR0_SM4_SHIFT)
+#define	ID_AA64ZFR0_SM4_VAL(x)		((x) & ID_AA64ZFR0_SM4_MASK
+#define	ID_AA64ZFR0_SM4_NONE		(UL(0x0) << ID_AA64ZFR0_SM4_SHIFT)
+#define	ID_AA64ZFR0_SM4_IMPL		(UL(0x1) << ID_AA64ZFR0_SM4_SHIFT)
+#define	ID_AA64ZFR0_I8MM_SHIFT		44
+#define	ID_AA64ZFR0_I8MM_MASK		(UL(0xf) << ID_AA64ZFR0_I8MM_SHIFT)
+#define	ID_AA64ZFR0_I8MM_VAL(x)		((x) & ID_AA64ZFR0_I8MM_MASK
+#define	ID_AA64ZFR0_I8MM_NONE		(UL(0x0) << ID_AA64ZFR0_I8MM_SHIFT)
+#define	ID_AA64ZFR0_I8MM_IMPL		(UL(0x1) << ID_AA64ZFR0_I8MM_SHIFT)
+#define	ID_AA64ZFR0_F32MM_SHIFT		52
+#define	ID_AA64ZFR0_F32MM_MASK		(UL(0xf) << ID_AA64ZFR0_F32MM_SHIFT)
+#define	ID_AA64ZFR0_F32MM_VAL(x)	((x) & ID_AA64ZFR0_F32MM_MASK
+#define	ID_AA64ZFR0_F32MM_NONE		(UL(0x0) << ID_AA64ZFR0_F32MM_SHIFT)
+#define	ID_AA64ZFR0_F32MM_IMPL		(UL(0x1) << ID_AA64ZFR0_F32MM_SHIFT)
+#define	ID_AA64ZFR0_F64MM_SHIFT		56
+#define	ID_AA64ZFR0_F64MM_MASK		(UL(0xf) << ID_AA64ZFR0_F64MM_SHIFT)
+#define	ID_AA64ZFR0_F64MM_VAL(x)	((x) & ID_AA64ZFR0_F64MM_MASK
+#define	ID_AA64ZFR0_F64MM_NONE		(UL(0x0) << ID_AA64ZFR0_F64MM_SHIFT)
+#define	ID_AA64ZFR0_F64MM_IMPL		(UL(0x1) << ID_AA64ZFR0_F64MM_SHIFT)
+
 /* ID_ISAR5_EL1 */
 #define	ID_ISAR5_EL1			MRS_REG(ID_ISAR5_EL1)
 #define	ID_ISAR5_EL1_op0		0x3



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202207190737.26J7bR38021627>