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