| #include <stdint.h> |
| |
| #include <arm/linux/api.h> |
| #include <log.h> |
| |
| |
| void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( |
| uint32_t features, |
| uint32_t midr, |
| const struct cpuinfo_arm_chipset chipset[restrict static 1], |
| struct cpuinfo_arm_isa isa[restrict static 1]) |
| { |
| if (features & CPUINFO_ARM_LINUX_FEATURE_AES) { |
| isa->aes = true; |
| } |
| if (features & CPUINFO_ARM_LINUX_FEATURE_PMULL) { |
| isa->pmull = true; |
| } |
| if (features & CPUINFO_ARM_LINUX_FEATURE_SHA1) { |
| isa->sha1 = true; |
| } |
| if (features & CPUINFO_ARM_LINUX_FEATURE_SHA2) { |
| isa->sha2 = true; |
| } |
| if (features & CPUINFO_ARM_LINUX_FEATURE_CRC32) { |
| isa->crc32 = true; |
| } |
| if (features & CPUINFO_ARM_LINUX_FEATURE_ATOMICS) { |
| isa->atomics = true; |
| } |
| const uint32_t fp16arith_mask = CPUINFO_ARM_LINUX_FEATURE_FPHP | CPUINFO_ARM_LINUX_FEATURE_ASIMDHP; |
| if ((features & fp16arith_mask) == fp16arith_mask) { |
| if (chipset->series == cpuinfo_arm_chipset_series_samsung_exynos && chipset->model == 9810) { |
| /* Exynos 9810 reports that it supports FP16 compute, but in fact only little cores do */ |
| cpuinfo_log_warning("FP16 arithmetics disabled: only little cores of Exynos 9810 support FP16 compute"); |
| } else { |
| isa->fp16arith = true; |
| } |
| } else if (features & CPUINFO_ARM_LINUX_FEATURE_FPHP) { |
| cpuinfo_log_warning("FP16 arithmetics disabled: detected support only for scalar operations"); |
| } else if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDHP) { |
| cpuinfo_log_warning("FP16 arithmetics disabled: detected support only for SIMD operations"); |
| } |
| /* Qualcomm Kryo 385 may have buggy kernel configuration that doesn't report VQRDMLAH/VQRDMLSH instructions */ |
| switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) { |
| case UINT32_C(0x51008020): /* Kryo 385 Gold (Cortex-A75) */ |
| case UINT32_C(0x51008030): /* Kryo 385 Silver (Cortex-A55) */ |
| isa->rdm = true; |
| break; |
| default: |
| if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM) { |
| isa->rdm = true; |
| } |
| break; |
| } |
| if (features & CPUINFO_ARM_LINUX_FEATURE_JSCVT) { |
| isa->jscvt = true; |
| } |
| if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM) { |
| isa->rdm = true; |
| } |
| if (features & CPUINFO_ARM_LINUX_FEATURE_JSCVT) { |
| isa->jscvt = true; |
| } |
| if (features & CPUINFO_ARM_LINUX_FEATURE_FCMA) { |
| isa->fcma = true; |
| } |
| } |