1+ /*
2+ * Copyright (c) 2026 elementary LLC. (https://elementary.io)
3+ *
4+ * This program is free software; you can redistribute it and/or
5+ * modify it under the terms of the GNU General Public
6+ * License as published by the Free Software Foundation; either
7+ * version 3 of the License, or (at your option) any later version.
8+ *
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+ * General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU General Public
15+ * License along with this program; if not, write to the
16+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17+ * Boston, MA 02110-1301 USA
18+ */
19+
20+ public class Monitor.ARMPartDecoder {
21+ // Vala port of https://github.com/util-linux/util-linux/blob/2da5c904e18fdcffd2b252d641e6f76374c7b406/sys-utils/lscpu-arm.c
22+ struct ARMPart {
23+ int id;
24+ string name;
25+ }
26+
27+ struct ARMImplementer {
28+ int id;
29+ ARMPart [] parts;
30+ string name;
31+ }
32+
33+ const ARMPart ARM_PARTS [] = {
34+ { 0x810 , " ARM810" },
35+ { 0x920 , " ARM920" },
36+ { 0x922 , " ARM922" },
37+ { 0x926 , " ARM926" },
38+ { 0x940 , " ARM940" },
39+ { 0x946 , " ARM946" },
40+ { 0x966 , " ARM966" },
41+ { 0xa20 , " ARM1020" },
42+ { 0xa22 , " ARM1022" },
43+ { 0xa26 , " ARM1026" },
44+ { 0xb02 , " ARM11 MPCore" },
45+ { 0xb36 , " ARM1136" },
46+ { 0xb56 , " ARM1156" },
47+ { 0xb76 , " ARM1176" },
48+ { 0xc05 , " Cortex-A5" },
49+ { 0xc07 , " Cortex-A7" },
50+ { 0xc08 , " Cortex-A8" },
51+ { 0xc09 , " Cortex-A9" },
52+ { 0xc0d , " Cortex-A17" }, /* Originally A12 */
53+ { 0xc0f , " Cortex-A15" },
54+ { 0xc0e , " Cortex-A17" },
55+ { 0xc14 , " Cortex-R4" },
56+ { 0xc15 , " Cortex-R5" },
57+ { 0xc17 , " Cortex-R7" },
58+ { 0xc18 , " Cortex-R8" },
59+ { 0xc20 , " Cortex-M0" },
60+ { 0xc21 , " Cortex-M1" },
61+ { 0xc23 , " Cortex-M3" },
62+ { 0xc24 , " Cortex-M4" },
63+ { 0xc27 , " Cortex-M7" },
64+ { 0xc60 , " Cortex-M0+" },
65+ { 0xd01 , " Cortex-A32" },
66+ { 0xd02 , " Cortex-A34" },
67+ { 0xd03 , " Cortex-A53" },
68+ { 0xd04 , " Cortex-A35" },
69+ { 0xd05 , " Cortex-A55" },
70+ { 0xd06 , " Cortex-A65" },
71+ { 0xd07 , " Cortex-A57" },
72+ { 0xd08 , " Cortex-A72" },
73+ { 0xd09 , " Cortex-A73" },
74+ { 0xd0a , " Cortex-A75" },
75+ { 0xd0b , " Cortex-A76" },
76+ { 0xd0c , " Neoverse-N1" },
77+ { 0xd0d , " Cortex-A77" },
78+ { 0xd0e , " Cortex-A76AE" },
79+ { 0xd13 , " Cortex-R52" },
80+ { 0xd15 , " Cortex-R82" },
81+ { 0xd16 , " Cortex-R52+" },
82+ { 0xd20 , " Cortex-M23" },
83+ { 0xd21 , " Cortex-M33" },
84+ { 0xd22 , " Cortex-M55" },
85+ { 0xd23 , " Cortex-M85" },
86+ { 0xd40 , " Neoverse-V1" },
87+ { 0xd41 , " Cortex-A78" },
88+ { 0xd42 , " Cortex-A78AE" },
89+ { 0xd43 , " Cortex-A65AE" },
90+ { 0xd44 , " Cortex-X1" },
91+ { 0xd46 , " Cortex-A510" },
92+ { 0xd47 , " Cortex-A710" },
93+ { 0xd48 , " Cortex-X2" },
94+ { 0xd49 , " Neoverse-N2" },
95+ { 0xd4a , " Neoverse-E1" },
96+ { 0xd4b , " Cortex-A78C" },
97+ { 0xd4c , " Cortex-X1C" },
98+ { 0xd4d , " Cortex-A715" },
99+ { 0xd4e , " Cortex-X3" },
100+ { 0xd4f , " Neoverse-V2" },
101+ { 0xd80 , " Cortex-A520" },
102+ { 0xd81 , " Cortex-A720" },
103+ { 0xd82 , " Cortex-X4" },
104+ };
105+
106+ const ARMPart BROADCOM_PARTS [] = {
107+ { 0x0f , " Brahma-B15" },
108+ { 0x100 , " Brahma-B53" },
109+ { 0x516 , " ThunderX2" },
110+ };
111+
112+ const ARMPart DEC_PARTS [] = {
113+ { 0xa10 , " SA110" },
114+ { 0xa11 , " SA1100" },
115+ };
116+
117+ const ARMPart CAVIUM_PARTS [] = {
118+ { 0x0a0 , " ThunderX" },
119+ { 0x0a1 , " ThunderX-88XX" },
120+ { 0x0a2 , " ThunderX-81XX" },
121+ { 0x0a3 , " ThunderX-83XX" },
122+ { 0x0af , " ThunderX2-99xx" },
123+ { 0x0b0 , " OcteonTX2" },
124+ { 0x0b1 , " OcteonTX2-98XX" },
125+ { 0x0b2 , " OcteonTX2-96XX" },
126+ { 0x0b3 , " OcteonTX2-95XX" },
127+ { 0x0b4 , " OcteonTX2-95XXN" },
128+ { 0x0b5 , " OcteonTX2-95XXMM" },
129+ { 0x0b6 , " OcteonTX2-95XXO" },
130+ { 0x0b8 , " ThunderX3-T110" },
131+ };
132+
133+ const ARMPart APM_PARTS [] = {
134+ { 0x000 , " X-Gene" },
135+ };
136+
137+ const ARMPart QUALCOMM_PARTS [] = {
138+ { 0x00f , " Scorpion" },
139+ { 0x02d , " Scorpion" },
140+ { 0x04d , " Krait" },
141+ { 0x06f , " Krait" },
142+ { 0x201 , " Kryo" },
143+ { 0x205 , " Kryo" },
144+ { 0x211 , " Kryo" },
145+ { 0x800 , " Falkor-V1/Kryo" },
146+ { 0x801 , " Kryo-V2" },
147+ { 0x802 , " Kryo-3XX-Gold" },
148+ { 0x803 , " Kryo-3XX-Silver" },
149+ { 0x804 , " Kryo-4XX-Gold" },
150+ { 0x805 , " Kryo-4XX-Silver" },
151+ { 0xc00 , " Falkor" },
152+ { 0xc01 , " Saphira" },
153+ };
154+
155+ const ARMPart SAMSUNG_PARTS [] = {
156+ { 0x001 , " exynos-m1" },
157+ { 0x002 , " exynos-m3" },
158+ { 0x003 , " exynos-m4" },
159+ { 0x004 , " exynos-m5" },
160+ };
161+
162+ const ARMPart NVIDIA_PARTS [] = {
163+ { 0x000 , " Denver" },
164+ { 0x003 , " Denver 2" },
165+ { 0x004 , " Carmel" },
166+ };
167+
168+ const ARMPart MARVELL_PARTS [] = {
169+ { 0x131 , " Feroceon-88FR131" },
170+ { 0x581 , " PJ4/PJ4b" },
171+ { 0x584 , " PJ4B-MP" },
172+ };
173+
174+ const ARMPart APPLE_PARTS [] = {
175+ { 0x000 , " Swift" },
176+ { 0x001 , " Cyclone" },
177+ { 0x002 , " Typhoon" },
178+ { 0x003 , " Typhoon/Capri" },
179+ { 0x004 , " Twister" },
180+ { 0x005 , " Twister/Elba/Malta" },
181+ { 0x006 , " Hurricane" },
182+ { 0x007 , " Hurricane/Myst" },
183+ { 0x008 , " Monsoon" },
184+ { 0x009 , " Mistral" },
185+ { 0x00b , " Vortex" },
186+ { 0x00c , " Tempest" },
187+ { 0x00f , " Tempest-M9" },
188+ { 0x010 , " Vortex/Aruba" },
189+ { 0x011 , " Tempest/Aruba" },
190+ { 0x012 , " Lightning" },
191+ { 0x013 , " Thunder" },
192+ { 0x020 , " Icestorm-A14" },
193+ { 0x021 , " Firestorm-A14" },
194+ { 0x022 , " Icestorm-M1" },
195+ { 0x023 , " Firestorm-M1" },
196+ { 0x024 , " Icestorm-M1-Pro" },
197+ { 0x025 , " Firestorm-M1-Pro" },
198+ { 0x026 , " Thunder-M10" },
199+ { 0x028 , " Icestorm-M1-Max" },
200+ { 0x029 , " Firestorm-M1-Max" },
201+ { 0x030 , " Blizzard-A15" },
202+ { 0x031 , " Avalanche-A15" },
203+ { 0x032 , " Blizzard-M2" },
204+ { 0x033 , " Avalanche-M2" },
205+ { 0x034 , " Blizzard-M2-Pro" },
206+ { 0x035 , " Avalanche-M2-Pro" },
207+ { 0x036 , " Sawtooth-A16" },
208+ { 0x037 , " Everest-A16" },
209+ { 0x038 , " Blizzard-M2-Max" },
210+ { 0x039 , " Avalanche-M2-Max" },
211+ };
212+
213+ const ARMPart FARADAY_PARTS [] = {
214+ { 0x526 , " FA526" },
215+ { 0x626 , " FA626" },
216+ };
217+
218+ const ARMPart INTEL_PARTS [] = {
219+ { 0x200 , " i80200" },
220+ { 0x210 , " PXA250A" },
221+ { 0x212 , " PXA210A" },
222+ { 0x242 , " i80321-400" },
223+ { 0x243 , " i80321-600" },
224+ { 0x290 , " PXA250B/PXA26x" },
225+ { 0x292 , " PXA210B" },
226+ { 0x2c2 , " i80321-400-B0" },
227+ { 0x2c3 , " i80321-600-B0" },
228+ { 0x2d0 , " PXA250C/PXA255/PXA26x" },
229+ { 0x2d2 , " PXA210C" },
230+ { 0x411 , " PXA27x" },
231+ { 0x41c , " IPX425-533" },
232+ { 0x41d , " IPX425-400" },
233+ { 0x41f , " IPX425-266" },
234+ { 0x682 , " PXA32x" },
235+ { 0x683 , " PXA930/PXA935" },
236+ { 0x688 , " PXA30x" },
237+ { 0x689 , " PXA31x" },
238+ { 0xb11 , " SA1110" },
239+ { 0xc12 , " IPX1200" },
240+ };
241+
242+ const ARMPart FUJITSU_PARTS [] = {
243+ { 0x001 , " A64FX" },
244+ };
245+
246+ const ARMPart HISILICON_PARTS [] = {
247+ { 0xd01 , " Kunpeng-920" }, /* aka tsv110 */
248+ { 0xd40 , " Cortex-A76" }, /* HiSilicon uses this ID though advertises A76 */
249+ };
250+
251+ const ARMPart AMPERE_PARTS [] = {
252+ { 0xac3 , " Ampere-1" },
253+ { 0xac4 , " Ampere-1a" },
254+ };
255+
256+ const ARMPart PHYTIUM_PARTS [] = {
257+ { 0x303 , " FTC310" },
258+ { 0x660 , " FTC660" },
259+ { 0x661 , " FTC661" },
260+ { 0x662 , " FTC662" },
261+ { 0x663 , " FTC663" },
262+ { 0x664 , " FTC664" },
263+ { 0x862 , " FTC862" },
264+ };
265+
266+ const ARMImplementer ARM_IMPLEMENTERS [] = {
267+ { 0x41 , ARM_PARTS , " ARM" },
268+ { 0x42 , BROADCOM_PARTS , " Broadcom" },
269+ { 0x43 , CAVIUM_PARTS , " Cavium" },
270+ { 0x44 , DEC_PARTS , " DEC" },
271+ { 0x46 , FUJITSU_PARTS , " FUJITSU" },
272+ { 0x48 , HISILICON_PARTS , " HiSilicon" },
273+ { 0x4e , NVIDIA_PARTS , " NVIDIA" },
274+ { 0x50 , APM_PARTS , " APM" },
275+ { 0x51 , QUALCOMM_PARTS , " Qualcomm" },
276+ { 0x53 , SAMSUNG_PARTS , " Samsung" },
277+ { 0x56 , MARVELL_PARTS , " Marvell" },
278+ { 0x61 , APPLE_PARTS , " Apple" },
279+ { 0x66 , FARADAY_PARTS , " Faraday" },
280+ { 0x69 , INTEL_PARTS , " Intel" },
281+ { 0x70 , PHYTIUM_PARTS , " Phytium" },
282+ { 0xc0 , AMPERE_PARTS , " Ampere" },
283+ };
284+
285+ public static string ? decode_arm_model (uint ? cpu_implementer , uint ? cpu_part ) {
286+
287+ string ? result = null ;
288+
289+ if (cpu_implementer == null || cpu_part == null ) {
290+ return result;
291+ }
292+
293+ if (cpu_implementer == 0 || cpu_part == 0 ) {
294+ return result;
295+ }
296+
297+ foreach (var implementer in ARM_IMPLEMENTERS ) {
298+ if (cpu_implementer == implementer. id) {
299+ result = implementer. name + " " ;
300+ foreach (var part in implementer. parts) {
301+ if (cpu_part == part. id) {
302+ result + = part. name;
303+ }
304+ }
305+ }
306+ }
307+
308+ return result;
309+ }
310+ }
0 commit comments