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>