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 }
Основные определения ядра
char * getNameBrand()
Получение имени процессора
Definition: cpuinfo.c:80
#define AMD_MAGIC
Ключ процессора AMD.
Definition: cpuinfo.c:22
char * Intel_Other[]
Дополнительная таблица спецификаций Intel
Definition: cpuinfo.c:116
#define INTEL_MAGIC
Ключ процессора Intel.
Definition: cpuinfo.c:21
char * Intel[]
Лист-спецификаций Intel.
Definition: cpuinfo.c:84
int do_intel(bool silent)
Получение информации о процессоре Intel.
Definition: cpuinfo.c:152
#define VMWARE_HYPERVISOR_MAGIC
Ключ гипервизора VMWare.
Definition: cpuinfo.c:23
char brandAllName[128]
Название процессора
Definition: cpuinfo.c:16
int detect_cpu(bool silent)
Получение имени процессора (Инициализация)
Definition: cpuinfo.c:45
int do_amd(bool silent)
Получение информации о процессоре AMD.
Definition: cpuinfo.c:357
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
Definition: string.c:203
char * strcat(char *destination, const char *source)
Объединение строк
Definition: string.c:463