1/*
2 SPDX-FileCopyrightText: 2021 Alexey Minnekhanov <alexeymin@postmarketos.org>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
6
7#include "cpuinfo_arm.h"
8
9// don't even build the following code for non-ARM platforms
10#ifdef BUILDING_FOR_ARM_TARGET
11
12namespace Solid
13{
14namespace Backends
15{
16namespace UDev
17{
18/**
19 * IDs list is based on code from lscpu-arm.c from util-linux project.
20 * You can also find them in Linux kernel source:
21 * https://elixir.bootlin.com/linux/latest/source/arch/arm64/include/asm/cputype.h
22 * https://elixir.bootlin.com/linux/latest/source/arch/arm/include/asm/cputype.h
23 * There is also maintained list at https://github.com/bp0/armids
24 **/
25
26// clang-format off
27static const struct ArmIdPart armParts[] = {
28 {0x810, "ARM810"},
29 {0x920, "ARM920"},
30 {0x922, "ARM922"},
31 {0x926, "ARM926"},
32 {0x940, "ARM940"},
33 {0x946, "ARM946"},
34 {0x966, "ARM966"},
35 {0xa20, "ARM1020"},
36 {0xa22, "ARM1022"},
37 {0xa26, "ARM1026"},
38 {0xb02, "ARM11 MPCore"},
39 {0xb36, "ARM1136"},
40 {0xb56, "ARM1156"},
41 {0xb76, "ARM1176"},
42 {0xc05, "Cortex-A5"},
43 {0xc07, "Cortex-A7"},
44 {0xc08, "Cortex-A8"},
45 {0xc09, "Cortex-A9"},
46 {0xc0d, "Cortex-A17"},
47 {0xc0e, "Cortex-A17"},
48 {0xc0f, "Cortex-A15"},
49 {0xc14, "Cortex-R4"},
50 {0xc15, "Cortex-R5"},
51 {0xc17, "Cortex-R7"},
52 {0xc18, "Cortex-R8"},
53 {0xc20, "Cortex-M0"},
54 {0xc21, "Cortex-M1"},
55 {0xc23, "Cortex-M3"},
56 {0xc24, "Cortex-M4"},
57 {0xc27, "Cortex-M7"},
58 {0xc60, "Cortex-M0+"},
59 {0xd01, "Cortex-A32"},
60 {0xd03, "Cortex-A53"},
61 {0xd04, "Cortex-A35"},
62 {0xd05, "Cortex-A55"},
63 {0xd06, "Cortex-A65"},
64 {0xd07, "Cortex-A57"},
65 {0xd08, "Cortex-A72"},
66 {0xd09, "Cortex-A73"},
67 {0xd0a, "Cortex-A75"},
68 {0xd0b, "Cortex-A76"},
69 {0xd0c, "Neoverse-N1"},
70 {0xd0d, "Cortex-A77"},
71 {0xd0e, "Cortex-A76AE"},
72 {0xd13, "Cortex-R52"},
73 {0xd20, "Cortex-M23"},
74 {0xd21, "Cortex-M33"},
75 {0xd40, "Neoverse-V1"},
76 {0xd41, "Cortex-A78"},
77 {0xd42, "Cortex-A78AE"},
78 {0xd44, "Cortex-X1"},
79 {0xd46, "Cortex-A510"},
80 {0xd47, "Cortex-A710"},
81 {0xd48, "Cortex-X2"},
82 {0xd49, "Neoverse-N2"},
83 {0xd4a, "Neoverse-E1"},
84 {0xd4b, "Cortex-A78C"},
85 {0xd4d, "Cortex-A715"},
86 {-1, "unknown"},
87};
88// clang-format on
89
90static const struct ArmIdPart brcmParts[] = {
91 {0x0f, "Brahma B15"},
92 {0x100, "Brahma B53"},
93 {0x516, "ThunderX2 (Vulcan)"},
94 {-1, "unknown"},
95};
96
97static const struct ArmIdPart decParts[] = {
98 {0xa10, "SA110"},
99 {0xa11, "SA1100"},
100 {-1, "unknown"},
101};
102
103static const struct ArmIdPart caviumParts[] = {
104 {0x0a0, "ThunderX"},
105 {0x0a1, "ThunderX 88XX"},
106 {0x0a2, "ThunderX 81XX"},
107 {0x0a3, "ThunderX 83XX"},
108 {0x0af, "ThunderX2 99xx"},
109 {-1, "unknown"},
110};
111
112static const struct ArmIdPart apmParts[] = {
113 {0x000, "X-Gene"},
114 {-1, "unknown"},
115};
116
117static const struct ArmIdPart qcomParts[] = {
118 {0x00f, "Scorpion"},
119 {0x02d, "Scorpion"},
120 {0x04d, "Krait"},
121 {0x06f, "Krait 400"},
122 {0x200, "Kryo"},
123 {0x201, "Kryo Silver"},
124 {0x205, "Kryo Gold"},
125 {0x211, "Kryo"},
126 {0x800, "Falkor V1/Kryo 2xx Gold"},
127 {0x801, "Kryo 2xx Silver"},
128 {0x802, "Kryo 3xx Gold"},
129 {0x803, "Kryo 3xx Silver"},
130 {0x804, "Kryo 4xx/5xx Gold"},
131 {0x805, "Kryo 4xx/5xx Silver"},
132 {0xc00, "Falkor"},
133 {0xc01, "Saphira"},
134 {-1, "unknown"},
135};
136
137static const struct ArmIdPart samsungParts[] = {
138 {0x001, "exynos-m1"},
139 {-1, "unknown"},
140};
141
142static const struct ArmIdPart nvidiaParts[] = {
143 {0x000, "Denver"},
144 {0x003, "Denver 2"},
145 {0x004, "Carmel"},
146 {-1, "unknown"},
147};
148
149static const struct ArmIdPart marvellParts[] = {
150 {0x131, "Feroceon 88FR131"},
151 {0x581, "PJ4/PJ4b"},
152 {0x584, "PJ4B-MP"},
153 {-1, "unknown"},
154};
155
156static const struct ArmIdPart faradayParts[] = {
157 {0x526, "FA526"},
158 {0x626, "FA626"},
159 {-1, "unknown"},
160};
161
162// clang-format off
163static const struct ArmIdPart intelParts[] = {
164 {0x200, "i80200"},
165 {0x210, "PXA250A"},
166 {0x212, "PXA210A"},
167 {0x242, "i80321-400"},
168 {0x243, "i80321-600"},
169 {0x290, "PXA250B/PXA26x"},
170 {0x292, "PXA210B"},
171 {0x2c2, "i80321-400-B0"},
172 {0x2c3, "i80321-600-B0"},
173 {0x2d0, "PXA250C/PXA255/PXA26x"},
174 {0x2d2, "PXA210C"},
175 {0x411, "PXA27x"},
176 {0x41c, "IPX425-533"},
177 {0x41d, "IPX425-400"},
178 {0x41f, "IPX425-266"},
179 {0x682, "PXA32x"},
180 {0x683, "PXA930/PXA935"},
181 {0x688, "PXA30x"},
182 {0x689, "PXA31x"},
183 {0xb11, "SA1110"},
184 {0xc12, "IPX1200"},
185 {-1, "unknown"},
186};
187// clang-format on
188
189static const struct ArmIdPart fujitsuParts[] = {
190 {0x001, "A64FX"},
191 {-1, "unknown"},
192};
193
194static const struct ArmIdPart hisiParts[] = {
195 {0xd01, "Kunpeng-920 (TSV110)"},
196 {-1, "unknown"},
197};
198
199static const struct ArmIdPart appleParts[] = {
200 {0x020, "Icestorm (A14)"},
201 {0x021, "Firestorm (A14)"},
202 {0x022, "Icestorm (M1)"},
203 {0x023, "Firestorm (M1)"},
204 {0x024, "Icestorm (M1 Pro)"},
205 {0x025, "Firestorm (M1 Pro)"},
206 {0x028, "Icestorm (M1 Max)"},
207 {0x029, "Firestorm (M1 Max)"},
208 {0x030, "Blizzard (A15)"},
209 {0x031, "Avalanche (A15)"},
210 {0x032, "Blizzard (M2)"},
211 {0x033, "Avalanche (M2)"},
212 {-1, "unknown"},
213};
214
215static const struct ArmIdPart unknownPart[] = {
216 {-1, "unknown"},
217};
218
219static const struct ArmCpuImplementer armHwImplementers[] = {
220 {0x41, armParts, "ARM"},
221 {0x42, brcmParts, "Broadcom"},
222 {0x43, caviumParts, "Cavium"},
223 {0x44, decParts, "DEC"},
224 {0x46, fujitsuParts, "FUJITSU"},
225 {0x48, hisiParts, "HiSilicon"},
226 {0x49, unknownPart, "Infineon"},
227 {0x4d, unknownPart, "Motorola/Freescale"},
228 {0x4e, nvidiaParts, "NVIDIA"},
229 {0x50, apmParts, "APM"},
230 {0x51, qcomParts, "Qualcomm"},
231 {0x53, samsungParts, "Samsung"},
232 {0x56, marvellParts, "Marvell"},
233 {0x61, appleParts, "Apple"},
234 {0x66, faradayParts, "Faraday"},
235 {0x69, intelParts, "Intel"},
236 {0xc0, unknownPart, "Ampere"},
237 {-1, unknownPart, "unknown"},
238};
239
240const ArmCpuImplementer *findArmCpuImplementer(int vendorId)
241{
242 const ArmCpuImplementer *ret = nullptr;
243 for (int i = 0; armHwImplementers[i].id != -1; i++) {
244 if (armHwImplementers[i].id == vendorId) {
245 ret = &armHwImplementers[i];
246 break;
247 }
248 }
249 return ret;
250}
251
252/*
253 * The CPU part number is meaningless without referring to the CPU
254 * implementer: implementers are free to define their own part numbers
255 * which are permitted to clash with other implementer part numbers.
256 */
257QString findArmCpuModel(int vendorId, int modelId)
258{
259 const ArmCpuImplementer *impl = findArmCpuImplementer(vendorId);
260 if (!impl) {
261 return QString();
262 }
263 for (int i = 0; impl->parts[i].id != -1; i++) {
264 if (impl->parts[i].id == modelId) {
265 return QString::fromUtf8(impl->name) + QLatin1Char(' ') + QString::fromUtf8(impl->parts[i].name);
266 }
267 }
268 return QString();
269}
270
271} // namespace UDev
272} // namespace Backends
273} // namespace Solid
274
275#endif // BUILDING_FOR_ARM_TARGET
276

source code of solid/src/solid/devices/backends/udev/cpuinfo_arm.cpp