blob: c35c2ba7285a3924c416b23e3ab757fd7c7dc41d (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
|
/*
* cpuid.h --
*
* contains the data structures required for CPUID
* implementation.
*
*/
#ifndef _CPUID_H_
#define _CPUID_H_
#include "stdint.h"
#include "defs.h"
#include "smp.h"
#define CPUID_EXTENDED_BASE 0x80000000
#define CPUID_EXTENDED_FEATURE 0x80000001
#define CPUID_EXTENDED_BRAND1 0x80000002
#define CPUID_EXTENDED_BRAND2 0x80000003
#define CPUID_EXTENDED_BRAND3 0x80000004
#define CPUID_VENDOR_LENGTH 3 /* 3 GPRs hold vendor ID */
#define CPUID_VENDOR_STR_LENGTH (CPUID_VENDOR_LENGTH * sizeof(uint32_t) + 1)
#define CPUID_BRAND_LENGTH 12 /* 12 GPRs hold vendor ID */
#define CPUID_BRAND_STR_LENGTH (CPUID_BRAND_LENGTH * sizeof(uint32_t) + 1)
#define CPUID_FAMILY(_eax) (((_eax) >> 8) & 0xf)
/* Intel CPU Family */
#define CPUID_FAMILY_486 4
#define CPUID_FAMILY_P5 5
#define CPUID_FAMILY_P6 6
#define CPUID_FAMILY_EXTENDED 15
#define CPUID_EXTENDED_FAMILY(_eax) (((_eax) >> 20) & 0xff)
#define CPUID_EXTENDED_FAMILY_PENTIUM4 0
#define CPUID_EXTENDED_FAMILY_OPTERON 0
#define CPUID_FAMILY_IS_OPTERON(_eax) \
(CPUID_FAMILY(_eax) == CPUID_FAMILY_EXTENDED && \
CPUID_EXTENDED_FAMILY(_eax) == CPUID_EXTENDED_FAMILY_OPTERON)
#define CPUID_FEATURE_COMMON_ID1EDX_HT 0x10000000 /* 28 */
typedef struct {
uint32_t eax;
uint32_t ebx;
uint32_t ecx;
uint32_t edx;
} cpuid_t;
/* cached CPUID data for CPUID(0) and CPUID(0x80000000) */
extern cpuid_t cpuid_data0;
extern cpuid_t cpuid_data80;
static inline unsigned
cpuid_max_func()
{
return cpuid_data0.eax;
}
static inline unsigned
cpuid_max_ext_func()
{
return cpuid_data80.eax;
}
/* Typedef for storing the CPUID Vendor String */
typedef union {
/* Note: the extra byte in the char array is for '\0'. */
char char_array[CPUID_VENDOR_STR_LENGTH];
uint32_t uint32_array[CPUID_VENDOR_LENGTH];
} cpuid_vendor_string_t;
/* Typedef for storing the CPUID Brand String */
typedef union {
/* Note: the extra byte in the char array is for '\0'. */
char char_array[CPUID_BRAND_STR_LENGTH];
uint32_t uint32_array[CPUID_BRAND_LENGTH];
} cpuid_brand_string_t;
/* Typedef for storing CPUID Version */
typedef union {
uint32_t flat;
struct {
uint32_t stepping:4; /* Bit 0 */
uint32_t model:4;
uint32_t family:4;
uint32_t processorType:2;
uint32_t reserved1514:2;
uint32_t extendedModel:4;
uint32_t extendedFamily:8;
uint32_t reserved3128:4; /* Bit 31 */
} bits;
} cpuid_version_t;
/* Typedef for storing CPUID Processor Information */
typedef union {
uint32_t flat;
struct {
uint32_t brandIndex:8; /* Bit 0 */
uint32_t cflushLineSize:8;
uint32_t logicalProcessorCount:8;
uint32_t apicID:8; /* Bit 31 */
} bits;
} cpuid_proc_info_t;
/* Typedef for storing CPUID Feature flags */
typedef union {
uint64_t flat;
uint32_t uint32_array[2];
struct {
uint32_t fpu:1; /* Bit 0 */
uint32_t vme:1;
uint32_t de:1;
uint32_t pse:1;
uint32_t tsc:1;
uint32_t msr:1;
uint32_t pae:1;
uint32_t mce:1;
uint32_t cx8:1;
uint32_t apic:1;
uint32_t reserved10:1;
uint32_t sep:1;
uint32_t mtrr:1;
uint32_t pge:1;
uint32_t mca:1;
uint32_t cmov:1;
uint32_t pat:1;
uint32_t pse36:1;
uint32_t psn:1;
uint32_t cflush:1;
uint32_t reserved20:1;
uint32_t ds:1;
uint32_t acpi:1;
uint32_t mmx:1;
uint32_t fxsr:1;
uint32_t sse:1;
uint32_t sse2:1;
uint32_t ss:1;
uint32_t htt:1;
uint32_t tm:1;
uint32_t reserved30:1;
uint32_t pbe:1; /* Bit 31 */
uint32_t sse3:1; /* Bit 32 */
uint32_t reserved3433:2;
uint32_t monitor:1;
uint32_t dscpl:1;
uint32_t reserved3937:3;
uint32_t tm2:1;
uint32_t reserved41:1;
uint32_t cnxtid:1;
uint32_t reserved4443:2;
uint32_t cmpxchg16b:1;
uint32_t reserved6346:18; /* Bit 63 */
} bits;
} cpuid_feature_flags_t;
/* Feature flags returned by extended CPUID node function 8000_0001. */
typedef union {
uint64_t flat;
uint32_t uint32_array[2];
struct {
uint32_t fpu:1; /* Bit 0 */
uint32_t vme:1;
uint32_t de:1;
uint32_t pse:1;
uint32_t tsc:1;
uint32_t msr:1;
uint32_t pae:1;
uint32_t mce:1;
uint32_t cx8:1;
uint32_t apic:1;
uint32_t reserved10:1;
uint32_t sep:1;
uint32_t mtrr:1;
uint32_t pge:1;
uint32_t mca:1;
uint32_t cmov:1;
uint32_t pat:1;
uint32_t pse36:1;
uint32_t reserved1918:2;
uint32_t nx:1;
uint32_t reserved21:1;
uint32_t mmxamd:1;
uint32_t mmx:1;
uint32_t fxsr:1;
uint32_t ffxsr:1;
uint32_t reserved26:1;
uint32_t rdtscp:1;
uint32_t reserved28:1;
uint32_t lm:1;
uint32_t threedeenowext:1;
uint32_t threedeenow:1; /* Bit 31 */
uint32_t lahf:1; /* Bit 32 */
uint32_t cmplegacy:1;
uint32_t reserved3534:2;
uint32_t cr8avail:1;
uint32_t reserved6337:27; /* Bit 63 */
} bits;
} cpuid_ext_feature_flags_t;
void cpuid_get(unsigned n, cpuid_t *data);
cpuid_vendor_string_t cpuid_get_vendor_string(void);
cpuid_version_t cpuid_get_version(void);
cpuid_feature_flags_t cpuid_get_feature_flags(void);
bool cpuid_get_ext_feature_flags(cpuid_ext_feature_flags_t *f);
bool cpuid_is_vendor_amd(void);
bool cpuid_is_vendor_intel(void);
bool cpuid_is_family_p6(void);
bool cpuid_is_family_p4(void);
bool cpuid_is_family_opteron(void);
void cpuid_init(void);
#endif
|