Added "-p" to make parent directories as needed.
[AROS.git] / arch / arm-all / processor / processor_util.c
blobd09a681ee28a5acd68fad6870304597f1aa5a05e
1 /*
2 Copyright © 2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 0
7 #include <aros/debug.h>
9 #include <resources/processor.h>
10 #include <string.h>
12 #include "processor_arch_intern.h"
14 #define DPROBE(a)
16 static const char *ARMCPUVendors[] =
18 "Unknown",
19 "ARM Ltd.",
20 "DEC",
21 "Motorola",
22 "Texas Instruments",
23 "Qualcomm",
24 "Marvell",
25 "Intel",
26 NULL
29 static const char *ARMCPUFamilies[] =
31 "v3",
32 "v4",
33 "v4T",
34 "v5",
35 "v5T",
36 "v5TE",
37 "v5TEJ",
38 "v6",
39 "v7",
40 NULL
43 VOID ReadProcessorInformation(struct ARMProcessorInformation * info)
45 register unsigned int scp_reg, cache_reg;
46 APTR ssp;
48 D(bug("[processor.ARM] %s()\n", __PRETTY_FUNCTION__));
50 D(bug("[processor.ARM] %s: Probing CPU ..\n", __PRETTY_FUNCTION__));
52 ssp = SuperState();
54 DPROBE(bug("[processor.ARM] %s: Checking Main ID Register..\n", __PRETTY_FUNCTION__));
55 asm volatile("mrc p15, 0, %[scp_reg], c0, c0, 0" : [scp_reg] "=r" (scp_reg) );
57 info->VendorID = (scp_reg >> 24) & 0x7F;
59 if ((scp_reg & 0x8F000) == 0)
60 info->Family = CPUFAMILY_UNKNOWN;
61 else if ((scp_reg & 0x8F000) == 0x7000)
62 info->Family = (scp_reg & (1 << 23)) ? CPUFAMILY_ARM_4T : CPUFAMILY_ARM_3;
63 else if ((scp_reg & 0x80000) == 0)
65 info->Family = CPUFAMILY_ARM_3;
66 if ((scp_reg >> 16) & 7)
67 info->Family += ((scp_reg >> 16) & 7);
69 else if ((scp_reg & 0xF0000) == 0xF0000)
71 info->Family = CPUFAMILY_ARM_6;
73 DPROBE(bug("[processor.ARM] %s: Checking Memory Model Feature Register..\n", __PRETTY_FUNCTION__));
74 asm volatile("mrc p15, 0, %[scp_reg], c0, c1, 4" : [scp_reg] "=r" (scp_reg) );
76 if (((((scp_reg >> 4) & 0xF) >= 1) && ((scp_reg & 0xF) >= 3)) || (((scp_reg >> 4) & 0xF) >= 3))
77 info->Family = CPUFAMILY_ARM_7;
79 DPROBE(bug("[processor.ARM] %s: - %02d:%02d\n", __PRETTY_FUNCTION__, (scp_reg >> 4) & 0xF, scp_reg & 0xF));
81 else
82 info->Family = CPUFAMILY_UNKNOWN;
84 DPROBE(bug("[processor.ARM] %s: Checking Feature Register #1 ..\n", __PRETTY_FUNCTION__));
85 asm volatile("mrc p15, 0, %[scp_reg], c0, c1, 1" : [scp_reg] "=r" (scp_reg) );
87 if (scp_reg & (0xF << 4))
88 info->Features1 |= FEATF_SECURE;
90 DPROBE(bug("[processor.ARM] %s: Checking Feature Register #0 ..\n", __PRETTY_FUNCTION__));
91 asm volatile("mrc p15, 0, %[scp_reg], c0, c1, 1" : [scp_reg] "=r" (scp_reg) );
93 DPROBE(bug("[processor.ARM] %s: Checking Co-Processor Access Control Register..\n", __PRETTY_FUNCTION__));
94 asm volatile("mrc p15,0,%[scp_reg], c1, c0, 2\n" : [scp_reg] "=r" (scp_reg));
95 if (scp_reg & ((3 << 20)|(3 << 22)))
96 info->Features1 |= FEATF_FPU_VFP;
98 if (info->Features1 & FEATF_FPU_VFP)
100 DPROBE(bug("[processor.ARM] %s: Checking Floating Point System ID Register..\n", __PRETTY_FUNCTION__));
101 asm volatile("fmrx %[scp_reg], FPSID\n" : [scp_reg] "=r" (scp_reg));
102 if (((scp_reg >> 16) & 0xF) >= 2)
104 info->Features1 |= FEATF_FPU_VFP3;
106 else
109 info->Features1 |= FEATF_FPU_VFP2;
113 DPROBE(bug("[processor.ARM] %s: Checking Media and VFP Feature Register #0..\n", __PRETTY_FUNCTION__));
114 asm volatile("fmrx %[scp_reg], MVFR0\n" : [scp_reg] "=r" (scp_reg));
115 if ((scp_reg & 0xF) == 1)
117 info->Features1 |= FEATF_FPU_VFP3_16;
120 DPROBE(bug("[processor.ARM] %s: Checking Media and VFP Feature Register #1..\n", __PRETTY_FUNCTION__));
121 asm volatile("fmrx %[scp_reg], MVFR1\n" : [scp_reg] "=r" (scp_reg));
122 if ((scp_reg & 0x000FFF00) == 0x00011100)
124 info->Features1 |= FEATF_NEON;
126 if ((scp_reg & 0xF0000000) == 0x10000000)
128 info->Features1 |= FEATF_FPU_VFP4;
132 DPROBE(bug("[processor.ARM] %s: Checking Instruction Set Attributes Register #3..\n", __PRETTY_FUNCTION__));
133 asm volatile("mrc p15,0,%[scp_reg], c0, c2, 3\n" : [scp_reg] "=r" (scp_reg));
134 if (((scp_reg >> 28) & 0xF) > 0)
135 info->Features1 |= FEATF_THUMBEX;
137 DPROBE(bug("[processor.ARM] %s: Checking System Control Register..\n", __PRETTY_FUNCTION__));
138 asm volatile("mrc p15, 0, %[scp_reg], c1, c0, 0" : [scp_reg] "=r" (scp_reg) );
140 if (scp_reg & (1 << 11))
141 info->Features1 |= FEATF_BRANCHP;
143 if (scp_reg & (1 << 31))
144 info->Features1 |= FEATF_BIGEND;
146 DPROBE(bug("[processor.ARM] %s: Checking Cache Type Register..\n", __PRETTY_FUNCTION__));
147 asm volatile("mrc p15, 0, %[cache_reg], c0, c0, 1" : [cache_reg] "=r" (cache_reg) );
149 if (scp_reg & (1 << 2))
151 switch((cache_reg >> 18) & 0xF) {
152 case 3:
153 info->L1DataCacheSize = 4;
154 break;
155 case 4:
156 info->L1DataCacheSize = 8;
157 break;
158 case 5:
159 info->L1DataCacheSize = 16;
160 break;
161 case 6:
162 info->L1DataCacheSize = 32;
163 break;
164 case 7:
165 info->L1DataCacheSize = 64;
166 break;
167 case 8:
168 info->L1DataCacheSize = 128;
169 break;
170 case 9:
171 info->L1DataCacheSize = 256;
172 break;
173 case 10:
174 info->L1DataCacheSize = 512;
175 break;
176 case 11:
177 info->L1DataCacheSize = 1024;
178 break;
179 default:
180 info->L1DataCacheSize = 0;
181 break;
184 if (scp_reg & (1 << 12))
186 switch((cache_reg >> 6) & 0xF) {
187 case 3:
188 info->L1InstructionCacheSize = 4;
189 break;
190 case 4:
191 info->L1InstructionCacheSize = 8;
192 break;
193 case 5:
194 info->L1InstructionCacheSize = 16;
195 break;
196 case 6:
197 info->L1InstructionCacheSize = 32;
198 break;
199 case 7:
200 info->L1InstructionCacheSize = 64;
201 break;
202 case 8:
203 info->L1InstructionCacheSize = 128;
204 break;
205 case 9:
206 info->L1InstructionCacheSize = 256;
207 break;
208 case 10:
209 info->L1InstructionCacheSize = 512;
210 break;
211 case 11:
212 info->L1InstructionCacheSize = 1024;
213 break;
214 default:
215 info->L1InstructionCacheSize = 0;
216 break;
219 D(bug("[processor.ARM] %s: .. Done\n", __PRETTY_FUNCTION__));
221 UserState(ssp);
223 switch (info->VendorID) {
224 case 'A':
225 info->Vendor = ARMCPUVendors[1];
226 break;
227 case 'D':
228 info->Vendor = ARMCPUVendors[2];
229 break;
230 case 'M':
231 info->Vendor = ARMCPUVendors[3];
232 break;
233 case 'T':
234 info->Vendor = ARMCPUVendors[4];
235 break;
236 case 'Q':
237 info->Vendor = ARMCPUVendors[5];
238 break;
239 case 'V':
240 info->Vendor = ARMCPUVendors[6];
241 break;
242 case 'i':
243 info->Vendor = ARMCPUVendors[7];
244 break;
245 default:
246 info->Vendor = ARMCPUVendors[0];
247 info->Vendor = 0;
248 break;
251 if (info->Family >= CPUFAMILY_ARM_3)
252 info->FamilyString = ARMCPUFamilies[info->Family - CPUFAMILY_ARM_3];
254 D(bug("[processor.ARM] %s: CPU Details Read\n", __PRETTY_FUNCTION__));