xref: /haiku/headers/private/kernel/arch/x86/arch_cpu.h (revision c8fcb2a04eae4f56899e660db81a72aacdbef46f)
1 /*
2  * Copyright 2018, Jérôme Duval, jerome.duval@gmail.com.
3  * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
4  * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
5  * Distributed under the terms of the MIT License.
6  *
7  * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
8  * Distributed under the terms of the NewOS License.
9  */
10 #ifndef _KERNEL_ARCH_x86_CPU_H
11 #define _KERNEL_ARCH_x86_CPU_H
12 
13 
14 #ifndef _ASSEMBLER
15 
16 #include <module.h>
17 
18 #include <arch_thread_types.h>
19 
20 #include <arch/x86/descriptors.h>
21 
22 #ifdef __x86_64__
23 #	include <arch/x86/64/cpu.h>
24 #endif
25 
26 #endif	// !_ASSEMBLER
27 
28 
29 #define CPU_MAX_CACHE_LEVEL	8
30 
31 #define CACHE_LINE_SIZE		64
32 
33 
34 // MSR registers (possibly Intel specific)
35 #define IA32_MSR_TSC					0x10
36 #define IA32_MSR_APIC_BASE				0x1b
37 
38 #define IA32_MSR_PLATFORM_INFO			0xce
39 #define IA32_MSR_MPERF					0xe7
40 #define IA32_MSR_APERF					0xe8
41 #define IA32_MSR_MTRR_CAPABILITIES		0xfe
42 #define IA32_MSR_SYSENTER_CS			0x174
43 #define IA32_MSR_SYSENTER_ESP			0x175
44 #define IA32_MSR_SYSENTER_EIP			0x176
45 #define IA32_MSR_PERF_STATUS			0x198
46 #define IA32_MSR_PERF_CTL				0x199
47 #define IA32_MSR_TURBO_RATIO_LIMIT		0x1ad
48 #define IA32_MSR_ENERGY_PERF_BIAS		0x1b0
49 #define IA32_MSR_MTRR_DEFAULT_TYPE		0x2ff
50 #define IA32_MSR_MTRR_PHYSICAL_BASE_0	0x200
51 #define IA32_MSR_MTRR_PHYSICAL_MASK_0	0x201
52 
53 
54 // MSR APIC BASE bits
55 #define IA32_MSR_APIC_BASE_BSP			0x00000100
56 #define IA32_MSR_APIC_BASE_X2APIC		0x00000400
57 #define IA32_MSR_APIC_BASE_ENABLED		0x00000800
58 #define IA32_MSR_APIC_BASE_ADDRESS		0xfffff000
59 
60 // MSR EFER bits
61 // reference
62 #define IA32_MSR_EFER_SYSCALL			(1 << 0)
63 #define IA32_MSR_EFER_NX				(1 << 11)
64 
65 // X2APIC MSRs.
66 #define IA32_MSR_APIC_ID					0x00000802
67 #define IA32_MSR_APIC_VERSION				0x00000803
68 #define IA32_MSR_APIC_TASK_PRIORITY			0x00000808
69 #define IA32_MSR_APIC_PROCESSOR_PRIORITY	0x0000080a
70 #define IA32_MSR_APIC_EOI					0x0000080b
71 #define IA32_MSR_APIC_LOGICAL_DEST			0x0000080d
72 #define IA32_MSR_APIC_SPURIOUS_INTR_VECTOR	0x0000080f
73 #define IA32_MSR_APIC_ERROR_STATUS			0x00000828
74 #define IA32_MSR_APIC_INTR_COMMAND			0x00000830
75 #define IA32_MSR_APIC_LVT_TIMER				0x00000832
76 #define IA32_MSR_APIC_LVT_THERMAL_SENSOR	0x00000833
77 #define IA32_MSR_APIC_LVT_PERFMON_COUNTERS	0x00000834
78 #define IA32_MSR_APIC_LVT_LINT0				0x00000835
79 #define IA32_MSR_APIC_LVT_LINT1				0x00000836
80 #define IA32_MSR_APIC_LVT_ERROR				0x00000837
81 #define IA32_MSR_APIC_INITIAL_TIMER_COUNT	0x00000838
82 #define IA32_MSR_APIC_CURRENT_TIMER_COUNT	0x00000839
83 #define IA32_MSR_APIC_TIMER_DIVIDE_CONFIG	0x0000083e
84 #define IA32_MSR_APIC_SELF_IPI				0x0000083f
85 #define IA32_MSR_XSS						0x00000da0
86 
87 // x86_64 MSRs.
88 #define IA32_MSR_EFER					0xc0000080
89 #define IA32_MSR_STAR					0xc0000081
90 #define IA32_MSR_LSTAR					0xc0000082
91 #define IA32_MSR_CSTAR					0xc0000083
92 #define IA32_MSR_FMASK					0xc0000084
93 #define IA32_MSR_FS_BASE				0xc0000100
94 #define IA32_MSR_GS_BASE				0xc0000101
95 #define IA32_MSR_KERNEL_GS_BASE			0xc0000102
96 
97 // K8 MSR registers
98 #define K8_MSR_IPM						0xc0010055
99 
100 // x86 features from cpuid eax 1, edx register
101 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-5)
102 #define IA32_FEATURE_FPU	(1 << 0) // x87 fpu
103 #define IA32_FEATURE_VME	(1 << 1) // virtual 8086
104 #define IA32_FEATURE_DE		(1 << 2) // debugging extensions
105 #define IA32_FEATURE_PSE	(1 << 3) // page size extensions
106 #define IA32_FEATURE_TSC	(1 << 4) // rdtsc instruction
107 #define IA32_FEATURE_MSR	(1 << 5) // rdmsr/wrmsr instruction
108 #define IA32_FEATURE_PAE	(1 << 6) // extended 3 level page table addressing
109 #define IA32_FEATURE_MCE	(1 << 7) // machine check exception
110 #define IA32_FEATURE_CX8	(1 << 8) // cmpxchg8b instruction
111 #define IA32_FEATURE_APIC	(1 << 9) // local apic on chip
112 //							(1 << 10) // Reserved
113 #define IA32_FEATURE_SEP	(1 << 11) // SYSENTER/SYSEXIT
114 #define IA32_FEATURE_MTRR	(1 << 12) // MTRR
115 #define IA32_FEATURE_PGE	(1 << 13) // paging global bit
116 #define IA32_FEATURE_MCA	(1 << 14) // machine check architecture
117 #define IA32_FEATURE_CMOV	(1 << 15) // cmov instruction
118 #define IA32_FEATURE_PAT	(1 << 16) // page attribute table
119 #define IA32_FEATURE_PSE36	(1 << 17) // page size extensions with 4MB pages
120 #define IA32_FEATURE_PSN	(1 << 18) // processor serial number
121 #define IA32_FEATURE_CLFSH	(1 << 19) // cflush instruction
122 //							(1 << 20) // Reserved
123 #define IA32_FEATURE_DS		(1 << 21) // debug store
124 #define IA32_FEATURE_ACPI	(1 << 22) // thermal monitor and clock ctrl
125 #define IA32_FEATURE_MMX	(1 << 23) // mmx instructions
126 #define IA32_FEATURE_FXSR	(1 << 24) // FXSAVE/FXRSTOR instruction
127 #define IA32_FEATURE_SSE	(1 << 25) // SSE
128 #define IA32_FEATURE_SSE2	(1 << 26) // SSE2
129 #define IA32_FEATURE_SS		(1 << 27) // self snoop
130 #define IA32_FEATURE_HTT	(1 << 28) // hyperthreading
131 #define IA32_FEATURE_TM		(1 << 29) // thermal monitor
132 #define IA32_FEATURE_IA64	(1 << 30) // IA64 processor emulating x86
133 #define IA32_FEATURE_PBE	(1 << 31) // pending break enable
134 
135 // x86 features from cpuid eax 1, ecx register
136 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-4)
137 #define IA32_FEATURE_EXT_SSE3		(1 << 0) // SSE3
138 #define IA32_FEATURE_EXT_PCLMULQDQ	(1 << 1) // PCLMULQDQ Instruction
139 #define IA32_FEATURE_EXT_DTES64		(1 << 2) // 64-Bit Debug Store
140 #define IA32_FEATURE_EXT_MONITOR	(1 << 3) // MONITOR/MWAIT
141 #define IA32_FEATURE_EXT_DSCPL		(1 << 4) // CPL qualified debug store
142 #define IA32_FEATURE_EXT_VMX		(1 << 5) // Virtual Machine Extensions
143 #define IA32_FEATURE_EXT_SMX		(1 << 6) // Safer Mode Extensions
144 #define IA32_FEATURE_EXT_EST		(1 << 7) // Enhanced SpeedStep
145 #define IA32_FEATURE_EXT_TM2		(1 << 8) // Thermal Monitor 2
146 #define IA32_FEATURE_EXT_SSSE3		(1 << 9) // Supplemental SSE-3
147 #define IA32_FEATURE_EXT_CNXTID		(1 << 10) // L1 Context ID
148 //									(1 << 11) // Reserved
149 #define IA32_FEATURE_EXT_FMA		(1 << 12) // Fused Multiply Add
150 #define IA32_FEATURE_EXT_CX16		(1 << 13) // CMPXCHG16B
151 #define IA32_FEATURE_EXT_XTPR		(1 << 14) // xTPR Update Control
152 #define IA32_FEATURE_EXT_PDCM		(1 << 15) // Perfmon and Debug Capability
153 //									(1 << 16) // Reserved
154 #define IA32_FEATURE_EXT_PCID		(1 << 17) // Process Context Identifiers
155 #define IA32_FEATURE_EXT_DCA		(1 << 18) // Direct Cache Access
156 #define IA32_FEATURE_EXT_SSE4_1		(1 << 19) // SSE4.1
157 #define IA32_FEATURE_EXT_SSE4_2		(1 << 20) // SSE4.2
158 #define IA32_FEATURE_EXT_X2APIC		(1 << 21) // Extended xAPIC Support
159 #define IA32_FEATURE_EXT_MOVBE 		(1 << 22) // MOVBE Instruction
160 #define IA32_FEATURE_EXT_POPCNT		(1 << 23) // POPCNT Instruction
161 #define IA32_FEATURE_EXT_TSCDEADLINE (1 << 24) // Time Stamp Counter Deadline
162 #define IA32_FEATURE_EXT_AES		(1 << 25) // AES Instruction Extensions
163 #define IA32_FEATURE_EXT_XSAVE		(1 << 26) // XSAVE/XSTOR States
164 #define IA32_FEATURE_EXT_OSXSAVE	(1 << 27) // OS-Enabled XSAVE
165 #define IA32_FEATURE_EXT_AVX		(1 << 28) // Advanced Vector Extensions
166 #define IA32_FEATURE_EXT_F16C		(1 << 29) // 16-bit FP conversion
167 #define IA32_FEATURE_EXT_RDRND		(1 << 30) // RDRAND instruction
168 #define IA32_FEATURE_EXT_HYPERVISOR	(1 << 31) // Running on a hypervisor
169 
170 // x86 features from cpuid eax 0x80000001, ecx register (AMD)
171 #define IA32_FEATURE_AMD_EXT_CMPLEGACY	(1 << 1) // Core MP legacy mode
172 #define IA32_FEATURE_AMD_EXT_TOPOLOGY	(1 << 22) // Topology extensions
173 
174 // x86 features from cpuid eax 0x80000001, edx register (AMD)
175 // only care about the ones that are unique to this register
176 #define IA32_FEATURE_AMD_EXT_SYSCALL	(1 << 11) // SYSCALL/SYSRET
177 #define IA32_FEATURE_AMD_EXT_NX			(1 << 20) // no execute bit
178 #define IA32_FEATURE_AMD_EXT_MMXEXT		(1 << 22) // mmx extensions
179 #define IA32_FEATURE_AMD_EXT_FFXSR		(1 << 25) // fast FXSAVE/FXRSTOR
180 #define IA32_FEATURE_AMD_EXT_RDTSCP		(1 << 27) // rdtscp instruction
181 #define IA32_FEATURE_AMD_EXT_LONG		(1 << 29) // long mode
182 #define IA32_FEATURE_AMD_EXT_3DNOWEXT	(1 << 30) // 3DNow! extensions
183 #define IA32_FEATURE_AMD_EXT_3DNOW		(1 << 31) // 3DNow!
184 
185 // some of the features from cpuid eax 0x80000001, edx register (AMD) are also
186 // available on Intel processors
187 #define IA32_FEATURES_INTEL_EXT			(IA32_FEATURE_AMD_EXT_SYSCALL		\
188 											| IA32_FEATURE_AMD_EXT_NX		\
189 											| IA32_FEATURE_AMD_EXT_RDTSCP	\
190 											| IA32_FEATURE_AMD_EXT_LONG)
191 
192 // x86 defined features from cpuid eax 5, ecx register
193 #define IA32_FEATURE_POWER_MWAIT		(1 << 0)
194 #define IA32_FEATURE_INTERRUPT_MWAIT	(1 << 1)
195 
196 // x86 defined features from cpuid eax 6, eax register
197 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-11)
198 #define IA32_FEATURE_DTS	(1 << 0) //Digital Thermal Sensor
199 #define IA32_FEATURE_ITB	(1 << 1) //Intel Turbo Boost Technology
200 #define IA32_FEATURE_ARAT	(1 << 2) //Always running APIC Timer
201 #define IA32_FEATURE_PLN	(1 << 4) //Power Limit Notification
202 #define IA32_FEATURE_ECMD	(1 << 5) //Extended Clock Modulation Duty
203 #define IA32_FEATURE_PTM	(1 << 6) //Package Thermal Management
204 
205 // x86 defined features from cpuid eax 6, ecx register
206 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-11)
207 #define IA32_FEATURE_APERFMPERF	(1 << 0) //IA32_APERF, IA32_MPERF
208 #define IA32_FEATURE_EPB	(1 << 3) //IA32_ENERGY_PERF_BIAS
209 
210 // x86 features from cpuid eax 7, ebx register
211 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 3-8)
212 #define IA32_FEATURE_TSC_ADJUST	(1 << 1) // IA32_TSC_ADJUST MSR supported
213 #define IA32_FEATURE_SGX		(1 << 2) // Software Guard Extensions
214 #define IA32_FEATURE_BMI1		(1 << 3) // Bit Manipulation Instruction Set 1
215 #define IA32_FEATURE_HLE		(1 << 4) // Hardware Lock Elision
216 #define IA32_FEATURE_AVX2		(1 << 5) // Advanced Vector Extensions 2
217 #define IA32_FEATURE_SMEP		(1 << 7) // Supervisor-Mode Execution Prevention
218 #define IA32_FEATURE_BMI2		(1 << 8) // Bit Manipulation Instruction Set 2
219 #define IA32_FEATURE_ERMS		(1 << 9) // Enhanced REP MOVSB/STOSB
220 #define IA32_FEATURE_INVPCID	(1 << 10) // INVPCID instruction
221 #define IA32_FEATURE_RTM		(1 << 11) // Transactional Synchronization Extensions
222 #define IA32_FEATURE_CQM		(1 << 12) // Platform Quality of Service Monitoring
223 #define IA32_FEATURE_MPX		(1 << 14) // Memory Protection Extensions
224 #define IA32_FEATURE_RDT_A		(1 << 15) // Resource Director Technology Allocation
225 #define IA32_FEATURE_AVX512F	(1 << 16) // AVX-512 Foundation
226 #define IA32_FEATURE_AVX512DQ	(1 << 17) // AVX-512 Doubleword and Quadword Instructions
227 #define IA32_FEATURE_RDSEED		(1 << 18) // RDSEED instruction
228 #define IA32_FEATURE_ADX		(1 << 19) // ADX (Multi-Precision Add-Carry Instruction Extensions)
229 #define IA32_FEATURE_SMAP		(1 << 20) // Supervisor Mode Access Prevention
230 #define IA32_FEATURE_AVX512IFMA	(1 << 21) // AVX-512 Integer Fused Multiply-Add Instructions
231 #define IA32_FEATURE_PCOMMIT	(1 << 22) // PCOMMIT instruction
232 #define IA32_FEATURE_CLFLUSHOPT	(1 << 23) // CLFLUSHOPT instruction
233 #define IA32_FEATURE_CLWB		(1 << 24) // CLWB instruction
234 #define IA32_FEATURE_INTEL_PT	(1 << 25) // Intel Processor Trace
235 #define IA32_FEATURE_AVX512PF	(1 << 26) // AVX-512 Prefetch Instructions
236 #define IA32_FEATURE_AVX512ER	(1 << 27) // AVX-512 Exponential and Reciprocal Instructions
237 #define IA32_FEATURE_AVX512CD	(1 << 28) // AVX-512 Conflict Detection Instructions
238 #define IA32_FEATURE_SHA_NI		(1 << 29) // SHA extensions
239 #define IA32_FEATURE_AVX512BW	(1 << 30) // AVX-512 Byte and Word Instructions
240 #define IA32_FEATURE_AVX512VI	(1 << 31) // AVX-512 Vector Length Extensions
241 
242 // x86 features from cpuid eax 7, ecx register
243 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 3-8)
244 // https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features
245 #define IA32_FEATURE_AVX512VMBI		(1 << 1) // AVX-512 Vector Bit Manipulation Instructions
246 #define IA32_FEATURE_UMIP			(1 << 2) // User-mode Instruction Prevention
247 #define IA32_FEATURE_PKU			(1 << 3) // Memory Protection Keys for User-mode pages
248 #define IA32_FEATURE_OSPKE			(1 << 4) // PKU enabled by OS
249 #define IA32_FEATURE_AVX512VMBI2	(1 << 6) // AVX-512 Vector Bit Manipulation Instructions 2
250 #define IA32_FEATURE_GFNI			(1 << 8) // Galois Field instructions
251 #define IA32_FEATURE_VAES			(1 << 9) // AES instruction set (VEX-256/EVEX)
252 #define IA32_FEATURE_VPCLMULQDQ		(1 << 10) // CLMUL instruction set (VEX-256/EVEX)
253 #define IA32_FEATURE_AVX512_VNNI	(1 << 11) // AVX-512 Vector Neural Network Instructions
254 #define IA32_FEATURE_AVX512_BITALG	(1 << 12) // AVX-512 BITALG instructions
255 #define IA32_FEATURE_AVX512_VPOPCNTDQ (1 << 14) // AVX-512 Vector Population Count D/Q
256 #define IA32_FEATURE_LA57			(1 << 16) // 5-level page tables
257 #define IA32_FEATURE_RDPID			(1 << 22) // RDPID Instruction
258 #define IA32_FEATURE_SGX_LC			(1 << 30) // SGX Launch Configuration
259 
260 // x86 features from cpuid eax 7, edx register
261 // https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features
262 #define IA32_FEATURE_AVX512_4VNNIW	(1 << 2) // AVX-512 4-register Neural Network Instructions
263 #define IA32_FEATURE_AVX512_4FMAPS	(1 << 3) // AVX-512 4-register Multiply Accumulation Single precision
264 #define IA32_FEATURE_IBRS			(1 << 26)	// IBRS / IBPB Speculation Control
265 #define IA32_FEATURE_STIBP			(1 << 27)	// STIBP Speculation Control
266 
267 
268 // x86 defined features from cpuid eax 0x80000007, edx register
269 #define IA32_FEATURE_INVARIANT_TSC		(1 << 8)
270 
271 // x86 defined features from cpuid eax 0x80000008, ebx register
272 #define IA32_FEATURE_AMD_EXT_IBPB	(1 << 12)	/* IBPB Support only (no IBRS) */
273 
274 
275 // cr4 flags
276 #define IA32_CR4_PAE					(1UL << 5)
277 #define IA32_CR4_GLOBAL_PAGES			(1UL << 7)
278 
279 // Memory type ranges
280 #define IA32_MTR_UNCACHED				0
281 #define IA32_MTR_WRITE_COMBINING		1
282 #define IA32_MTR_WRITE_THROUGH			4
283 #define IA32_MTR_WRITE_PROTECTED		5
284 #define IA32_MTR_WRITE_BACK				6
285 
286 // EFLAGS register
287 #define X86_EFLAGS_CARRY						0x00000001
288 #define X86_EFLAGS_RESERVED1					0x00000002
289 #define X86_EFLAGS_PARITY						0x00000004
290 #define X86_EFLAGS_AUXILIARY_CARRY				0x00000010
291 #define X86_EFLAGS_ZERO							0x00000040
292 #define X86_EFLAGS_SIGN							0x00000080
293 #define X86_EFLAGS_TRAP							0x00000100
294 #define X86_EFLAGS_INTERRUPT					0x00000200
295 #define X86_EFLAGS_DIRECTION					0x00000400
296 #define X86_EFLAGS_OVERFLOW						0x00000800
297 #define X86_EFLAGS_IO_PRIVILEG_LEVEL			0x00003000
298 #define X86_EFLAGS_IO_PRIVILEG_LEVEL_SHIFT		12
299 #define X86_EFLAGS_NESTED_TASK					0x00004000
300 #define X86_EFLAGS_RESUME						0x00010000
301 #define X86_EFLAGS_V86_MODE						0x00020000
302 #define X86_EFLAGS_ALIGNMENT_CHECK				0x00040000
303 #define X86_EFLAGS_VIRTUAL_INTERRUPT			0x00080000
304 #define X86_EFLAGS_VIRTUAL_INTERRUPT_PENDING	0x00100000
305 #define X86_EFLAGS_ID							0x00200000
306 
307 #define X86_EFLAGS_USER_FLAGS	(X86_EFLAGS_CARRY | X86_EFLAGS_PARITY \
308 	| X86_EFLAGS_AUXILIARY_CARRY | X86_EFLAGS_ZERO | X86_EFLAGS_SIGN \
309 	| X86_EFLAGS_DIRECTION | X86_EFLAGS_OVERFLOW)
310 
311 #define CR0_CACHE_DISABLE		(1UL << 30)
312 #define CR0_NOT_WRITE_THROUGH	(1UL << 29)
313 #define CR0_FPU_EMULATION		(1UL << 2)
314 #define CR0_MONITOR_FPU			(1UL << 1)
315 
316 #define CR4_OS_FXSR				(1UL << 9)
317 #define CR4_OS_XMM_EXCEPTION	(1UL << 10)
318 
319 
320 // iframe types
321 #define IFRAME_TYPE_SYSCALL				0x1
322 #define IFRAME_TYPE_OTHER				0x2
323 #define IFRAME_TYPE_MASK				0xf
324 
325 
326 #ifndef _ASSEMBLER
327 
328 
329 struct X86PagingStructures;
330 
331 
332 typedef struct x86_mtrr_info {
333 	uint64	base;
334 	uint64	size;
335 	uint8	type;
336 } x86_mtrr_info;
337 
338 typedef struct x86_cpu_module_info {
339 	module_info	info;
340 	uint32		(*count_mtrrs)(void);
341 	void		(*init_mtrrs)(void);
342 
343 	void		(*set_mtrr)(uint32 index, uint64 base, uint64 length,
344 					uint8 type);
345 	status_t	(*get_mtrr)(uint32 index, uint64* _base, uint64* _length,
346 					uint8* _type);
347 	void		(*set_mtrrs)(uint8 defaultType, const x86_mtrr_info* infos,
348 					uint32 count);
349 } x86_cpu_module_info;
350 
351 // features
352 enum x86_feature_type {
353 	FEATURE_COMMON = 0,     // cpuid eax=1, ecx register
354 	FEATURE_EXT,            // cpuid eax=1, edx register
355 	FEATURE_EXT_AMD_ECX,	// cpuid eax=0x80000001, ecx register (AMD)
356 	FEATURE_EXT_AMD,        // cpuid eax=0x80000001, edx register (AMD)
357 	FEATURE_5_ECX,			// cpuid eax=5, ecx register
358 	FEATURE_6_EAX,          // cpuid eax=6, eax registers
359 	FEATURE_6_ECX,          // cpuid eax=6, ecx registers
360 	FEATURE_7_EBX,          // cpuid eax=7, ebx registers
361 	FEATURE_7_ECX,          // cpuid eax=7, ecx registers
362 	FEATURE_7_EDX,          // cpuid eax=7, edx registers
363 	FEATURE_EXT_7_EDX,		// cpuid eax=0x80000007, edx register
364 	FEATURE_EXT_8_EBX,		// cpuid eax=0x80000008, ebx register
365 
366 	FEATURE_NUM
367 };
368 
369 enum x86_vendors {
370 	VENDOR_INTEL = 0,
371 	VENDOR_AMD,
372 	VENDOR_CYRIX,
373 	VENDOR_UMC,
374 	VENDOR_NEXGEN,
375 	VENDOR_CENTAUR,
376 	VENDOR_RISE,
377 	VENDOR_TRANSMETA,
378 	VENDOR_NSC,
379 
380 	VENDOR_NUM,
381 	VENDOR_UNKNOWN,
382 };
383 
384 
385 typedef struct arch_cpu_info {
386 	// saved cpu info
387 	enum x86_vendors	vendor;
388 	uint32				feature[FEATURE_NUM];
389 	char				model_name[49];
390 	const char*			vendor_name;
391 	int					type;
392 	int					family;
393 	int					extended_family;
394 	int					stepping;
395 	int					model;
396 	int					extended_model;
397 
398 	uint32				logical_apic_id;
399 
400 	struct X86PagingStructures* active_paging_structures;
401 
402 	size_t				dr6;	// temporary storage for debug registers (cf.
403 	size_t				dr7;	// x86_exit_user_debug_at_kernel_entry())
404 
405 	// local TSS for this cpu
406 	struct tss			tss;
407 #ifndef __x86_64__
408 	struct tss			double_fault_tss;
409 	void*				kernel_tls;
410 #endif
411 } arch_cpu_info;
412 
413 
414 #define nop() __asm__ ("nop"::)
415 
416 #define x86_read_cr0() ({ \
417 	size_t _v; \
418 	__asm__("mov	%%cr0,%0" : "=r" (_v)); \
419 	_v; \
420 })
421 
422 #define x86_write_cr0(value) \
423 	__asm__("mov	%0,%%cr0" : : "r" (value))
424 
425 #define x86_read_cr2() ({ \
426 	size_t _v; \
427 	__asm__("mov	%%cr2,%0" : "=r" (_v)); \
428 	_v; \
429 })
430 
431 #define x86_read_cr3() ({ \
432 	size_t _v; \
433 	__asm__("mov	%%cr3,%0" : "=r" (_v)); \
434 	_v; \
435 })
436 
437 #define x86_write_cr3(value) \
438 	__asm__("mov	%0,%%cr3" : : "r" (value))
439 
440 #define x86_read_cr4() ({ \
441 	size_t _v; \
442 	__asm__("mov	%%cr4,%0" : "=r" (_v)); \
443 	_v; \
444 })
445 
446 #define x86_write_cr4(value) \
447 	__asm__("mov	%0,%%cr4" : : "r" (value))
448 
449 #define x86_read_dr3() ({ \
450 	size_t _v; \
451 	__asm__("mov	%%dr3,%0" : "=r" (_v)); \
452 	_v; \
453 })
454 
455 #define x86_write_dr3(value) \
456 	__asm__("mov	%0,%%dr3" : : "r" (value))
457 
458 #define invalidate_TLB(va) \
459 	__asm__("invlpg (%0)" : : "r" (va))
460 
461 #define wbinvd() \
462 	__asm__("wbinvd")
463 
464 #define out8(value,port) \
465 	__asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port))
466 
467 #define out16(value,port) \
468 	__asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port))
469 
470 #define out32(value,port) \
471 	__asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port))
472 
473 #define in8(port) ({ \
474 	uint8 _v; \
475 	__asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \
476 	_v; \
477 })
478 
479 #define in16(port) ({ \
480 	uint16 _v; \
481 	__asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \
482 	_v; \
483 })
484 
485 #define in32(port) ({ \
486 	uint32 _v; \
487 	__asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \
488 	_v; \
489 })
490 
491 #define out8_p(value,port) \
492 	__asm__ ("outb %%al,%%dx\n" \
493 		"\tjmp 1f\n" \
494 		"1:\tjmp 1f\n" \
495 		"1:" : : "a" (value), "d" (port))
496 
497 #define in8_p(port) ({ \
498 	uint8 _v; \
499 	__asm__ volatile ("inb %%dx,%%al\n" \
500 		"\tjmp 1f\n" \
501 		"1:\tjmp 1f\n" \
502 		"1:" : "=a" (_v) : "d" (port)); \
503 	_v; \
504 })
505 
506 
507 extern void (*gCpuIdleFunc)(void);
508 
509 
510 #ifdef __cplusplus
511 extern "C" {
512 #endif
513 
514 struct arch_thread;
515 
516 #ifdef __x86_64__
517 void __x86_setup_system_time(uint64 conversionFactor,
518 	uint64 conversionFactorNsecs);
519 #else
520 void __x86_setup_system_time(uint32 conversionFactor,
521 	uint32 conversionFactorNsecs, bool conversionFactorNsecsShift);
522 #endif
523 
524 void x86_userspace_thread_exit(void);
525 void x86_end_userspace_thread_exit(void);
526 
527 addr_t x86_get_stack_frame();
528 uint32 x86_count_mtrrs(void);
529 void x86_set_mtrr(uint32 index, uint64 base, uint64 length, uint8 type);
530 status_t x86_get_mtrr(uint32 index, uint64* _base, uint64* _length,
531 	uint8* _type);
532 void x86_set_mtrrs(uint8 defaultType, const x86_mtrr_info* infos,
533 	uint32 count);
534 void x86_init_fpu();
535 bool x86_check_feature(uint32 feature, enum x86_feature_type type);
536 void* x86_get_double_fault_stack(int32 cpu, size_t* _size);
537 int32 x86_double_fault_get_cpu(void);
538 
539 void x86_invalid_exception(iframe* frame);
540 void x86_fatal_exception(iframe* frame);
541 void x86_unexpected_exception(iframe* frame);
542 void x86_hardware_interrupt(iframe* frame);
543 void x86_page_fault_exception(iframe* iframe);
544 
545 #ifndef __x86_64__
546 
547 void x86_swap_pgdir(addr_t newPageDir);
548 
549 uint64 x86_read_msr(uint32 registerNumber);
550 void x86_write_msr(uint32 registerNumber, uint64 value);
551 
552 void x86_context_switch(struct arch_thread* oldState,
553 	struct arch_thread* newState);
554 
555 void x86_fnsave(void* fpuState);
556 void x86_frstor(const void* fpuState);
557 
558 void x86_fxsave(void* fpuState);
559 void x86_fxrstor(const void* fpuState);
560 
561 void x86_noop_swap(void* oldFpuState, const void* newFpuState);
562 void x86_fnsave_swap(void* oldFpuState, const void* newFpuState);
563 void x86_fxsave_swap(void* oldFpuState, const void* newFpuState);
564 
565 #endif
566 
567 
568 static inline void
569 arch_cpu_idle(void)
570 {
571 	gCpuIdleFunc();
572 }
573 
574 
575 static inline void
576 arch_cpu_pause(void)
577 {
578 	asm volatile("pause" : : : "memory");
579 }
580 
581 
582 #ifdef __cplusplus
583 }	// extern "C" {
584 #endif
585 
586 #endif	// !_ASSEMBLER
587 
588 #endif	/* _KERNEL_ARCH_x86_CPU_H */
589