• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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])7 void 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