SayoriOS 0.3.3

cpuinfo.c
См. документацию.
1
10 #include "common.h"
11 #include "lib/string.h"
12 #include "portability.h"
13 #include <io/ports.h>
14 #include <sys/cpuinfo.h>
15
16 char brandAllName[128] = {0};
17
18
19 #define tty_printf(M, ...)
20
21 #define INTEL_MAGIC 0x756e6547
22 #define AMD_MAGIC 0x68747541
23 #define VMWARE_HYPERVISOR_MAGIC 0x564D5868
24 #define VMWARE_HYPERVISOR_PORT 0x5658
25 #define VMWARE_PORT_CMD_GETVERSION 10
26
27
28 #define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \
29 __asm__("inl (%%dx)" : \
30 "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \
31 "0"(VMWARE_HYPERVISOR_MAGIC), \
32 "1"(VMWARE_PORT_CMD_##cmd), \
33 "2"(VMWARE_HYPERVISOR_PORT), "3"(UINT_MAX) : \
34 "memory");
35
45 int detect_cpu(bool silent) {
46 int type;
47 uint32_t ebx, unused;
48 cpuid(0, unused, ebx, unused, unused);
49 switch (ebx) {
50 case INTEL_MAGIC: /* Intel Magic Code */
51 //strcat(brandAllName,"Intel ");
52 do_intel(silent);
53 type = 1;
54 break;
55 case AMD_MAGIC: /* AMD Magic Code */
56 //strcat(brandAllName,"AMD ");
57 do_amd(silent);
58 type = 2;
59 break;
60 case VMWARE_HYPERVISOR_MAGIC: /* VMWARE_HW_MAGIC */
61 memset(brandAllName, 0, 128);
62 strcat(brandAllName, "VMWARE_HYPERVISOR_MAGIC");
63 type = 3;
64 break;
65 default:
66 strcat(brandAllName,"Unknown x86");
67 type = 0;
68 //qemu_log("Unknown x86 CPU Detected\n");
69 break;
70 }
71 qemu_log("[CPU] Detect: %s",brandAllName);
72 return type;
73 }
74
80 char* getNameBrand(){
81 return brandAllName;
82 }
83
84 char *Intel[] = {
85 "Brand ID Not Supported.",
86 "Intel(R) Celeron(R) processor",
87 "Intel(R) Pentium(R) III processor",
88 "Intel(R) Pentium(R) III Xeon(R) processor",
89 "Intel(R) Pentium(R) III processor",
90 "Reserved",
91 "Mobile Intel(R) Pentium(R) III processor-M",
92 "Mobile Intel(R) Celeron(R) processor",
93 "Intel(R) Pentium(R) 4 processor",
94 "Intel(R) Pentium(R) 4 processor",
95 "Intel(R) Celeron(R) processor",
96 "Intel(R) Xeon(R) Processor",
97 "Intel(R) Xeon(R) processor MP",
98 "Reserved",
99 "Mobile Intel(R) Pentium(R) 4 processor-M",
100 "Mobile Intel(R) Pentium(R) Celeron(R) processor",
101 "Reserved",
102 "Mobile Genuine Intel(R) processor",
103 "Intel(R) Celeron(R) M processor",
104 "Mobile Intel(R) Celeron(R) processor",
105 "Intel(R) Celeron(R) processor",
106 "Mobile Geniune Intel(R) processor",
107 "Intel(R) Pentium(R) M processor",
108 "Mobile Intel(R) Celeron(R) processor"
109 };
110
116 char *Intel_Other[] = {
117 "Reserved",
118 "Reserved",
119 "Reserved",
120 "Intel(R) Celeron(R) processor",
121 "Reserved",
122 "Reserved",
123 "Reserved",
124 "Reserved",
125 "Reserved",
126 "Reserved",
127 "Reserved",
128 "Intel(R) Xeon(R) processor MP",
129 "Reserved",
130 "Reserved",
131 "Intel(R) Xeon(R) processor",
132 "Reserved",
133 "Reserved",
134 "Reserved",
135 "Reserved",
136 "Reserved",
137 "Reserved",
138 "Reserved",
139 "Reserved",
140 "Reserved"
141 };
142
152 int do_intel(bool silent) {
153 if (silent == false){
154 qemu_log("Detected Intel CPU.\nIntel-specific features:\n");
155 }
156
157 // uint32_t dtc1, dtc2, dtc3, dtc4, dtc5;
158 uint32_t eax, ebx, max_eax, signature, unused;
159 uint32_t model, family, type, brand;//, stepping, reserved;
160 // uint32_t extended_family;
161 cpuid(1, eax, ebx, unused, unused);
162 model = (eax >> 4) & 0xf;
163 family = (eax >> 8) & 0xf;
164 type = (eax >> 12) & 0x3;
165 brand = ebx & 0xff;
166 // stepping = eax & 0xf;
167 // reserved = eax >> 14;
168 signature = eax;
169 if (silent == 0){
170 qemu_log("Type %d - ", type);
171 switch(type) {
172 case 0:
173 qemu_log("Original OEM");
174 break;
175 case 1:
176 qemu_log("Overdrive");
177 break;
178 case 2:
179 qemu_log("Dual-capable");
180 break;
181 case 3:
182 qemu_log("Reserved");
183 break;
184 default:
185 qemu_log("Unknown");
186 }
187 qemu_log("Family %d - ", family);
188 switch(family) {
189 case 3:
190 qemu_log("i386");
191 break;
192 case 4:
193 qemu_log("i486");
194 break;
195 case 5:
196 qemu_log("Pentium");
197 break;
198 case 6:
199 qemu_log("Pentium Pro");
200 break;
201 case 15:
202 qemu_log("Pentium 4");
203 default:
204 qemu_log("Unknown");
205 }
206 if (family == 15) {
207 // extended_family = (eax >> 20) & 0xff;
208 qemu_log("Extended family %d\n", (eax >> 20) & 0xff);
209 }
210 qemu_log("Model %d - ", model);
211
212 switch (family) {
213 case 3:
214 break;
215 case 4:
216 switch (model) {
217 case 0:
218 case 1:
219 qemu_log("DX");
220 break;
221 case 2:
222 qemu_log("SX");
223 break;
224 case 3:
225 qemu_log("487/DX2");
226 break;
227 case 4:
228 qemu_log("SL");
229 break;
230 case 5:
231 qemu_log("SX2");
232 break;
233 case 7:
234 qemu_log("Write-back enhanced DX2");
235 break;
236 case 8:
237 qemu_log("DX4");
238 break;
239 default:
240 break;
241 }
242 break;
243 case 5:
244 switch (model) {
245 case 1:
246 qemu_log("60/66");
247 break;
248 case 2:
249 qemu_log("75-200");
250 break;
251 case 3:
252 qemu_log("for 486 system");
253 break;
254 case 4:
255 qemu_log("MMX");
256 break;
257 default:
258 break;
259 }
260 break;
261 case 6:
262 switch (model) {
263 case 1:
264 qemu_log("Pentium Pro");
265 break;
266 case 3:
267 qemu_log("Pentium II Model 3");
268 break;
269 case 5:
270 qemu_log("Pentium II Model 5/Xeon/Celeron");
271 break;
272 case 6:
273 qemu_log("Celeron");
274 break;
275 case 7:
276 qemu_log("Pentium III/Pentium III Xeon - external L2 cache");
277 break;
278 case 8:
279 qemu_log("Pentium III/Pentium III Xeon - internal L2 cache");
280 break;
281 default:
282 break;
283 }
284 break;
285 default:
286 break;
287 }
288 }
289 cpuid(0x80000000, max_eax, unused, unused, unused);
290
291 /* Quok said: If the max extended eax value is high enough to support the processor brand string
292 (values 0x80000002 to 0x80000004), then we'll use that information to return the brand information.
293 Otherwise, we'll refer back to the brand tables above for backwards compatibility with older processors.
294 According to the Sept. 2006 Intel Arch Software Developer's Guide, if extended eax values are supported,
295 then all 3 values for the processor brand string are supported, but we'll test just to make sure and be safe. */
296
297 if (max_eax >= 0x80000004) {
298 unsigned int a, b, c, d;
299 int inx = 0, aa = 0;
300 memset(brandAllName,0,128);
301 for (int i = 0x80000002; i <= 0x80000004; ++i) {
302 cpuid(i, a, b, c, d);
303 // Конкатенация информации о модели в processorModel
304 for (aa = 0; aa < 4; aa++){
305 char* delta = (char*)&a;
306 brandAllName[inx] = delta[aa];
307 inx++;
308 }
309 for (aa = 0; aa < 4; aa++){
310 char* delta = (char*)&b;
311 brandAllName[inx] = delta[aa];
312 inx++;
313 }
314 for (aa = 0; aa < 4; aa++){
315 char* delta = (char*)&c;
316 brandAllName[inx] = delta[aa];
317 inx++;
318 }
319 for (aa = 0; aa < 4; aa++){
320 char* delta = (char*)&d;
321 brandAllName[inx] = delta[aa];
322 inx++;
323 }
324 //qemu_log("[%s] [%s] [%s] [%s]", &a, &b, &c, &d);
325 }
326
327 //qemu_log("%s", brandAllName);
328 } else if (brand > 0 && silent == 0) {
329 qemu_log("Brand %d - ", brand);
330 if (brand < 0x18) {
331 if (signature == 0x000006B1 || signature == 0x00000F13) {
332 qemu_log("%s\n", Intel_Other[brand]);
333 } else {
334 qemu_log("%s\n", Intel[brand]);
335 }
336 } else {
337 qemu_log("Reserved\n");
338 }
339 } else {
340 qemu_log("Other INTEL CPU\n");
341 }
342 if (silent == 0){
343 //qemu_log("Stepping: %d Reserved: %d\n", stepping, reserved);
344 }
345 return 0;
346 }
347
357 int do_amd(bool silent) {
358 if (silent == 0){
359 qemu_log("Detected AMD CPU. \nAMD-specific features:\n");
360 }
361
362 uint32_t extended, eax, ebx, ecx, edx, unused;
363 uint32_t family, model;//, stepping, reserved;
364 cpuid(1, eax, unused, unused, unused);
365
366 model = (eax >> 4) & 0xf;
367 family = (eax >> 8) & 0xf;
368 // stepping = eax & 0xf;
369 // reserved = eax >> 12;
370 if (silent == 0){
371 qemu_log("Family: %d Model: %d [", family, model);
372 switch (family) {
373 case 4:
374 qemu_log("486 Model %d", model);
375 break;
376 case 5:
377 switch (model) {
378 case 0:
379 case 1:
380 case 2:
381 case 3:
382 case 6:
383 case 7:
384 qemu_log("K6 Model %d", model);
385 break;
386 case 8:
387 qemu_log("K6-2 Model 8");
388 break;
389 case 9:
390 qemu_log("K6-III Model 9");
391 break;
392 default:
393 qemu_log("K5/K6 Model %d", model);
394 break;
395 }
396 break;
397 case 6:
398 switch (model) {
399 case 1:
400 case 2:
401 case 4:
402 qemu_log("Athlon Model %d", model);
403 break;
404 case 3:
405 qemu_log("Duron Model 3");
406 break;
407 case 6:
408 qemu_log("Athlon MP/Mobile Athlon Model 6");
409 break;
410 case 7:
411 qemu_log("Mobile Duron Model 7");
412 break;
413 default:
414 qemu_log("Duron/Athlon Model %d", model);
415 break;
416 }
417 break;
418
419 default:
420 qemu_log("Unknown");
421 break;
422 }
423
424 qemu_log("]\n");
425 }
426 cpuid(0x80000000, extended, unused, unused, unused);
427 if (extended == 0) {
428 return 0;
429 }
430 if (extended >= 0x80000002) {
431 unsigned int j;
432 if (silent == 0){
433 qemu_log("Detected Processor Name: ");
434 }
435 for (j = 0x80000002; j <= 0x80000004; j++) {
436 cpuid(j, eax, ebx, ecx, edx);
437 if (silent == 0){
438
439 // qemu_log(cpuinfo_printregs(eax, ebx, ecx, edx));
440 memset(brandAllName,0,128);
441 }
442 }
443 if (silent == 0){
444 qemu_log("\n");
445 }
446 }
447 if (extended >= 0x80000007) {
448 cpuid(0x80000007, unused, unused, unused, edx);
449 if ((edx & 1) && silent == 0) {
450 qemu_log("Temperature Sensing Diode Detected!\n");
451 }
452 }
453 if (silent == 0){
454 //qemu_log("Stepping: %d Reserved: %d\n", stepping, reserved);
455 }
456 return 0;
457 }
458
459 size_t get_max_cpuid_count() {
460 uint32_t info[4] = {0};
461
462 cpuid(0x0,
463 info[0],
464 info[1],
465 info[2],
466 info[3]
467 );
468
469 return info[0];
470 }
common.h
Основные определения ядра
getNameBrand
char * getNameBrand()
Получение имени процессора
Definition: cpuinfo.c:80
AMD_MAGIC
#define AMD_MAGIC
Ключ процессора AMD.
Definition: cpuinfo.c:22
Intel_Other
char * Intel_Other[]
Дополнительная таблица спецификаций Intel
Definition: cpuinfo.c:116
INTEL_MAGIC
#define INTEL_MAGIC
Ключ процессора Intel.
Definition: cpuinfo.c:21
Intel
char * Intel[]
Лист-спецификаций Intel.
Definition: cpuinfo.c:84
do_intel
int do_intel(bool silent)
Получение информации о процессоре Intel.
Definition: cpuinfo.c:152
VMWARE_HYPERVISOR_MAGIC
#define VMWARE_HYPERVISOR_MAGIC
Ключ гипервизора VMWare.
Definition: cpuinfo.c:23
brandAllName
char brandAllName[128]
Название процессора
Definition: cpuinfo.c:16
detect_cpu
int detect_cpu(bool silent)
Получение имени процессора (Инициализация)
Definition: cpuinfo.c:45
do_amd
int do_amd(bool silent)
Получение информации о процессоре AMD.
Definition: cpuinfo.c:357
memset
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
Definition: string.c:203
strcat
char * strcat(char *destination, const char *source)
Объединение строк
Definition: string.c:463