Index: head/sys/arm64/arm64/identcpu.c =================================================================== --- head/sys/arm64/arm64/identcpu.c +++ head/sys/arm64/arm64/identcpu.c @@ -47,7 +47,7 @@ #include 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 @@ 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 @@ identify_cpu_sysinit(void *dummy __unused) { int cpu; - u_long hwcap; bool dic, idc; dic = (allow_dic != 0); @@ -1139,11 +1138,6 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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;