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
MFC after:	3 weeks
Relnotes:	yes
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D31175
This commit is contained in:
Peter Grehan 2021-07-25 19:34:14 +10:00
parent 87c010e6e3
commit bbe80bff7c
5 changed files with 471 additions and 0 deletions

View file

@ -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,
@ -112,6 +115,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,
};

View file

@ -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) \
@ -1288,6 +1489,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)
@ -1499,6 +1706,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)
{
@ -1712,6 +1979,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
@ -1811,6 +2095,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
@ -1875,4 +2168,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
}

View file

@ -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))
@ -780,6 +819,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)

View file

@ -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_ */

View file

@ -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;