blob: 4c25ede95affbf5f595fc5447995929842e1c4f5 [file] [log] [blame]
Martin Roth9b1b3352016-02-24 12:27:06 -08001/*
2 * cpuid.c --
3 *
4 * Implements CPUID querying functions
5 *
6 */
7#include "stdin.h"
8#include "cpuid.h"
9
10struct cpu_ident cpu_id;
11
12void get_cpuid()
13{
14 unsigned int *v, dummy[3];
15 char *p, *q;
16
17 /* Get max std cpuid & vendor ID */
18 cpuid(0x0, &cpu_id.max_cpuid, &cpu_id.vend_id.uint32_array[0],
19 &cpu_id.vend_id.uint32_array[2], &cpu_id.vend_id.uint32_array[1]);
20 cpu_id.vend_id.char_array[11] = 0;
21
22 /* Get processor family information & feature flags */
23 if (cpu_id.max_cpuid >= 1) {
24 cpuid(0x00000001, &cpu_id.vers.flat, &cpu_id.info.flat,
25 &cpu_id.fid.uint32_array[1], &cpu_id.fid.uint32_array[0]);
26 }
27
28 /* Get the digital thermal sensor & power management status bits */
29 if(cpu_id.max_cpuid >= 6) {
30 cpuid(0x00000006, &cpu_id.dts_pmp, &dummy[0], &dummy[1], &dummy[2]);
31 }
32
33 /* Get the max extended cpuid */
34 cpuid(0x80000000, &cpu_id.max_xcpuid, &dummy[0], &dummy[1], &dummy[2]);
35
36 /* Get extended feature flags, only save EDX */
37 if (cpu_id.max_xcpuid >= 0x80000001) {
38 cpuid(0x80000001, &dummy[0], &dummy[1],
39 &dummy[2], &cpu_id.fid.uint32_array[2]);
40 }
41
42 /* Get the brand ID */
43 if (cpu_id.max_xcpuid >= 0x80000004) {
44 v = (unsigned int *)&cpu_id.brand_id;
45 cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
46 cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
47 cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
48 cpu_id.brand_id.char_array[47] = 0;
49 }
50 /*
51 * Intel chips right-justify this string for some dumb reason;
52 * undo that brain damage:
53 */
54 p = q = &cpu_id.brand_id.char_array[0];
55 while (*p == ' ')
56 p++;
57 if (p != q) {
58 while (*p)
59 *q++ = *p++;
60 while (q <= &cpu_id.brand_id.char_array[48])
61 *q++ = '\0'; /* Zero-pad the rest */
62 }
63
64 /* Get cache information */
65 switch(cpu_id.vend_id.char_array[0]) {
66 case 'A':
67 /* AMD Processors */
68 /* The cache information is only in ecx and edx so only save
69 * those registers */
70 if (cpu_id.max_xcpuid >= 0x80000005) {
71 cpuid(0x80000005, &dummy[0], &dummy[1],
72 &cpu_id.cache_info.uint[0], &cpu_id.cache_info.uint[1]);
73 }
74 if (cpu_id.max_xcpuid >= 0x80000006) {
75 cpuid(0x80000006, &dummy[0], &dummy[1],
76 &cpu_id.cache_info.uint[2], &cpu_id.cache_info.uint[3]);
77 }
78 break;
79 case 'G':
80 /* Intel Processors, Need to do this in init.c */
81 break;
82 }
83
84 /* Turn off mon bit since monitor based spin wait may not be reliable */
85 cpu_id.fid.bits.mon = 0;
86
87}