diff options
author | Emmanuel Vadot <manu@FreeBSD.org> | 2020-06-19 18:25:27 +0000 |
---|---|---|
committer | Emmanuel Vadot <manu@FreeBSD.org> | 2020-06-19 18:25:27 +0000 |
commit | 4b95d1ffa7a2426c5977e349037a22386a1b88ad (patch) | |
tree | 210c0872d46f4ac7c30ea77290a85ac4a97e5183 /sys/arm64 | |
parent | a1187fb9dd74bfb595d6b7224ecb569f2c32b51f (diff) | |
download | src-test2-4b95d1ffa7a2426c5977e349037a22386a1b88ad.tar.gz src-test2-4b95d1ffa7a2426c5977e349037a22386a1b88ad.zip |
Notes
Diffstat (limited to 'sys/arm64')
-rw-r--r-- | sys/arm64/arm64/elf_machdep.c | 3 | ||||
-rw-r--r-- | sys/arm64/arm64/identcpu.c | 105 | ||||
-rw-r--r-- | sys/arm64/include/cpu.h | 1 | ||||
-rw-r--r-- | sys/arm64/include/elf.h | 30 |
4 files changed, 134 insertions, 5 deletions
diff --git a/sys/arm64/arm64/elf_machdep.c b/sys/arm64/arm64/elf_machdep.c index 1aa942cf28f4..90149303f664 100644 --- a/sys/arm64/arm64/elf_machdep.c +++ b/sys/arm64/arm64/elf_machdep.c @@ -55,6 +55,8 @@ __FBSDID("$FreeBSD$"); #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 @@ static struct sysentvec elf64_freebsd_sysvec = { .sv_schedtail = NULL, .sv_thread_detach = NULL, .sv_trap = NULL, + .sv_hwcap = &elf_hwcap, }; INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec); diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c index 707b6bc4d284..62b4a7a2933e 100644 --- a/sys/arm64/arm64/identcpu.c +++ b/sys/arm64/arm64/identcpu.c @@ -44,8 +44,11 @@ __FBSDID("$FreeBSD$"); #include <machine/cpu.h> #include <machine/cpufunc.h> #include <machine/undefined.h> +#include <machine/elf.h> static int ident_lock; +static void print_cpu_features(u_int cpu); +static u_long parse_cpu_features_hwcap(u_int cpu); char machine[] = "arm64"; @@ -398,10 +401,14 @@ update_user_regs(u_int cpu) } } +/* HWCAP */ +extern u_long elf_hwcap; + static void identify_cpu_sysinit(void *dummy __unused) { int cpu; + u_long hwcap; /* Create a user visible cpu description with safe values */ memset(&user_cpu_desc, 0, sizeof(user_cpu_desc)); @@ -413,6 +420,11 @@ identify_cpu_sysinit(void *dummy __unused) CPU_FOREACH(cpu) { print_cpu_features(cpu); + hwcap = parse_cpu_features_hwcap(cpu); + if (elf_hwcap == 0) + elf_hwcap = hwcap; + else + elf_hwcap &= hwcap; update_user_regs(cpu); } @@ -420,7 +432,95 @@ identify_cpu_sysinit(void *dummy __unused) } SYSINIT(idenrity_cpu, SI_SUB_SMP, SI_ORDER_ANY, identify_cpu_sysinit, NULL); -void +static u_long +parse_cpu_features_hwcap(u_int cpu) +{ + u_long hwcap = 0; + + if (ID_AA64ISAR0_DP(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_DP_IMPL) + hwcap |= HWCAP_ASIMDDP; + + if (ID_AA64ISAR0_SM4(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_SM4_IMPL) + hwcap |= HWCAP_SM4; + + if (ID_AA64ISAR0_SM3(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_SM3_IMPL) + hwcap |= HWCAP_SM3; + + if (ID_AA64ISAR0_RDM(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_RDM_IMPL) + hwcap |= HWCAP_ASIMDRDM; + + if (ID_AA64ISAR0_Atomic(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_Atomic_IMPL) + hwcap |= HWCAP_ATOMICS; + + if (ID_AA64ISAR0_CRC32(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_CRC32_BASE) + hwcap |= HWCAP_CRC32; + + switch (ID_AA64ISAR0_SHA2(cpu_desc[cpu].id_aa64isar0)) { + case ID_AA64ISAR0_SHA2_BASE: + hwcap |= HWCAP_SHA2; + break; + case ID_AA64ISAR0_SHA2_512: + hwcap |= HWCAP_SHA2 | HWCAP_SHA512; + break; + default: + break; + } + + if (ID_AA64ISAR0_SHA1(cpu_desc[cpu].id_aa64isar0)) + hwcap |= HWCAP_SHA1; + + switch (ID_AA64ISAR0_AES(cpu_desc[cpu].id_aa64isar0)) { + case ID_AA64ISAR0_AES_BASE: + hwcap |= HWCAP_AES; + break; + case ID_AA64ISAR0_AES_PMULL: + hwcap |= HWCAP_PMULL | HWCAP_AES; + break; + default: + break; + } + + if (ID_AA64ISAR1_LRCPC(cpu_desc[cpu].id_aa64isar1) == ID_AA64ISAR1_LRCPC_IMPL) + hwcap |= HWCAP_LRCPC; + + if (ID_AA64ISAR1_FCMA(cpu_desc[cpu].id_aa64isar1) == ID_AA64ISAR1_FCMA_IMPL) + hwcap |= HWCAP_FCMA; + + if (ID_AA64ISAR1_JSCVT(cpu_desc[cpu].id_aa64isar1) == ID_AA64ISAR1_JSCVT_IMPL) + hwcap |= HWCAP_JSCVT; + + if (ID_AA64ISAR1_DPB(cpu_desc[cpu].id_aa64isar1) == ID_AA64ISAR1_DPB_IMPL) + hwcap |= HWCAP_DCPOP; + + if (ID_AA64PFR0_SVE(cpu_desc[cpu].id_aa64pfr0) == ID_AA64PFR0_SVE_IMPL) + hwcap |= HWCAP_SVE; + + switch (ID_AA64PFR0_AdvSIMD(cpu_desc[cpu].id_aa64pfr0)) { + case ID_AA64PFR0_AdvSIMD_IMPL: + hwcap |= HWCAP_ASIMD; + break; + case ID_AA64PFR0_AdvSIMD_HP: + hwcap |= HWCAP_ASIMD | HWCAP_ASIMDDP; + break; + default: + break; + } + + switch (ID_AA64PFR0_FP(cpu_desc[cpu].id_aa64pfr0)) { + case ID_AA64PFR0_FP_IMPL: + hwcap |= HWCAP_FP; + break; + case ID_AA64PFR0_FP_HP: + hwcap |= HWCAP_FP | HWCAP_FPHP; + break; + default: + break; + } + + return (hwcap); +} + +static void print_cpu_features(u_int cpu) { struct sbuf *sb; @@ -474,9 +574,6 @@ print_cpu_features(u_int cpu) "hardware bugs that may cause the incorrect operation of " "atomic operations.\n"); - if (cpu != 0 && cpu_print_regs == 0) - return; - #define SEP_STR ((printed++) == 0) ? "" : "," /* AArch64 Instruction Set Attribute Register 0 */ diff --git a/sys/arm64/include/cpu.h b/sys/arm64/include/cpu.h index 5663e50ebcbc..4b2305967b1a 100644 --- a/sys/arm64/include/cpu.h +++ b/sys/arm64/include/cpu.h @@ -163,7 +163,6 @@ void cpu_reset(void) __dead2; void fork_trampoline(void); void identify_cpu(void); void install_cpu_errata(void); -void print_cpu_features(u_int); void swi_vm(void *v); #define CPU_AFFINITY(cpu) __cpu_affinity[(cpu)] diff --git a/sys/arm64/include/elf.h b/sys/arm64/include/elf.h index 04487c43abf6..b1572784ff77 100644 --- a/sys/arm64/include/elf.h +++ b/sys/arm64/include/elf.h @@ -114,4 +114,34 @@ __ElfType(Auxinfo); #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_ */ |