Index: sys/arm64/arm64/elf_machdep.c =================================================================== --- sys/arm64/arm64/elf_machdep.c +++ sys/arm64/arm64/elf_machdep.c @@ -55,6 +55,8 @@ #include "linker_if.h" +u_long elf_hwcap; + static struct sysentvec elf64_freebsd_sysvec = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, @@ -89,6 +91,7 @@ .sv_schedtail = NULL, .sv_thread_detach = NULL, .sv_trap = NULL, + .sv_hwcap = &elf_hwcap, }; INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec); Index: sys/arm64/arm64/identcpu.c =================================================================== --- sys/arm64/arm64/identcpu.c +++ sys/arm64/arm64/identcpu.c @@ -43,6 +43,7 @@ #include #include #include +#include static int ident_lock; @@ -162,6 +163,9 @@ CPU_IMPLEMENTER_NONE, }; +/* HWCAP */ +extern u_long elf_hwcap; + static void identify_cpu_sysinit(void *dummy __unused) { @@ -242,6 +246,7 @@ break; case ID_AA64ISAR0_RDM_IMPL: sbuf_printf(sb, "%sRDM", SEP_STR); + elf_hwcap |= HWCAP_ASIMDRDM; break; default: sbuf_printf(sb, "%sUnknown RDM", SEP_STR); @@ -252,6 +257,7 @@ break; case ID_AA64ISAR0_ATOMIC_IMPL: sbuf_printf(sb, "%sAtomic", SEP_STR); + elf_hwcap |= HWCAP_ATOMICS; break; default: sbuf_printf(sb, "%sUnknown Atomic", SEP_STR); @@ -262,9 +268,11 @@ break; case ID_AA64ISAR0_AES_BASE: sbuf_printf(sb, "%sAES", SEP_STR); + elf_hwcap |= HWCAP_AES; break; case ID_AA64ISAR0_AES_PMULL: sbuf_printf(sb, "%sAES+PMULL", SEP_STR); + elf_hwcap |= HWCAP_PMULL | HWCAP_AES; break; default: sbuf_printf(sb, "%sUnknown AES", SEP_STR); @@ -276,6 +284,7 @@ break; case ID_AA64ISAR0_SHA1_BASE: sbuf_printf(sb, "%sSHA1", SEP_STR); + elf_hwcap |= HWCAP_SHA1; break; default: sbuf_printf(sb, "%sUnknown SHA1", SEP_STR); @@ -287,9 +296,11 @@ break; case ID_AA64ISAR0_SHA2_BASE: sbuf_printf(sb, "%sSHA2", SEP_STR); + elf_hwcap |= HWCAP_SHA2; break; case ID_AA64ISAR0_SHA2_512: sbuf_printf(sb, "%sSHA2+SHA512", SEP_STR); + elf_hwcap |= HWCAP_SHA2 | HWCAP_SHA512; break; default: sbuf_printf(sb, "%sUnknown SHA2", SEP_STR); @@ -301,6 +312,7 @@ break; case ID_AA64ISAR0_CRC32_BASE: sbuf_printf(sb, "%sCRC32", SEP_STR); + elf_hwcap |= HWCAP_CRC32; break; default: sbuf_printf(sb, "%sUnknown CRC32", SEP_STR); @@ -323,6 +335,7 @@ break; case ID_AA64ISAR0_SM3_IMPL: sbuf_printf(sb, "%sSM3", SEP_STR); + elf_hwcap |= HWCAP_SM3; break; default: sbuf_printf(sb, "%sUnknown SM3", SEP_STR); @@ -334,6 +347,7 @@ break; case ID_AA64ISAR0_SM4_IMPL: sbuf_printf(sb, "%sSM4", SEP_STR); + elf_hwcap |= HWCAP_SM4; break; default: sbuf_printf(sb, "%sUnknown SM4", SEP_STR); @@ -345,6 +359,7 @@ break; case ID_AA64ISAR0_DP_IMPL: sbuf_printf(sb, "%sDotProd", SEP_STR); + elf_hwcap |= HWCAP_ASIMDDP; break; default: sbuf_printf(sb, "%sUnknown DP", SEP_STR); @@ -392,6 +407,7 @@ break; case ID_AA64ISAR1_LRCPC_IMPL: sbuf_printf(sb, "%sRCpc", SEP_STR); + elf_hwcap |= HWCAP_LRCPC; break; default: sbuf_printf(sb, "%sUnknown RCpc", SEP_STR); @@ -403,6 +419,7 @@ break; case ID_AA64ISAR1_FCMA_IMPL: sbuf_printf(sb, "%sFCMA", SEP_STR); + elf_hwcap |= HWCAP_FCMA; break; default: sbuf_printf(sb, "%sUnknown FCMA", SEP_STR); @@ -414,6 +431,7 @@ break; case ID_AA64ISAR1_JSCVT_IMPL: sbuf_printf(sb, "%sJS Conv", SEP_STR); + elf_hwcap |= HWCAP_JSCVT; break; default: sbuf_printf(sb, "%sUnknown JS Conv", SEP_STR); @@ -447,6 +465,7 @@ break; case ID_AA64ISAR1_DPB_IMPL: sbuf_printf(sb, "%sDC CVAP", SEP_STR); + elf_hwcap |= HWCAP_DCPOP; break; default: sbuf_printf(sb, "%sUnknown DC CVAP", SEP_STR); @@ -471,6 +490,7 @@ break; case ID_AA64PFR0_SVE_IMPL: sbuf_printf(sb, "%sSVE", SEP_STR); + elf_hwcap |= HWCAP_SVE; break; default: sbuf_printf(sb, "%sUnknown SVE", SEP_STR); @@ -504,9 +524,11 @@ break; case ID_AA64PFR0_ADV_SIMD_IMPL: sbuf_printf(sb, "%sAdvSIMD", SEP_STR); + elf_hwcap |= HWCAP_ASIMD; break; case ID_AA64PFR0_ADV_SIMD_HP: sbuf_printf(sb, "%sAdvSIMD+HP", SEP_STR); + elf_hwcap |= HWCAP_ASIMD | HWCAP_ASIMDDP; break; default: sbuf_printf(sb, "%sUnknown AdvSIMD", SEP_STR); @@ -518,9 +540,11 @@ break; case ID_AA64PFR0_FP_IMPL: sbuf_printf(sb, "%sFloat", SEP_STR); + elf_hwcap |= HWCAP_FP; break; case ID_AA64PFR0_FP_HP: sbuf_printf(sb, "%sFloat+HP", SEP_STR); + elf_hwcap |= HWCAP_FP | HWCAP_FPHP; break; default: sbuf_printf(sb, "%sUnknown Float", SEP_STR); Index: sys/arm64/include/elf.h =================================================================== --- sys/arm64/include/elf.h +++ sys/arm64/include/elf.h @@ -114,4 +114,34 @@ #define ET_DYN_LOAD_ADDR 0x100000 +/* HWCAP */ + +#define HWCAP_FP 0x00000001 +#define HWCAP_ASIMD 0x00000002 +#define HWCAP_EVTSTRM 0x00000004 +#define HWCAP_AES 0x00000008 +#define HWCAP_PMULL 0x00000010 +#define HWCAP_SHA1 0x00000020 +#define HWCAP_SHA2 0x00000040 +#define HWCAP_CRC32 0x00000080 +#define HWCAP_ATOMICS 0x00000100 +#define HWCAP_FPHP 0x00000200 +#define HWCAP_CPUID 0x00000400 +#define HWCAP_ASIMDRDM 0x00000800 +#define HWCAP_JSCVT 0x00001000 +#define HWCAP_FCMA 0x00002000 +#define HWCAP_LRCPC 0x00004000 +#define HWCAP_DCPOP 0x00008000 +#define HWCAP_SHA3 0x00010000 +#define HWCAP_SM3 0x00020000 +#define HWCAP_SM4 0x00040000 +#define HWCAP_ASIMDDP 0x00080000 +#define HWCAP_SHA512 0x00100000 +#define HWCAP_SVE 0x00200000 +#define HWCAP_ASIMDFHM 0x00400000 +#define HWCAP_DIT 0x00800000 +#define HWCAP_USCAT 0x01000000 +#define HWCAP_ILRCPC 0x02000000 +#define HWCAP_FLAGM 0x04000000 + #endif /* !_MACHINE_ELF_H_ */