2 Copyright © 2013, The AROS Development Team. All rights reserved.
7 #include <aros/debug.h>
9 #include <resources/processor.h>
12 #include "processor_arch_intern.h"
16 static const char *ARMCPUVendors
[] =
29 static const char *ARMCPUFamilies
[] =
43 VOID
ReadProcessorInformation(struct ARMProcessorInformation
* info
)
45 register unsigned int scp_reg
, cache_reg
;
48 D(bug("[processor.ARM] %s()\n", __PRETTY_FUNCTION__
));
50 D(bug("[processor.ARM] %s: Probing CPU ..\n", __PRETTY_FUNCTION__
));
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 if ((scp_reg
& 0xFFF0) == 0xc070)
74 info
->Family
= CPUFAMILY_ARM_7
;
76 DPROBE(bug("[processor.ARM] %s: Checking Memory Model Feature Register..\n", __PRETTY_FUNCTION__
));
77 asm volatile("mrc p15, 0, %[scp_reg], c0, c1, 4" : [scp_reg
] "=r" (scp_reg
) );
79 DPROBE(bug("[processor.ARM] %s: - %02d:%02d\n", __PRETTY_FUNCTION__
, (scp_reg
>> 4) & 0xF, scp_reg
& 0xF));
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
;
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) {
153 info
->L1DataCacheSize
= 4;
156 info
->L1DataCacheSize
= 8;
159 info
->L1DataCacheSize
= 16;
162 info
->L1DataCacheSize
= 32;
165 info
->L1DataCacheSize
= 64;
168 info
->L1DataCacheSize
= 128;
171 info
->L1DataCacheSize
= 256;
174 info
->L1DataCacheSize
= 512;
177 info
->L1DataCacheSize
= 1024;
180 info
->L1DataCacheSize
= 0;
184 if (scp_reg
& (1 << 12))
186 switch((cache_reg
>> 6) & 0xF) {
188 info
->L1InstructionCacheSize
= 4;
191 info
->L1InstructionCacheSize
= 8;
194 info
->L1InstructionCacheSize
= 16;
197 info
->L1InstructionCacheSize
= 32;
200 info
->L1InstructionCacheSize
= 64;
203 info
->L1InstructionCacheSize
= 128;
206 info
->L1InstructionCacheSize
= 256;
209 info
->L1InstructionCacheSize
= 512;
212 info
->L1InstructionCacheSize
= 1024;
215 info
->L1InstructionCacheSize
= 0;
219 D(bug("[processor.ARM] %s: .. Done\n", __PRETTY_FUNCTION__
));
223 switch (info
->VendorID
) {
225 info
->Vendor
= ARMCPUVendors
[1];
228 info
->Vendor
= ARMCPUVendors
[2];
231 info
->Vendor
= ARMCPUVendors
[3];
234 info
->Vendor
= ARMCPUVendors
[4];
237 info
->Vendor
= ARMCPUVendors
[5];
240 info
->Vendor
= ARMCPUVendors
[6];
243 info
->Vendor
= ARMCPUVendors
[7];
246 info
->Vendor
= ARMCPUVendors
[0];
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__
));