Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Aug 2021 02:32:19 GMT
From:      Peter Grehan <grehan@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 28e22482279f - stable/13 - arm64: HWCAP/HWCAP2 aux args support for 32-bit ARM binaries.
Message-ID:  <202108220232.17M2WJCm005414@gitrepo.freebsd.org>

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

URL: https://cgit.FreeBSD.org/src/commit/?id=28e22482279f43dda9c78f3fec2189630e9b84cd

commit 28e22482279f43dda9c78f3fec2189630e9b84cd
Author:     Peter Grehan <grehan@FreeBSD.org>
AuthorDate: 2021-07-25 09:34:14 +0000
Commit:     Peter Grehan <grehan@FreeBSD.org>
CommitDate: 2021-08-22 04:17:46 +0000

    arm64: HWCAP/HWCAP2 aux args support for 32-bit ARM binaries.
    
    This fixes build/run of golang under COMPAT32 emulation.
    
    PR:     256897
    Reviewed by:    andrew, mmel, manu, jhb, cognet, Robert Clausecker
    Tested by:      brd, andrew, Robert Clausecker
    Relnotes:       yes
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D31175
    
    (cherry picked from commit bbe80bff7c3549128bd19862eea7899b3def1d7f)
---
 sys/arm64/arm64/elf32_machdep.c |   5 +
 sys/arm64/arm64/identcpu.c      | 302 ++++++++++++++++++++++++++++++++++++++++
 sys/arm64/include/armreg.h      | 131 +++++++++++++++++
 sys/arm64/include/elf.h         |  29 ++++
 sys/arm64/include/md_var.h      |   4 +
 5 files changed, 471 insertions(+)

