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