diff --git a/sys/arm64/arm64/elf32_machdep.c b/sys/arm64/arm64/elf32_machdep.c --- a/sys/arm64/arm64/elf32_machdep.c +++ b/sys/arm64/arm64/elf32_machdep.c @@ -77,6 +77,9 @@ 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 @@ .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 --- a/sys/arm64/arm64/identcpu.c +++ b/sys/arm64/arm64/identcpu.c @@ -50,6 +50,10 @@ 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 @@ 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 @@ #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 @@ 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 @@ .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 @@ 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 @@ 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_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 @@ 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 @@ 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 --- 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)) @@ -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) diff --git a/sys/arm64/include/elf.h b/sys/arm64/include/elf.h --- a/sys/arm64/include/elf.h +++ b/sys/arm64/include/elf.h @@ -150,4 +150,33 @@ #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 --- a/sys/arm64/include/md_var.h +++ b/sys/arm64/include/md_var.h @@ -38,6 +38,10 @@ 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;