diff --git a/sys/arm64/arm64/elf32_machdep.c b/sys/arm64/arm64/elf32_machdep.c
index 48d6dc189e3a..3625a4d124da 100644
--- a/sys/arm64/arm64/elf32_machdep.c
+++ b/sys/arm64/arm64/elf32_machdep.c
@@ -77,6 +77,9 @@ static boolean_t elf32_arm_abi_supported(struct image_params *, int32_t *,
 
 extern void freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
 
+u_long __read_frequently elf32_hwcap;
+u_long __read_frequently elf32_hwcap2;
+
 static struct sysentvec elf32_freebsd_sysvec = {
 	.sv_size	= SYS_MAXSYSCALL,
 	.sv_table	= freebsd32_sysent,
@@ -109,6 +112,8 @@ static struct sysentvec elf32_freebsd_sysvec = {
 	.sv_schedtail	= NULL,
 	.sv_thread_detach = NULL,
 	.sv_trap	= NULL,
+	.sv_hwcap	= &elf32_hwcap,
+	.sv_hwcap2	= &elf32_hwcap2,
 	.sv_onexec_old	= exec_onexec_old,
 	.sv_onexit	= exit_onexit,
 };
diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c
index 6395b3e0f08a..522526b92307 100644
--- a/sys/arm64/arm64/identcpu.c
+++ b/sys/arm64/arm64/identcpu.c
@@ -50,6 +50,10 @@ __FBSDID("$FreeBSD$");
 static void print_cpu_features(u_int cpu);
 static u_long parse_cpu_features_hwcap(void);
 static u_long parse_cpu_features_hwcap2(void);
+#ifdef COMPAT_FREEBSD32
+static u_long parse_cpu_features_hwcap32(void);
+static u_long parse_cpu_features_hwcap32_2(void);
+#endif
 
 char machine[] = "arm64";
 
@@ -135,6 +139,11 @@ struct cpu_desc {
 	uint64_t	id_aa64pfr0;
 	uint64_t	id_aa64pfr1;
 	uint64_t	ctr;
+#ifdef COMPAT_FREEBSD32
+	uint64_t	id_isar5;
+	uint64_t	mvfr0;
+	uint64_t	mvfr1;
+#endif
 };
 
 static struct cpu_desc cpu_desc[MAXCPU];
@@ -152,6 +161,11 @@ static u_int cpu_print_regs;
 #define	PRINT_ID_AA64_MMFR2	0x00004000
 #define	PRINT_ID_AA64_PFR0	0x00010000
 #define	PRINT_ID_AA64_PFR1	0x00020000
+#ifdef COMPAT_FREEBSD32
+#define	PRINT_ID_ISAR5		0x01000000
+#define	PRINT_MVFR0		0x02000000
+#define	PRINT_MVFR1		0x04000000
+#endif
 #define	PRINT_CTR_EL0		0x10000000
 
 struct cpu_parts {
@@ -987,6 +1001,167 @@ static struct mrs_field id_aa64pfr1_fields[] = {
 	MRS_FIELD_END,
 };
 
+#ifdef COMPAT_FREEBSD32
+/* ID_ISAR5_EL1 */
+static struct mrs_field_value id_isar5_vcma[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_ISAR5, VCMA, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value id_isar5_rdm[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_ISAR5, RDM, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value id_isar5_crc32[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_ISAR5, CRC32, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value id_isar5_sha2[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_ISAR5, SHA2, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value id_isar5_sha1[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_ISAR5, SHA1, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value id_isar5_aes[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_ISAR5, AES, NONE, BASE),
+	MRS_FIELD_VALUE(ID_ISAR5_AES_VMULL, "AES+VMULL"),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value id_isar5_sevl[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(ID_ISAR5, SEVL, NOP, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field id_isar5_fields[] = {
+	MRS_FIELD(ID_ISAR5, VCMA, false, MRS_LOWER, id_isar5_vcma),
+	MRS_FIELD(ID_ISAR5, RDM, false, MRS_LOWER, id_isar5_rdm),
+	MRS_FIELD(ID_ISAR5, CRC32, false, MRS_LOWER, id_isar5_crc32),
+	MRS_FIELD(ID_ISAR5, SHA2, false, MRS_LOWER, id_isar5_sha2),
+	MRS_FIELD(ID_ISAR5, SHA1, false, MRS_LOWER, id_isar5_sha1),
+	MRS_FIELD(ID_ISAR5, AES, false, MRS_LOWER, id_isar5_aes),
+	MRS_FIELD(ID_ISAR5, SEVL, false, MRS_LOWER, id_isar5_sevl),
+	MRS_FIELD_END,
+};
+
+/* MVFR0 */
+static struct mrs_field_value mvfr0_fpround[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(MVFR0, FPRound, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value mvfr0_fpsqrt[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(MVFR0, FPSqrt, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value mvfr0_fpdivide[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(MVFR0, FPDivide, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value mvfr0_fptrap[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(MVFR0, FPTrap, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value mvfr0_fpdp[] = {
+	MRS_FIELD_VALUE(MVFR0_FPDP_NONE, ""),
+	MRS_FIELD_VALUE(MVFR0_FPDP_VFP_v2, "DP VFPv2"),
+	MRS_FIELD_VALUE(MVFR0_FPDP_VFP_v3_v4, "DP VFPv3+v4"),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value mvfr0_fpsp[] = {
+	MRS_FIELD_VALUE(MVFR0_FPSP_NONE, ""),
+	MRS_FIELD_VALUE(MVFR0_FPSP_VFP_v2, "SP VFPv2"),
+	MRS_FIELD_VALUE(MVFR0_FPSP_VFP_v3_v4, "SP VFPv3+v4"),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value mvfr0_simdreg[] = {
+	MRS_FIELD_VALUE(MVFR0_SIMDReg_NONE, ""),
+	MRS_FIELD_VALUE(MVFR0_SIMDReg_FP, "FP 16x64"),
+	MRS_FIELD_VALUE(MVFR0_SIMDReg_AdvSIMD, "AdvSIMD"),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field mvfr0_fields[] = {
+	MRS_FIELD(MVFR0, FPRound, false, MRS_LOWER, mvfr0_fpround),
+	MRS_FIELD(MVFR0, FPSqrt, false, MRS_LOWER, mvfr0_fpsqrt),
+	MRS_FIELD(MVFR0, FPDivide, false, MRS_LOWER, mvfr0_fpdivide),
+	MRS_FIELD(MVFR0, FPTrap, false, MRS_LOWER, mvfr0_fptrap),
+	MRS_FIELD(MVFR0, FPDP, false, MRS_LOWER, mvfr0_fpdp),
+	MRS_FIELD(MVFR0, FPSP, false, MRS_LOWER, mvfr0_fpsp),
+	MRS_FIELD(MVFR0, SIMDReg, false, MRS_LOWER, mvfr0_simdreg),
+	MRS_FIELD_END,
+};
+
+/* MVFR1 */
+static struct mrs_field_value mvfr1_simdfmac[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(MVFR1, SIMDFMAC, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value mvfr1_fphp[] = {
+	MRS_FIELD_VALUE(MVFR1_FPHP_NONE, ""),
+	MRS_FIELD_VALUE(MVFR1_FPHP_CONV_SP, "FPHP SP Conv"),
+	MRS_FIELD_VALUE(MVFR1_FPHP_CONV_DP, "FPHP DP Conv"),
+	MRS_FIELD_VALUE(MVFR1_FPHP_ARITH, "FPHP Arith"),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value mvfr1_simdhp[] = {
+	MRS_FIELD_VALUE(MVFR1_SIMDHP_NONE, ""),
+	MRS_FIELD_VALUE(MVFR1_SIMDHP_CONV_SP, "SIMDHP SP Conv"),
+	MRS_FIELD_VALUE(MVFR1_SIMDHP_ARITH, "SIMDHP Arith"),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value mvfr1_simdsp[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(MVFR1, SIMDSP, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value mvfr1_simdint[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(MVFR1, SIMDInt, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value mvfr1_simdls[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(MVFR1, SIMDLS, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value mvfr1_fpdnan[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(MVFR1, FPDNaN, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field_value mvfr1_fpftz[] = {
+	MRS_FIELD_VALUE_NONE_IMPL(MVFR1, FPFtZ, NONE, IMPL),
+	MRS_FIELD_VALUE_END,
+};
+
+static struct mrs_field mvfr1_fields[] = {
+	MRS_FIELD(MVFR1, SIMDFMAC, false, MRS_LOWER, mvfr1_simdfmac),
+	MRS_FIELD(MVFR1, FPHP, false, MRS_LOWER, mvfr1_fphp),
+	MRS_FIELD(MVFR1, SIMDHP, false, MRS_LOWER, mvfr1_simdhp),
+	MRS_FIELD(MVFR1, SIMDSP, false, MRS_LOWER, mvfr1_simdsp),
+	MRS_FIELD(MVFR1, SIMDInt, false, MRS_LOWER, mvfr1_simdint),
+	MRS_FIELD(MVFR1, SIMDLS, false, MRS_LOWER, mvfr1_simdls),
+	MRS_FIELD(MVFR1, FPDNaN, false, MRS_LOWER, mvfr1_fpdnan),
+	MRS_FIELD(MVFR1, FPFtZ, false, MRS_LOWER, mvfr1_fpftz),
+	MRS_FIELD_END,
+};
+#endif /* COMPAT_FREEBSD32 */
+
 struct mrs_user_reg {
 	u_int		reg;
 	u_int		CRm;
@@ -1038,6 +1213,32 @@ static struct mrs_user_reg user_regs[] = {
 		.offset = __offsetof(struct cpu_desc, id_aa64mmfr0),
 		.fields = id_aa64mmfr0_fields,
 	},
+#ifdef COMPAT_FREEBSD32
+	{
+		/* id_isar5_el1 */
+		.reg = ID_ISAR5_EL1,
+		.CRm = 2,
+		.Op2 = 5,
+		.offset = __offsetof(struct cpu_desc, id_isar5),
+		.fields = id_isar5_fields,
+	},
+	{
+		/* mvfr0 */
+		.reg = MVFR0_EL1,
+		.CRm = 3,
+		.Op2 = 0,
+		.offset = __offsetof(struct cpu_desc, mvfr0),
+		.fields = mvfr0_fields,
+	},
+	{
+		/* mvfr1 */
+		.reg = MVFR1_EL1,
+		.CRm = 3,
+		.Op2 = 1,
+		.offset = __offsetof(struct cpu_desc, mvfr1),
+		.fields = mvfr1_fields,
+	},
+#endif /* COMPAT_FREEBSD32 */
 };
 
 #define	CPU_DESC_FIELD(desc, idx)					\
@@ -1272,6 +1473,12 @@ identify_cpu_sysinit(void *dummy __unused)
 	elf_hwcap = parse_cpu_features_hwcap();
 	elf_hwcap2 = parse_cpu_features_hwcap2();
 
+#ifdef COMPAT_FREEBSD32
+	/* 32-bit ARM versions of AT_HWCAP/HWCAP2 */
+	elf32_hwcap = parse_cpu_features_hwcap32();
+	elf32_hwcap2 = parse_cpu_features_hwcap32_2();
+#endif
+
 	if (dic && idc) {
 		arm64_icache_sync_range = &arm64_dic_idc_icache_sync_range;
 		if (bootverbose)
@@ -1483,6 +1690,66 @@ parse_cpu_features_hwcap2(void)
 	return (hwcap2);
 }
 
+#ifdef COMPAT_FREEBSD32
+static u_long
+parse_cpu_features_hwcap32(void)
+{
+	u_long hwcap = HWCAP32_DEFAULT;
+
+	if (MVFR0_FPDP_VAL(user_cpu_desc.mvfr0) >=
+	    MVFR0_FPDP_VFP_v2) {
+		hwcap |= HWCAP32_VFP;
+
+		if (MVFR0_FPDP_VAL(user_cpu_desc.mvfr0) ==
+		    MVFR0_FPDP_VFP_v3_v4) {
+			hwcap |= HWCAP32_VFPv3;
+
+			if (MVFR1_SIMDFMAC_VAL(user_cpu_desc.mvfr1) ==
+			    MVFR1_SIMDFMAC_IMPL)
+				hwcap |= HWCAP32_VFPv4;
+		}
+	}
+
+	if ((MVFR1_SIMDLS_VAL(user_cpu_desc.mvfr1) ==
+	     MVFR1_SIMDLS_IMPL) &&
+	    (MVFR1_SIMDInt_VAL(user_cpu_desc.mvfr1) ==
+	     MVFR1_SIMDInt_IMPL) &&
+	    (MVFR1_SIMDSP_VAL(user_cpu_desc.mvfr1) ==
+	     MVFR1_SIMDSP_IMPL))
+		hwcap |= HWCAP32_NEON;
+
+	return (hwcap);
+}
+
+static u_long
+parse_cpu_features_hwcap32_2(void)
+{
+	u_long hwcap2 = 0;
+
+	if (ID_ISAR5_AES_VAL(user_cpu_desc.id_isar5) >=
+	    ID_ISAR5_AES_BASE)
+		hwcap2 |= HWCAP32_2_AES;
+
+	if (ID_ISAR5_AES_VAL(user_cpu_desc.id_isar5) ==
+	    ID_ISAR5_AES_VMULL)
+		hwcap2 |= HWCAP32_2_PMULL;
+
+	if (ID_ISAR5_SHA1_VAL(user_cpu_desc.id_isar5) ==
+	    ID_ISAR5_SHA1_IMPL)
+		hwcap2 |= HWCAP32_2_SHA1;
+
+	if (ID_ISAR5_SHA2_VAL(user_cpu_desc.id_isar5) ==
+	    ID_ISAR5_SHA2_IMPL)
+		hwcap2 |= HWCAP32_2_SHA2;
+
+	if (ID_ISAR5_CRC32_VAL(user_cpu_desc.id_isar5) ==
+	    ID_ISAR5_CRC32_IMPL)
+		hwcap2 |= HWCAP32_2_CRC32;
+
+	return (hwcap2);
+}
+#endif /* COMPAT_FREEBSD32 */
+
 static void
 print_ctr_fields(struct sbuf *sb, uint64_t reg, void *arg)
 {
@@ -1696,6 +1963,23 @@ print_cpu_features(u_int cpu)
 		print_id_register(sb, "Auxiliary Features 1",
 		    cpu_desc[cpu].id_aa64afr1, id_aa64afr1_fields);
 
+#ifdef COMPAT_FREEBSD32
+	/* AArch32 Instruction Set Attribute Register 5 */
+	if (cpu == 0 || (cpu_print_regs & PRINT_ID_ISAR5) != 0)
+		print_id_register(sb, "AArch32 Instruction Set Attributes 5",
+		     cpu_desc[cpu].id_isar5, id_isar5_fields);
+
+	/* AArch32 Media and VFP Feature Register 0 */
+	if (cpu == 0 || (cpu_print_regs & PRINT_MVFR0) != 0)
+		print_id_register(sb, "AArch32 Media and VFP Features 0",
+		     cpu_desc[cpu].mvfr0, mvfr0_fields);
+
+	/* AArch32 Media and VFP Feature Register 1 */
+	if (cpu == 0 || (cpu_print_regs & PRINT_MVFR1) != 0)
+		print_id_register(sb, "AArch32 Media and VFP Features 1",
+		     cpu_desc[cpu].mvfr1, mvfr1_fields);
+#endif
+
 	sbuf_delete(sb);
 	sb = NULL;
 #undef SEP_STR
@@ -1795,6 +2079,15 @@ identify_cpu(u_int cpu)
 	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);
+#ifdef COMPAT_FREEBSD32
+	/* Only read aarch32 SRs if EL0-32 is available */
+	if (ID_AA64PFR0_EL0_VAL(cpu_desc[cpu].id_aa64pfr0) ==
+	    ID_AA64PFR0_EL0_64_32) {
+		cpu_desc[cpu].id_isar5 = READ_SPECIALREG(id_isar5_el1);
+		cpu_desc[cpu].mvfr0 = READ_SPECIALREG(mvfr0_el1);
+		cpu_desc[cpu].mvfr1 = READ_SPECIALREG(mvfr1_el1);
+	}
+#endif
 }
 
 static void
@@ -1859,4 +2152,13 @@ check_cpu_regs(u_int cpu)
 		identify_cache(cpu_desc[cpu].ctr);
 		cpu_print_regs |= PRINT_CTR_EL0;
 	}
+
+#ifdef COMPAT_FREEBSD32
+	if (cpu_desc[cpu].id_isar5 != cpu_desc[0].id_isar5)
+		cpu_print_regs |= PRINT_ID_ISAR5;
+	if (cpu_desc[cpu].mvfr0 != cpu_desc[0].mvfr0)
+		cpu_print_regs |= PRINT_MVFR0;
+	if (cpu_desc[cpu].mvfr1 != cpu_desc[0].mvfr1)
+		cpu_print_regs |= PRINT_MVFR1;
+#endif
 }
diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h
index 9521b0826064..60389f4171ef 100644
--- a/sys/arm64/include/armreg.h
+++ b/sys/arm64/include/armreg.h
@@ -771,6 +771,45 @@
 #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_ISAR5_EL1 */
+#define	ID_ISAR5_EL1			MRS_REG(3, 0, 0, 2, 5)
+#define	ID_ISAR5_SEVL_SHIFT		0
+#define	ID_ISAR5_SEVL_MASK		(UL(0xf) << ID_ISAR5_SEVL_SHIFT)
+#define	ID_ISAR5_SEVL_VAL(x)		((x) & ID_ISAR5_SEVL_MASK)
+#define	 ID_ISAR5_SEVL_NOP		(UL(0x0) << ID_ISAR5_SEVL_SHIFT)
+#define	 ID_ISAR5_SEVL_IMPL		(UL(0x1) << ID_ISAR5_SEVL_SHIFT)
+#define	ID_ISAR5_AES_SHIFT		4
+#define	ID_ISAR5_AES_MASK		(UL(0xf) << ID_ISAR5_AES_SHIFT)
+#define	ID_ISAR5_AES_VAL(x)		((x) & ID_ISAR5_AES_MASK)
+#define	 ID_ISAR5_AES_NONE		(UL(0x0) << ID_ISAR5_AES_SHIFT)
+#define	 ID_ISAR5_AES_BASE		(UL(0x1) << ID_ISAR5_AES_SHIFT)
+#define	 ID_ISAR5_AES_VMULL		(UL(0x2) << ID_ISAR5_AES_SHIFT)
+#define	ID_ISAR5_SHA1_SHIFT		8
+#define	ID_ISAR5_SHA1_MASK		(UL(0xf) << ID_ISAR5_SHA1_SHIFT)
+#define	ID_ISAR5_SHA1_VAL(x)		((x) & ID_ISAR5_SHA1_MASK)
+#define	 ID_ISAR5_SHA1_NONE		(UL(0x0) << ID_ISAR5_SHA1_SHIFT)
+#define	 ID_ISAR5_SHA1_IMPL		(UL(0x1) << ID_ISAR5_SHA1_SHIFT)
+#define	ID_ISAR5_SHA2_SHIFT		12
+#define	ID_ISAR5_SHA2_MASK		(UL(0xf) << ID_ISAR5_SHA2_SHIFT)
+#define	ID_ISAR5_SHA2_VAL(x)		((x) & ID_ISAR5_SHA2_MASK)
+#define	 ID_ISAR5_SHA2_NONE		(UL(0x0) << ID_ISAR5_SHA2_SHIFT)
+#define	 ID_ISAR5_SHA2_IMPL		(UL(0x1) << ID_ISAR5_SHA2_SHIFT)
+#define	ID_ISAR5_CRC32_SHIFT		16
+#define	ID_ISAR5_CRC32_MASK		(UL(0xf) << ID_ISAR5_CRC32_SHIFT)
+#define	ID_ISAR5_CRC32_VAL(x)		((x) & ID_ISAR5_CRC32_MASK)
+#define	 ID_ISAR5_CRC32_NONE		(UL(0x0) << ID_ISAR5_CRC32_SHIFT)
+#define	 ID_ISAR5_CRC32_IMPL		(UL(0x1) << ID_ISAR5_CRC32_SHIFT)
+#define	ID_ISAR5_RDM_SHIFT		24
+#define	ID_ISAR5_RDM_MASK		(UL(0xf) << ID_ISAR5_RDM_SHIFT)
+#define	ID_ISAR5_RDM_VAL(x)		((x) & ID_ISAR5_RDM_MASK)
+#define	 ID_ISAR5_RDM_NONE		(UL(0x0) << ID_ISAR5_RDM_SHIFT)
+#define	 ID_ISAR5_RDM_IMPL		(UL(0x1) << ID_ISAR5_RDM_SHIFT)
+#define	ID_ISAR5_VCMA_SHIFT		28
+#define	ID_ISAR5_VCMA_MASK		(UL(0xf) << ID_ISAR5_VCMA_SHIFT)
+#define	ID_ISAR5_VCMA_VAL(x)		((x) & ID_ISAR5_VCMA_MASK)
+#define	 ID_ISAR5_VCMA_NONE		(UL(0x0) << ID_ISAR5_VCMA_SHIFT)
+#define	 ID_ISAR5_VCMA_IMPL		(UL(0x1) << ID_ISAR5_VCMA_SHIFT)
+
 /* MAIR_EL1 - Memory Attribute Indirection Register */
 #define	MAIR_ATTR_MASK(idx)	(0xff << ((n)* 8))
 #define	MAIR_ATTR(attr, idx) ((attr) << ((idx) * 8))
@@ -779,6 +818,98 @@
 #define	 MAIR_NORMAL_WT		0xbb
 #define	 MAIR_NORMAL_WB		0xff
 
+/* MVFR0_EL1 */
+#define	MVFR0_EL1			MRS_REG(3, 0, 0, 3, 0)
+#define	MVFR0_SIMDReg_SHIFT		0
+#define	MVFR0_SIMDReg_MASK		(UL(0xf) << MVFR0_SIMDReg_SHIFT)
+#define	MVFR0_SIMDReg_VAL(x)		((x) & MVFR0_SIMDReg_MASK)
+#define	 MVFR0_SIMDReg_NONE		(UL(0x0) << MVFR0_SIMDReg_SHIFT)
+#define	 MVFR0_SIMDReg_FP		(UL(0x1) << MVFR0_SIMDReg_SHIFT)
+#define	 MVFR0_SIMDReg_AdvSIMD		(UL(0x2) << MVFR0_SIMDReg_SHIFT)
+#define	MVFR0_FPSP_SHIFT		4
+#define	MVFR0_FPSP_MASK			(UL(0xf) << MVFR0_FPSP_SHIFT)
+#define	MVFR0_FPSP_VAL(x)		((x) & MVFR0_FPSP_MASK)
+#define	 MVFR0_FPSP_NONE		(UL(0x0) << MVFR0_FPSP_SHIFT)
+#define	 MVFR0_FPSP_VFP_v2		(UL(0x1) << MVFR0_FPSP_SHIFT)
+#define	 MVFR0_FPSP_VFP_v3_v4		(UL(0x2) << MVFR0_FPSP_SHIFT)
+#define	MVFR0_FPDP_SHIFT		8
+#define	MVFR0_FPDP_MASK			(UL(0xf) << MVFR0_FPDP_SHIFT)
+#define	MVFR0_FPDP_VAL(x)		((x) & MVFR0_FPDP_MASK)
+#define	 MVFR0_FPDP_NONE		(UL(0x0) << MVFR0_FPDP_SHIFT)
+#define	 MVFR0_FPDP_VFP_v2		(UL(0x1) << MVFR0_FPDP_SHIFT)
+#define	 MVFR0_FPDP_VFP_v3_v4		(UL(0x2) << MVFR0_FPDP_SHIFT)
+#define	MVFR0_FPTrap_SHIFT		12
+#define	MVFR0_FPTrap_MASK		(UL(0xf) << MVFR0_FPTrap_SHIFT)
+#define	MVFR0_FPTrap_VAL(x)		((x) & MVFR0_FPTrap_MASK)
+#define	 MVFR0_FPTrap_NONE		(UL(0x0) << MVFR0_FPTrap_SHIFT)
+#define	 MVFR0_FPTrap_IMPL		(UL(0x1) << MVFR0_FPTrap_SHIFT)
+#define	MVFR0_FPDivide_SHIFT		16
+#define	MVFR0_FPDivide_MASK		(UL(0xf) << MVFR0_FPDivide_SHIFT)
+#define	MVFR0_FPDivide_VAL(x)		((x) & MVFR0_FPDivide_MASK)
+#define	 MVFR0_FPDivide_NONE		(UL(0x0) << MVFR0_FPDivide_SHIFT)
+#define	 MVFR0_FPDivide_IMPL		(UL(0x1) << MVFR0_FPDivide_SHIFT)
+#define	MVFR0_FPSqrt_SHIFT		20
+#define	MVFR0_FPSqrt_MASK		(UL(0xf) << MVFR0_FPSqrt_SHIFT)
+#define	MVFR0_FPSqrt_VAL(x)		((x) & MVFR0_FPSqrt_MASK)
+#define	 MVFR0_FPSqrt_NONE		(UL(0x0) << MVFR0_FPSqrt_SHIFT)
+#define	 MVFR0_FPSqrt_IMPL		(UL(0x1) << MVFR0_FPSqrt_SHIFT)
+#define	MVFR0_FPShVec_SHIFT		24
+#define	MVFR0_FPShVec_MASK		(UL(0xf) << MVFR0_FPShVec_SHIFT)
+#define	MVFR0_FPShVec_VAL(x)		((x) & MVFR0_FPShVec_MASK)
+#define	 MVFR0_FPShVec_NONE		(UL(0x0) << MVFR0_FPShVec_SHIFT)
+#define	 MVFR0_FPShVec_IMPL		(UL(0x1) << MVFR0_FPShVec_SHIFT)
+#define	MVFR0_FPRound_SHIFT		28
+#define	MVFR0_FPRound_MASK		(UL(0xf) << MVFR0_FPRound_SHIFT)
+#define	MVFR0_FPRound_VAL(x)		((x) & MVFR0_FPRound_MASK)
+#define	 MVFR0_FPRound_NONE		(UL(0x0) << MVFR0_FPRound_SHIFT)
+#define	 MVFR0_FPRound_IMPL		(UL(0x1) << MVFR0_FPRound_SHIFT)
+
+/* MVFR1_EL1 */
+#define	MVFR1_EL1			MRS_REG(3, 0, 0, 3, 1)
+#define	MVFR1_FPFtZ_SHIFT		0
+#define	MVFR1_FPFtZ_MASK		(UL(0xf) << MVFR1_FPFtZ_SHIFT)
+#define	MVFR1_FPFtZ_VAL(x)		((x) & MVFR1_FPFtZ_MASK)
+#define	 MVFR1_FPFtZ_NONE		(UL(0x0) << MVFR1_FPFtZ_SHIFT)
+#define	 MVFR1_FPFtZ_IMPL		(UL(0x1) << MVFR1_FPFtZ_SHIFT)
+#define	MVFR1_FPDNaN_SHIFT		4
+#define	MVFR1_FPDNaN_MASK		(UL(0xf) << MVFR1_FPDNaN_SHIFT)
+#define	MVFR1_FPDNaN_VAL(x)		((x) & MVFR1_FPDNaN_MASK)
+#define	 MVFR1_FPDNaN_NONE		(UL(0x0) << MVFR1_FPDNaN_SHIFT)
+#define	 MVFR1_FPDNaN_IMPL		(UL(0x1) << MVFR1_FPDNaN_SHIFT)
+#define	MVFR1_SIMDLS_SHIFT		8
+#define	MVFR1_SIMDLS_MASK		(UL(0xf) << MVFR1_SIMDLS_SHIFT)
+#define	MVFR1_SIMDLS_VAL(x)		((x) & MVFR1_SIMDLS_MASK)
+#define	 MVFR1_SIMDLS_NONE		(UL(0x0) << MVFR1_SIMDLS_SHIFT)
+#define	 MVFR1_SIMDLS_IMPL		(UL(0x1) << MVFR1_SIMDLS_SHIFT)
+#define	MVFR1_SIMDInt_SHIFT		12
+#define	MVFR1_SIMDInt_MASK		(UL(0xf) << MVFR1_SIMDInt_SHIFT)
+#define	MVFR1_SIMDInt_VAL(x)		((x) & MVFR1_SIMDInt_MASK)
+#define	 MVFR1_SIMDInt_NONE		(UL(0x0) << MVFR1_SIMDInt_SHIFT)
+#define	 MVFR1_SIMDInt_IMPL		(UL(0x1) << MVFR1_SIMDInt_SHIFT)
+#define	MVFR1_SIMDSP_SHIFT		16
+#define	MVFR1_SIMDSP_MASK		(UL(0xf) << MVFR1_SIMDSP_SHIFT)
+#define	MVFR1_SIMDSP_VAL(x)		((x) & MVFR1_SIMDSP_MASK)
+#define	 MVFR1_SIMDSP_NONE		(UL(0x0) << MVFR1_SIMDSP_SHIFT)
+#define	 MVFR1_SIMDSP_IMPL		(UL(0x1) << MVFR1_SIMDSP_SHIFT)
+#define	MVFR1_SIMDHP_SHIFT		20
+#define	MVFR1_SIMDHP_MASK		(UL(0xf) << MVFR1_SIMDHP_SHIFT)
+#define	MVFR1_SIMDHP_VAL(x)		((x) & MVFR1_SIMDHP_MASK)
+#define	 MVFR1_SIMDHP_NONE		(UL(0x0) << MVFR1_SIMDHP_SHIFT)
+#define	 MVFR1_SIMDHP_CONV_SP		(UL(0x1) << MVFR1_SIMDHP_SHIFT)
+#define	 MVFR1_SIMDHP_ARITH		(UL(0x2) << MVFR1_SIMDHP_SHIFT)
+#define	MVFR1_FPHP_SHIFT		24
+#define	MVFR1_FPHP_MASK			(UL(0xf) << MVFR1_FPHP_SHIFT)
+#define	MVFR1_FPHP_VAL(x)		((x) & MVFR1_FPHP_MASK)
+#define	 MVFR1_FPHP_NONE		(UL(0x0) << MVFR1_FPHP_SHIFT)
+#define	 MVFR1_FPHP_CONV_SP		(UL(0x1) << MVFR1_FPHP_SHIFT)
+#define	 MVFR1_FPHP_CONV_DP		(UL(0x2) << MVFR1_FPHP_SHIFT)
+#define	 MVFR1_FPHP_ARITH		(UL(0x3) << MVFR1_FPHP_SHIFT)
+#define	MVFR1_SIMDFMAC_SHIFT		28
+#define	MVFR1_SIMDFMAC_MASK		(UL(0xf) << MVFR1_SIMDFMAC_SHIFT)
+#define	MVFR1_SIMDFMAC_VAL(x)		((x) & MVFR1_SIMDFMAC_MASK)
+#define	 MVFR1_SIMDFMAC_NONE		(UL(0x0) << MVFR1_SIMDFMAC_SHIFT)
+#define	 MVFR1_SIMDFMAC_IMPL		(UL(0x1) << MVFR1_SIMDFMAC_SHIFT)
+
 /* PAR_EL1 - Physical Address Register */
 #define	PAR_F_SHIFT		0
 #define	PAR_F			(0x1 << PAR_F_SHIFT)
diff --git a/sys/arm64/include/elf.h b/sys/arm64/include/elf.h
index bed84e6c755a..3f7c3964d428 100644
--- a/sys/arm64/include/elf.h
+++ b/sys/arm64/include/elf.h
@@ -150,4 +150,33 @@ __ElfType(Auxinfo);
 #define	HWCAP2_RNG		0x00010000
 #define	HWCAP2_BTI		0x00020000
 
+#ifdef COMPAT_FREEBSD32
+/* ARM HWCAP */
+#define	HWCAP32_HALF		0x00000002	/* Always set.               */
+#define	HWCAP32_THUMB		0x00000004	/* Always set.               */
+#define	HWCAP32_FAST_MULT	0x00000010	/* Always set.               */
+#define	HWCAP32_VFP		0x00000040
+#define	HWCAP32_EDSP		0x00000080	/* Always set.               */
+#define	HWCAP32_NEON		0x00001000
+#define	HWCAP32_VFPv3		0x00002000
+#define	HWCAP32_TLS		0x00008000	/* Always set.               */
+#define	HWCAP32_VFPv4		0x00010000
+#define	HWCAP32_IDIVA		0x00020000	/* Always set.               */
+#define	HWCAP32_IDIVT		0x00040000	/* Always set.               */
+#define	HWCAP32_VFPD32		0x00080000	/* Always set.               */
+#define	HWCAP32_LPAE		0x00100000	/* Always set.               */
+
+#define HWCAP32_DEFAULT \
+   (HWCAP32_HALF | HWCAP32_THUMB | HWCAP32_FAST_MULT | HWCAP32_EDSP |\
+    HWCAP32_TLS | HWCAP32_IDIVA | HWCAP32_IDIVT | HWCAP32_VFPD32 |   \
+    HWCAP32_LPAE)
+
+/* ARM HWCAP2 */
+#define	HWCAP32_2_AES		0x00000001
+#define	HWCAP32_2_PMULL		0x00000002
+#define	HWCAP32_2_SHA1		0x00000004
+#define	HWCAP32_2_SHA2		0x00000008
+#define	HWCAP32_2_CRC32		0x00000010
+#endif
+
 #endif /* !_MACHINE_ELF_H_ */
diff --git a/sys/arm64/include/md_var.h b/sys/arm64/include/md_var.h
index 73cf642148b5..beaea0f8e719 100644
--- a/sys/arm64/include/md_var.h
+++ b/sys/arm64/include/md_var.h
@@ -38,6 +38,10 @@ extern char sigcode[];
 extern int szsigcode;
 extern u_long elf_hwcap;
 extern u_long elf_hwcap2;
+#ifdef COMPAT_FREEBSD32
+extern u_long elf32_hwcap;
+extern u_long elf32_hwcap2;
+#endif
 
 struct dumperinfo;
 



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