1 #include <stdint.h> 2 3 #include <arm/linux/api.h> 4 #include <cpuinfo/log.h> 5 6 cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(uint32_t features,uint32_t midr,const struct cpuinfo_arm_chipset chipset[restrict static1],struct cpuinfo_arm_isa isa[restrict static1])7void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo( 8 uint32_t features, 9 uint32_t midr, 10 const struct cpuinfo_arm_chipset chipset[restrict static 1], 11 struct cpuinfo_arm_isa isa[restrict static 1]) 12 { 13 if (features & CPUINFO_ARM_LINUX_FEATURE_AES) { 14 isa->aes = true; 15 } 16 if (features & CPUINFO_ARM_LINUX_FEATURE_PMULL) { 17 isa->pmull = true; 18 } 19 if (features & CPUINFO_ARM_LINUX_FEATURE_SHA1) { 20 isa->sha1 = true; 21 } 22 if (features & CPUINFO_ARM_LINUX_FEATURE_SHA2) { 23 isa->sha2 = true; 24 } 25 if (features & CPUINFO_ARM_LINUX_FEATURE_CRC32) { 26 isa->crc32 = true; 27 } 28 if (features & CPUINFO_ARM_LINUX_FEATURE_ATOMICS) { 29 isa->atomics = true; 30 } 31 const uint32_t fp16arith_mask = CPUINFO_ARM_LINUX_FEATURE_FPHP | CPUINFO_ARM_LINUX_FEATURE_ASIMDHP; 32 if ((features & fp16arith_mask) == fp16arith_mask) { 33 if (chipset->series == cpuinfo_arm_chipset_series_samsung_exynos && chipset->model == 9810) { 34 /* Exynos 9810 reports that it supports FP16 compute, but in fact only little cores do */ 35 cpuinfo_log_warning("FP16 arithmetics disabled: only little cores of Exynos 9810 support FP16 compute"); 36 } else { 37 isa->fp16arith = true; 38 } 39 } else if (features & CPUINFO_ARM_LINUX_FEATURE_FPHP) { 40 cpuinfo_log_warning("FP16 arithmetics disabled: detected support only for scalar operations"); 41 } else if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDHP) { 42 cpuinfo_log_warning("FP16 arithmetics disabled: detected support only for SIMD operations"); 43 } 44 /* 45 * Many phones ship with an old kernel configuration that doesn't report 46 * SQRDMLAH/SQRDMLSH/UQRDMLAH/UQRDMLSH instructions. 47 * Use a MIDR-based heuristic to whitelist processors known to support it: 48 * - Processors with Qualcomm-modified Cortex-A55 cores 49 * - Processors with Qualcomm-modified Cortex-A75 cores 50 * - Processors with Qualcomm-modified Cortex-A76 cores 51 * - Kirin 980 processor 52 */ 53 switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) { 54 case UINT32_C(0x51008020): /* Kryo 385 Gold (Cortex-A75) */ 55 case UINT32_C(0x51008030): /* Kryo 385 Silver (Cortex-A55) */ 56 case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */ 57 isa->rdm = true; 58 break; 59 default: 60 if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM) { 61 isa->rdm = true; 62 } 63 if (chipset->series == cpuinfo_arm_chipset_series_hisilicon_kirin && chipset->model == 980) { 64 isa->rdm = true; 65 } 66 break; 67 } 68 /* 69 * Many phones ship with an old kernel configuration that doesn't report UDOT/SDOT instructions. 70 * Use a MIDR-based heuristic to whitelist processors known to support it: 71 * - Processors with Qualcomm-modified Cortex-A76 cores 72 * - Kirin 980 processor 73 */ 74 switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) { 75 case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */ 76 isa->dot = true; 77 break; 78 default: 79 if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDDP) { 80 isa->dot = true; 81 } 82 if (chipset->series == cpuinfo_arm_chipset_series_hisilicon_kirin && chipset->model == 980) { 83 isa->dot = true; 84 } 85 break; 86 } 87 if (features & CPUINFO_ARM_LINUX_FEATURE_JSCVT) { 88 isa->jscvt = true; 89 } 90 if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM) { 91 isa->rdm = true; 92 } 93 if (features & CPUINFO_ARM_LINUX_FEATURE_JSCVT) { 94 isa->jscvt = true; 95 } 96 if (features & CPUINFO_ARM_LINUX_FEATURE_FCMA) { 97 isa->fcma = true; 98 } 99 } 100