arm64: parse HWCAP values using user_cpu_desc
The hard work of parsing fields per-CPU, handling heterogeneous features, and excluding features from userspace is already done by update_special_regs. We can build our set of HWCAPs from the result. This exposed a small bug in update_special_regs, in which the generated bitmask was not wide enough, and as a result some bits weren't being exposed in user_cpu_desc. Fix this. While here, adjust some formatting. Reviewed by: andrew MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D26069
This commit is contained in:
parent
6194973636
commit
3d89a9759f
@ -47,7 +47,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/elf.h>
|
||||
|
||||
static void print_cpu_features(u_int cpu);
|
||||
static u_long parse_cpu_features_hwcap(u_int cpu);
|
||||
static u_long parse_cpu_features_hwcap(void);
|
||||
|
||||
char machine[] = "arm64";
|
||||
|
||||
@ -1095,7 +1095,7 @@ update_special_regs(u_int cpu)
|
||||
for (j = 0; fields[j].type != 0; j++) {
|
||||
switch (fields[j].type & MRS_TYPE_MASK) {
|
||||
case MRS_EXACT:
|
||||
user_reg &= ~(0xfu << fields[j].shift);
|
||||
user_reg &= ~(0xful << fields[j].shift);
|
||||
user_reg |=
|
||||
(uint64_t)MRS_EXACT_FIELD(fields[j].type) <<
|
||||
fields[j].shift;
|
||||
@ -1131,7 +1131,6 @@ static void
|
||||
identify_cpu_sysinit(void *dummy __unused)
|
||||
{
|
||||
int cpu;
|
||||
u_long hwcap;
|
||||
bool dic, idc;
|
||||
|
||||
dic = (allow_dic != 0);
|
||||
@ -1139,11 +1138,6 @@ identify_cpu_sysinit(void *dummy __unused)
|
||||
|
||||
CPU_FOREACH(cpu) {
|
||||
check_cpu_regs(cpu);
|
||||
hwcap = parse_cpu_features_hwcap(cpu);
|
||||
if (elf_hwcap == 0)
|
||||
elf_hwcap = hwcap;
|
||||
else
|
||||
elf_hwcap &= hwcap;
|
||||
if (cpu != 0)
|
||||
update_special_regs(cpu);
|
||||
|
||||
@ -1153,6 +1147,9 @@ identify_cpu_sysinit(void *dummy __unused)
|
||||
idc = false;
|
||||
}
|
||||
|
||||
/* Exposed to userspace as AT_HWCAP */
|
||||
elf_hwcap = parse_cpu_features_hwcap();
|
||||
|
||||
if (dic && idc) {
|
||||
arm64_icache_sync_range = &arm64_dic_idc_icache_sync_range;
|
||||
if (bootverbose)
|
||||
@ -1184,43 +1181,49 @@ cpu_features_sysinit(void *dummy __unused)
|
||||
SYSINIT(cpu_features, SI_SUB_SMP, SI_ORDER_ANY, cpu_features_sysinit, NULL);
|
||||
|
||||
static u_long
|
||||
parse_cpu_features_hwcap(u_int cpu)
|
||||
parse_cpu_features_hwcap(void)
|
||||
{
|
||||
u_long hwcap = 0;
|
||||
|
||||
if (ID_AA64ISAR0_DP_VAL(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_DP_IMPL)
|
||||
if (ID_AA64ISAR0_DP_VAL(user_cpu_desc.id_aa64isar0) ==
|
||||
ID_AA64ISAR0_DP_IMPL)
|
||||
hwcap |= HWCAP_ASIMDDP;
|
||||
|
||||
if (ID_AA64ISAR0_SM4_VAL(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_SM4_IMPL)
|
||||
if (ID_AA64ISAR0_SM4_VAL(user_cpu_desc.id_aa64isar0) ==
|
||||
ID_AA64ISAR0_SM4_IMPL)
|
||||
hwcap |= HWCAP_SM4;
|
||||
|
||||
if (ID_AA64ISAR0_SM3_VAL(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_SM3_IMPL)
|
||||
if (ID_AA64ISAR0_SM3_VAL(user_cpu_desc.id_aa64isar0) ==
|
||||
ID_AA64ISAR0_SM3_IMPL)
|
||||
hwcap |= HWCAP_SM3;
|
||||
|
||||
if (ID_AA64ISAR0_RDM_VAL(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_RDM_IMPL)
|
||||
if (ID_AA64ISAR0_RDM_VAL(user_cpu_desc.id_aa64isar0) ==
|
||||
ID_AA64ISAR0_RDM_IMPL)
|
||||
hwcap |= HWCAP_ASIMDRDM;
|
||||
|
||||
if (ID_AA64ISAR0_Atomic_VAL(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_Atomic_IMPL)
|
||||
if (ID_AA64ISAR0_Atomic_VAL(user_cpu_desc.id_aa64isar0) ==
|
||||
ID_AA64ISAR0_Atomic_IMPL)
|
||||
hwcap |= HWCAP_ATOMICS;
|
||||
|
||||
if (ID_AA64ISAR0_CRC32_VAL(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_CRC32_BASE)
|
||||
if (ID_AA64ISAR0_CRC32_VAL(user_cpu_desc.id_aa64isar0) ==
|
||||
ID_AA64ISAR0_CRC32_BASE)
|
||||
hwcap |= HWCAP_CRC32;
|
||||
|
||||
switch (ID_AA64ISAR0_SHA2_VAL(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;
|
||||
switch (ID_AA64ISAR0_SHA2_VAL(user_cpu_desc.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_VAL(cpu_desc[cpu].id_aa64isar0))
|
||||
if (ID_AA64ISAR0_SHA1_VAL(user_cpu_desc.id_aa64isar0))
|
||||
hwcap |= HWCAP_SHA1;
|
||||
|
||||
switch (ID_AA64ISAR0_AES_VAL(cpu_desc[cpu].id_aa64isar0)) {
|
||||
switch (ID_AA64ISAR0_AES_VAL(user_cpu_desc.id_aa64isar0)) {
|
||||
case ID_AA64ISAR0_AES_BASE:
|
||||
hwcap |= HWCAP_AES;
|
||||
break;
|
||||
@ -1231,22 +1234,27 @@ parse_cpu_features_hwcap(u_int cpu)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ID_AA64ISAR1_LRCPC_VAL(cpu_desc[cpu].id_aa64isar1) == ID_AA64ISAR1_LRCPC_RCPC_8_3)
|
||||
if (ID_AA64ISAR1_LRCPC_VAL(user_cpu_desc.id_aa64isar1) ==
|
||||
ID_AA64ISAR1_LRCPC_RCPC_8_3)
|
||||
hwcap |= HWCAP_LRCPC;
|
||||
|
||||
if (ID_AA64ISAR1_FCMA_VAL(cpu_desc[cpu].id_aa64isar1) == ID_AA64ISAR1_FCMA_IMPL)
|
||||
if (ID_AA64ISAR1_FCMA_VAL(user_cpu_desc.id_aa64isar1) ==
|
||||
ID_AA64ISAR1_FCMA_IMPL)
|
||||
hwcap |= HWCAP_FCMA;
|
||||
|
||||
if (ID_AA64ISAR1_JSCVT_VAL(cpu_desc[cpu].id_aa64isar1) == ID_AA64ISAR1_JSCVT_IMPL)
|
||||
if (ID_AA64ISAR1_JSCVT_VAL(user_cpu_desc.id_aa64isar1) ==
|
||||
ID_AA64ISAR1_JSCVT_IMPL)
|
||||
hwcap |= HWCAP_JSCVT;
|
||||
|
||||
if (ID_AA64ISAR1_DPB_VAL(cpu_desc[cpu].id_aa64isar1) == ID_AA64ISAR1_DPB_DCCVAP)
|
||||
if (ID_AA64ISAR1_DPB_VAL(user_cpu_desc.id_aa64isar1) ==
|
||||
ID_AA64ISAR1_DPB_DCCVAP)
|
||||
hwcap |= HWCAP_DCPOP;
|
||||
|
||||
if (ID_AA64PFR0_SVE_VAL(cpu_desc[cpu].id_aa64pfr0) == ID_AA64PFR0_SVE_IMPL)
|
||||
if (ID_AA64PFR0_SVE_VAL(user_cpu_desc.id_aa64pfr0) ==
|
||||
ID_AA64PFR0_SVE_IMPL)
|
||||
hwcap |= HWCAP_SVE;
|
||||
|
||||
switch (ID_AA64PFR0_AdvSIMD_VAL(cpu_desc[cpu].id_aa64pfr0)) {
|
||||
switch (ID_AA64PFR0_AdvSIMD_VAL(user_cpu_desc.id_aa64pfr0)) {
|
||||
case ID_AA64PFR0_AdvSIMD_IMPL:
|
||||
hwcap |= HWCAP_ASIMD;
|
||||
break;
|
||||
@ -1257,7 +1265,7 @@ parse_cpu_features_hwcap(u_int cpu)
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ID_AA64PFR0_FP_VAL(cpu_desc[cpu].id_aa64pfr0)) {
|
||||
switch (ID_AA64PFR0_FP_VAL(user_cpu_desc.id_aa64pfr0)) {
|
||||
case ID_AA64PFR0_FP_IMPL:
|
||||
hwcap |= HWCAP_FP;
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user