1 /* ----------------------------------------------------------------------- *
3 * Copyright 2006-2009 Erwan Velu - All Rights Reserved
5 * Portions of this file taken from the Linux kernel,
6 * Copyright 1991-2009 Linus Torvalds and contributors
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation, Inc.,
11 * 51 Franklin St, Fifth Floor, Boston MA 02110-1301;
12 * incorporated herein by reference.
14 * ----------------------------------------------------------------------- */
21 #include <cpufeature.h>
23 #include <klibc/compiler.h>
25 #define PAGE_SIZE 4096
27 #define CPU_MODEL_SIZE 48
28 #define CPU_VENDOR_SIZE 48
31 bool fpu
; /* Onboard FPU */
32 bool vme
; /* Virtual Mode Extensions */
33 bool de
; /* Debugging Extensions */
34 bool pse
; /* Page Size Extensions */
35 bool tsc
; /* Time Stamp Counter */
36 bool msr
; /* Model-Specific Registers, RDMSR, WRMSR */
37 bool pae
; /* Physical Address Extensions */
38 bool mce
; /* Machine Check Architecture */
39 bool cx8
; /* CMPXCHG8 instruction */
40 bool apic
; /* Onboard APIC */
41 bool sep
; /* SYSENTER/SYSEXIT */
42 bool mtrr
; /* Memory Type Range Registers */
43 bool pge
; /* Page Global Enable */
44 bool mca
; /* Machine Check Architecture */
45 bool cmov
; /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
46 bool pat
; /* Page Attribute Table */
47 bool pse_36
; /* 36-bit PSEs */
48 bool psn
; /* Processor serial number */
49 bool clflsh
; /* Supports the CLFLUSH instruction */
50 bool dts
; /* Debug Trace Store */
51 bool acpi
; /* ACPI via MSR */
52 bool pbe
; /* Pending Break Enable */
53 bool mmx
; /* Multimedia Extensions */
54 bool fxsr
; /* FXSAVE and FXRSTOR instructions (fast save and restore */
55 /* of FPU context), and CR4.OSFXSR available */
56 bool sse
; /* Streaming SIMD Extensions */
57 bool sse2
; /* Streaming SIMD Extensions 2 */
58 bool ss
; /* CPU self snoop */
59 bool htt
; /* Hyper-Threading */
60 bool acc
; /* Automatic clock control */
61 bool syscall
; /* SYSCALL/SYSRET */
62 bool mp
; /* MP Capable. */
63 bool nx
; /* Execute Disable */
64 bool mmxext
; /* AMD MMX extensions */
65 bool fxsr_opt
; /* FXSAVE/FXRSTOR optimizations */
66 bool gbpages
; /* "pdpe1gb" GB pages */
67 bool rdtscp
; /* RDTSCP */
68 bool lm
; /* Long Mode (x86-64) */
69 bool nowext
; /* AMD 3DNow! extensions */
70 bool now
; /* 3DNow! */
71 bool smp
; /* A smp configuration has been found */
72 bool pni
; /* Streaming SIMD Extensions-3 */
73 bool pclmulqd
; /* PCLMULQDQ instruction */
74 bool dtes64
; /* 64-bit Debug Store */
75 bool vmx
; /* Hardware virtualization */
76 bool smx
; /* Safer Mode */
77 bool est
; /* Enhanced SpeedStep */
78 bool tm2
; /* Thermal Monitor 2 */
79 bool sse3
; /* Supplemental SSE-3 */
80 bool cid
; /* Context ID */
81 bool fma
; /* Fused multiply-add */
82 bool cx16
; /* CMPXCHG16B */
83 bool xtpr
; /* Send Task Priority Messages */
84 bool pdcm
; /* Performance Capabilities */
85 bool dca
; /* Direct Cache Access */
86 bool xmm4_1
; /* "sse4_1" SSE-4.1 */
87 bool xmm4_2
; /* "sse4_2" SSE-4.2 */
88 bool x2apic
; /* x2APIC */
89 bool movbe
; /* MOVBE instruction */
90 bool popcnt
; /* POPCNT instruction */
91 bool aes
; /* AES Instruction */
92 bool xsave
; /* XSAVE/XRSTOR/XSETBV/XGETBV */
93 bool osxsave
; /* XSAVE enabled in the OS */
94 bool avx
; /* Advanced Vector Extensions */
95 bool hypervisor
; /* Running on a hypervisor */
96 bool ace2
; /* Advanced Cryptography Engine v2 */
97 bool ace2_en
; /* ACE v2 enabled */
98 bool phe
; /* PadLock Hash Engine */
99 bool phe_en
; /* PadLock Hash Engine Enabled */
100 bool pmm
; /* PadLock Montgomery Multiplier */
101 bool pmm_en
; /* PadLock Montgomery Multiplier enabled */
102 bool svm
; /* Secure virtual machine */
103 bool extapic
; /* Extended APIC space */
104 bool cr8_legacy
; /* CR8 in 32-bit mode */
105 bool abm
; /* Advanced bit manipulation */
106 bool sse4a
; /* SSE4-A */
107 bool misalignsse
; /* Misaligned SSE mode */
108 bool nowprefetch
; /* 3DNow prefetch instructions */
109 bool osvw
; /* OS Visible Workaround */
110 bool ibs
; /* Instruction Based Sampling */
111 bool sse5
; /* SSE5 */
112 bool skinit
; /* SKINIT/STGI instructions */
113 bool wdt
; /* Watchdog Timer */
114 bool ida
; /* Intel Dynamic Acceleration */
115 bool arat
; /* Always Running APIC Timer */
116 bool tpr_shadow
; /* Intel TPR Shadow */
117 bool vnmi
; /* Intel Virtual NMI */
118 bool flexpriority
; /* Intel FlexPriority */
119 bool ept
; /* Intel Extended Page Table */
120 bool vpid
; /* Intel Virtual Processor ID */
124 char vendor
[CPU_VENDOR_SIZE
];
127 char model
[CPU_MODEL_SIZE
];
131 uint16_t l1_data_cache_size
;
132 uint16_t l1_instruction_cache_size
;
133 uint16_t l2_cache_size
;
137 /**********************************************************************************/
138 /**********************************************************************************/
139 /* From this point this is some internal stuff mainly taken from the linux kernel */
140 /**********************************************************************************/
141 /**********************************************************************************/
146 #define X86_EFLAGS_CF 0x00000001 /* Carry Flag */
147 #define X86_EFLAGS_PF 0x00000004 /* Parity Flag */
148 #define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */
149 #define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */
150 #define X86_EFLAGS_SF 0x00000080 /* Sign Flag */
151 #define X86_EFLAGS_TF 0x00000100 /* Trap Flag */
152 #define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */
153 #define X86_EFLAGS_DF 0x00000400 /* Direction Flag */
154 #define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */
155 #define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */
156 #define X86_EFLAGS_NT 0x00004000 /* Nested Task */
157 #define X86_EFLAGS_RF 0x00010000 /* Resume Flag */
158 #define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */
159 #define X86_EFLAGS_AC 0x00040000 /* Alignment Check */
160 #define X86_EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */
161 #define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */
162 #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
164 #define X86_VENDOR_INTEL 0
165 #define X86_VENDOR_CYRIX 1
166 #define X86_VENDOR_AMD 2
167 #define X86_VENDOR_UMC 3
168 #define X86_VENDOR_NEXGEN 4
169 #define X86_VENDOR_CENTAUR 5
170 #define X86_VENDOR_RISE 6
171 #define X86_VENDOR_TRANSMETA 7
172 #define X86_VENDOR_NSC 8
173 #define X86_VENDOR_NUM 9
174 #define X86_VENDOR_UNKNOWN 0xff
176 static inline __purefunc
bool test_bit(int nr
, const uint32_t * addr
)
178 return ((1UL << (nr
& 31)) & (addr
[nr
>> 5])) != 0;
181 #define cpu_has(c, bit) test_bit(bit, (c)->x86_capability)
184 * CPU type and hardware bug flags. Kept separately for each CPU.
185 * Members of this structure are referenced in head.S, so think twice
186 * before touching them. [mj]
190 uint8_t x86
; /* CPU family */
191 uint8_t x86_vendor
; /* CPU vendor */
194 char wp_works_ok
; /* It doesn't on 386's */
195 char hlt_works_ok
; /* Problems on some 486Dx4's and old 386's */
198 int cpuid_level
; /* Maximum supported CPUID level, -1=no CPUID */
199 uint32_t x86_capability
[NCAPINTS
];
200 char x86_vendor_id
[16];
201 char x86_model_id
[64];
202 uint16_t x86_l1_data_cache_size
; /* in KB, if available */
203 uint16_t x86_l1_instruction_cache_size
; /* in KB, if available */
204 uint16_t x86_l2_cache_size
; /* in KB, if available */
205 int x86_cache_alignment
; /* in bytes */
211 unsigned long loops_per_jiffy
;
213 cpumask_t llc_shared_map
; /* cpus sharing the last level cache */
215 unsigned char x86_num_cores
; /* cpuid returned the number of cores */
216 unsigned char booted_cores
; /* number of cores as seen by OS */
217 unsigned char apicid
;
218 unsigned char x86_clflush_size
;
220 } __attribute__ ((__packed__
));
222 struct cpu_model_info
{
225 char *model_names
[16];
228 /* attempt to consolidate cpu attributes */
230 const char *c_vendor
;
232 /* some have two possibilities for cpuid string */
233 const char *c_ident
[2];
235 struct cpu_model_info c_models
[4];
237 void (*c_init
) (struct cpuinfo_x86
* c
);
238 void (*c_identify
) (struct cpuinfo_x86
* c
);
239 unsigned int (*c_size_cache
) (struct cpuinfo_x86
* c
, unsigned int size
);
243 * Structure definitions for SMP machines following the
244 * Intel Multiprocessing Specification 1.1 and 1.4.
248 * This tag identifies where the SMP configuration
252 #define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_')
254 struct intel_mp_floating
{
255 char mpf_signature
[4]; /* "_MP_" */
256 uint32_t mpf_physptr
; /* Configuration table address */
257 uint8_t mpf_length
; /* Our length (paragraphs) */
258 uint8_t mpf_specification
; /* Specification version */
259 uint8_t mpf_checksum
; /* Checksum (makes sum 0) */
260 uint8_t mpf_feature1
; /* Standard or configuration ? */
261 uint8_t mpf_feature2
; /* Bit7 set for IMCR|PIC */
262 uint8_t mpf_feature3
; /* Unused (0) */
263 uint8_t mpf_feature4
; /* Unused (0) */
264 uint8_t mpf_feature5
; /* Unused (0) */
267 extern void get_cpu_vendor(struct cpuinfo_x86
*c
);
268 extern void detect_cpu(s_cpu
* cpu
);