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/arch_cpuasm.h>
22#include <arch/x86/descriptors.h>
23
24#ifdef __x86_64__
25#	include <arch/x86/64/cpu.h>
26#endif
27
28#endif	// !_ASSEMBLER
29
30
31#define CPU_MAX_CACHE_LEVEL	8
32
33#define CACHE_LINE_SIZE		64
34
35
36// MSR registers (possibly Intel specific)
37#define IA32_MSR_TSC					0x10
38#define IA32_MSR_PLATFORM_ID			0x17
39#define IA32_MSR_APIC_BASE				0x1b
40#define IA32_MSR_SPEC_CTRL				0x48
41#define IA32_MSR_PRED_CMD				0x49
42#define IA32_MSR_UCODE_WRITE			0x79	// IA32_BIOS_UPDT_TRIG
43#define IA32_MSR_UCODE_REV				0x8b	// IA32_BIOS_SIGN_ID
44#define IA32_MSR_PLATFORM_INFO			0xce
45#define IA32_MSR_MPERF					0xe7
46#define IA32_MSR_APERF					0xe8
47#define IA32_MSR_MTRR_CAPABILITIES		0xfe
48#define IA32_MSR_ARCH_CAPABILITIES		0x10a
49#define IA32_MSR_FLUSH_CMD				0x10b
50#define IA32_MSR_SYSENTER_CS			0x174
51#define IA32_MSR_SYSENTER_ESP			0x175
52#define IA32_MSR_SYSENTER_EIP			0x176
53#define IA32_MSR_PERF_STATUS			0x198
54#define IA32_MSR_PERF_CTL				0x199
55#define IA32_MSR_TURBO_RATIO_LIMIT		0x1ad
56#define IA32_MSR_ENERGY_PERF_BIAS		0x1b0
57#define IA32_MSR_MTRR_DEFAULT_TYPE		0x2ff
58#define IA32_MSR_MTRR_PHYSICAL_BASE_0	0x200
59#define IA32_MSR_MTRR_PHYSICAL_MASK_0	0x201
60
61// MSR SPEC CTRL bits
62#define IA32_MSR_SPEC_CTRL_IBRS			(1 << 0)
63#define IA32_MSR_SPEC_CTRL_STIBP		(1 << 1)
64#define IA32_MSR_SPEC_CTRL_SSBD			(1 << 2)
65
66// MSR PRED CMD bits
67#define IA32_MSR_PRED_CMD_IBPB			(1 << 0)
68
69// MSR APIC BASE bits
70#define IA32_MSR_APIC_BASE_BSP			0x00000100
71#define IA32_MSR_APIC_BASE_X2APIC		0x00000400
72#define IA32_MSR_APIC_BASE_ENABLED		0x00000800
73#define IA32_MSR_APIC_BASE_ADDRESS		0xfffff000
74
75// MSR EFER bits
76// reference
77#define IA32_MSR_EFER_SYSCALL			(1 << 0)
78#define IA32_MSR_EFER_NX				(1 << 11)
79
80// MSR ARCH CAPABILITIES bits
81#define IA32_MSR_ARCH_CAP_RDCL_NO			(1 << 0)
82#define IA32_MSR_ARCH_CAP_IBRS_ALL			(1 << 1)
83#define IA32_MSR_ARCH_CAP_RSBA				(1 << 2)
84#define IA32_MSR_ARCH_CAP_SKIP_L1D_VMENTRY	(1 << 3)
85#define IA32_MSR_ARCH_CAP_SSB_NO			(1 << 4)
86
87// MSR FLUSH CMD bits
88#define IA32_MSR_L1D_FLUSH			(1 << 1)
89
90// X2APIC MSRs.
91#define IA32_MSR_APIC_ID					0x00000802
92#define IA32_MSR_APIC_VERSION				0x00000803
93#define IA32_MSR_APIC_TASK_PRIORITY			0x00000808
94#define IA32_MSR_APIC_PROCESSOR_PRIORITY	0x0000080a
95#define IA32_MSR_APIC_EOI					0x0000080b
96#define IA32_MSR_APIC_LOGICAL_DEST			0x0000080d
97#define IA32_MSR_APIC_SPURIOUS_INTR_VECTOR	0x0000080f
98#define IA32_MSR_APIC_ERROR_STATUS			0x00000828
99#define IA32_MSR_APIC_INTR_COMMAND			0x00000830
100#define IA32_MSR_APIC_LVT_TIMER				0x00000832
101#define IA32_MSR_APIC_LVT_THERMAL_SENSOR	0x00000833
102#define IA32_MSR_APIC_LVT_PERFMON_COUNTERS	0x00000834
103#define IA32_MSR_APIC_LVT_LINT0				0x00000835
104#define IA32_MSR_APIC_LVT_LINT1				0x00000836
105#define IA32_MSR_APIC_LVT_ERROR				0x00000837
106#define IA32_MSR_APIC_INITIAL_TIMER_COUNT	0x00000838
107#define IA32_MSR_APIC_CURRENT_TIMER_COUNT	0x00000839
108#define IA32_MSR_APIC_TIMER_DIVIDE_CONFIG	0x0000083e
109#define IA32_MSR_APIC_SELF_IPI				0x0000083f
110#define IA32_MSR_XSS						0x00000da0
111
112// x86_64 MSRs.
113#define IA32_MSR_EFER					0xc0000080
114#define IA32_MSR_STAR					0xc0000081
115#define IA32_MSR_LSTAR					0xc0000082
116#define IA32_MSR_CSTAR					0xc0000083
117#define IA32_MSR_FMASK					0xc0000084
118#define IA32_MSR_FS_BASE				0xc0000100
119#define IA32_MSR_GS_BASE				0xc0000101
120#define IA32_MSR_KERNEL_GS_BASE			0xc0000102
121#define IA32_MSR_TSC_AUX				0xc0000103
122
123// AMD MSR registers
124#define MSR_F10H_HWCR						0xc0010015
125#define 	HWCR_TSCFREQSEL					(1 << 24)
126#define MSR_K8_UCODE_UPDATE				0xc0010020
127#define K8_MSR_IPM						0xc0010055
128#define MSR_F10H_PSTATEDEF(x)				(0xc0010064 + (x))
129#define 	PSTATEDEF_EN					(1ULL << 63)
130#define MSR_F10H_DE_CFG					0xc0011029
131#define 	DE_CFG_SERIALIZE_LFENCE			(1 << 1)
132
133#define MSR_AMD_CPPC_CAP1				0xc00102b0
134#define		AMD_CPPC_LOWEST_PERF(x)		((x) & 0xff)
135#define		AMD_CPPC_LOWNONLIN_PERF(x)	((x >> 8) & 0xff)
136#define		AMD_CPPC_NOMINAL_PERF(x)	((x >> 16) & 0xff)
137#define		AMD_CPPC_HIGHEST_PERF(x)	((x >> 24) & 0xff)
138#define MSR_AMD_CPPC_ENABLE				0xc00102b1
139#define MSR_AMD_CPPC_REQ				0xc00102b3
140#define		AMD_CPPC_MAX_PERF(x)		((x) & 0xff)
141#define		AMD_CPPC_MIN_PERF(x)		(((x) & 0xff) << 8)
142#define		AMD_CPPC_DES_PERF(x)		(((x) & 0xff) << 16)
143#define		AMD_CPPC_EPP_PERF(x)		(((x) & 0xff) << 24)
144
145#define		AMD_CPPC_EPP_PERFORMANCE			0x00
146#define		AMD_CPPC_EPP_BALANCE_PERFORMANCE	0x80
147#define		AMD_CPPC_EPP_BALANCE_POWERSAVE		0xbf
148#define		AMD_CPPC_EPP_POWERSAVE				0xff
149#define MSR_AMD_CPPC_STATUS				0xc00102b4
150
151
152// Hardware P-States MSR registers ��14.4.1
153// reference https://software.intel.com/content/dam/develop/public/us/en/documents/253669-sdm-vol-3b.pdf
154#define IA32_MSR_PM_ENABLE				0x00000770
155#define IA32_MSR_HWP_CAPABILITIES		0x00000771
156#define IA32_MSR_HWP_REQUEST_PKG		0x00000772
157#define IA32_MSR_HWP_INTERRUPT			0x00000773
158#define IA32_MSR_HWP_REQUEST			0x00000774
159#define IA32_MSR_HWP_STATUS				0x00000777
160
161// IA32_MSR_HWP_CAPABILITIES bits ��14.4.3
162#define	IA32_HWP_CAPS_HIGHEST_PERFORMANCE(x)	(((x) >> 0) & 0xff)
163#define	IA32_HWP_CAPS_GUARANTEED_PERFORMANCE(x)	(((x) >> 8) & 0xff)
164#define	IA32_HWP_CAPS_EFFICIENT_PERFORMANCE(x)	(((x) >> 16) & 0xff)
165#define	IA32_HWP_CAPS_LOWEST_PERFORMANCE(x)		(((x) >> 24) & 0xff)
166
167// IA32_MSR_HWP_REQUEST bits ��14.4.4.1
168#define	IA32_HWP_REQUEST_MINIMUM_PERFORMANCE			(0xffULL << 0)
169#define	IA32_HWP_REQUEST_MAXIMUM_PERFORMANCE			(0xffULL << 8)
170#define	IA32_HWP_REQUEST_DESIRED_PERFORMANCE			(0xffULL << 16)
171#define	IA32_HWP_REQUEST_ENERGY_PERFORMANCE_PREFERENCE	(0xffULL << 24)
172#define	IA32_HWP_REQUEST_ACTIVITY_WINDOW				(0x3ffULL << 32)
173#define	IA32_HWP_REQUEST_PACKAGE_CONTROL				(1ULL << 42)
174#define	IA32_HWP_REQUEST_ACTIVITY_WINDOW_VALID			(1ULL << 59)
175#define	IA32_HWP_REQUEST_EPP_VALID 						(1ULL << 60)
176#define	IA32_HWP_REQUEST_DESIRED_VALID					(1ULL << 61)
177#define	IA32_HWP_REQUEST_MAXIMUM_VALID					(1ULL << 62)
178#define	IA32_HWP_REQUEST_MINIMUM_VALID					(1ULL << 63)
179
180// x86 features from cpuid eax 1, edx register
181// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-5)
182#define IA32_FEATURE_FPU	(1 << 0) // x87 fpu
183#define IA32_FEATURE_VME	(1 << 1) // virtual 8086
184#define IA32_FEATURE_DE		(1 << 2) // debugging extensions
185#define IA32_FEATURE_PSE	(1 << 3) // page size extensions
186#define IA32_FEATURE_TSC	(1 << 4) // rdtsc instruction
187#define IA32_FEATURE_MSR	(1 << 5) // rdmsr/wrmsr instruction
188#define IA32_FEATURE_PAE	(1 << 6) // extended 3 level page table addressing
189#define IA32_FEATURE_MCE	(1 << 7) // machine check exception
190#define IA32_FEATURE_CX8	(1 << 8) // cmpxchg8b instruction
191#define IA32_FEATURE_APIC	(1 << 9) // local apic on chip
192//							(1 << 10) // Reserved
193#define IA32_FEATURE_SEP	(1 << 11) // SYSENTER/SYSEXIT
194#define IA32_FEATURE_MTRR	(1 << 12) // MTRR
195#define IA32_FEATURE_PGE	(1 << 13) // paging global bit
196#define IA32_FEATURE_MCA	(1 << 14) // machine check architecture
197#define IA32_FEATURE_CMOV	(1 << 15) // cmov instruction
198#define IA32_FEATURE_PAT	(1 << 16) // page attribute table
199#define IA32_FEATURE_PSE36	(1 << 17) // page size extensions with 4MB pages
200#define IA32_FEATURE_PSN	(1 << 18) // processor serial number
201#define IA32_FEATURE_CLFSH	(1 << 19) // cflush instruction
202//							(1 << 20) // Reserved
203#define IA32_FEATURE_DS		(1 << 21) // debug store
204#define IA32_FEATURE_ACPI	(1 << 22) // thermal monitor and clock ctrl
205#define IA32_FEATURE_MMX	(1 << 23) // mmx instructions
206#define IA32_FEATURE_FXSR	(1 << 24) // FXSAVE/FXRSTOR instruction
207#define IA32_FEATURE_SSE	(1 << 25) // SSE
208#define IA32_FEATURE_SSE2	(1 << 26) // SSE2
209#define IA32_FEATURE_SS		(1 << 27) // self snoop
210#define IA32_FEATURE_HTT	(1 << 28) // hyperthreading
211#define IA32_FEATURE_TM		(1 << 29) // thermal monitor
212#define IA32_FEATURE_IA64	(1 << 30) // IA64 processor emulating x86
213#define IA32_FEATURE_PBE	(1 << 31) // pending break enable
214
215// x86 features from cpuid eax 1, ecx register
216// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-4)
217#define IA32_FEATURE_EXT_SSE3		(1 << 0) // SSE3
218#define IA32_FEATURE_EXT_PCLMULQDQ	(1 << 1) // PCLMULQDQ Instruction
219#define IA32_FEATURE_EXT_DTES64		(1 << 2) // 64-Bit Debug Store
220#define IA32_FEATURE_EXT_MONITOR	(1 << 3) // MONITOR/MWAIT
221#define IA32_FEATURE_EXT_DSCPL		(1 << 4) // CPL qualified debug store
222#define IA32_FEATURE_EXT_VMX		(1 << 5) // Virtual Machine Extensions
223#define IA32_FEATURE_EXT_SMX		(1 << 6) // Safer Mode Extensions
224#define IA32_FEATURE_EXT_EST		(1 << 7) // Enhanced SpeedStep
225#define IA32_FEATURE_EXT_TM2		(1 << 8) // Thermal Monitor 2
226#define IA32_FEATURE_EXT_SSSE3		(1 << 9) // Supplemental SSE-3
227#define IA32_FEATURE_EXT_CNXTID		(1 << 10) // L1 Context ID
228//									(1 << 11) // Reserved
229#define IA32_FEATURE_EXT_FMA		(1 << 12) // Fused Multiply Add
230#define IA32_FEATURE_EXT_CX16		(1 << 13) // CMPXCHG16B
231#define IA32_FEATURE_EXT_XTPR		(1 << 14) // xTPR Update Control
232#define IA32_FEATURE_EXT_PDCM		(1 << 15) // Perfmon and Debug Capability
233//									(1 << 16) // Reserved
234#define IA32_FEATURE_EXT_PCID		(1 << 17) // Process Context Identifiers
235#define IA32_FEATURE_EXT_DCA		(1 << 18) // Direct Cache Access
236#define IA32_FEATURE_EXT_SSE4_1		(1 << 19) // SSE4.1
237#define IA32_FEATURE_EXT_SSE4_2		(1 << 20) // SSE4.2
238#define IA32_FEATURE_EXT_X2APIC		(1 << 21) // Extended xAPIC Support
239#define IA32_FEATURE_EXT_MOVBE 		(1 << 22) // MOVBE Instruction
240#define IA32_FEATURE_EXT_POPCNT		(1 << 23) // POPCNT Instruction
241#define IA32_FEATURE_EXT_TSCDEADLINE (1 << 24) // Time Stamp Counter Deadline
242#define IA32_FEATURE_EXT_AES		(1 << 25) // AES Instruction Extensions
243#define IA32_FEATURE_EXT_XSAVE		(1 << 26) // XSAVE/XSTOR States
244#define IA32_FEATURE_EXT_OSXSAVE	(1 << 27) // OS-Enabled XSAVE
245#define IA32_FEATURE_EXT_AVX		(1 << 28) // Advanced Vector Extensions
246#define IA32_FEATURE_EXT_F16C		(1 << 29) // 16-bit FP conversion
247#define IA32_FEATURE_EXT_RDRND		(1 << 30) // RDRAND instruction
248#define IA32_FEATURE_EXT_HYPERVISOR	(1 << 31) // Running on a hypervisor
249
250// x86 features from cpuid eax 0x80000001, ecx register (AMD)
251#define IA32_FEATURE_AMD_EXT_CMPLEGACY	(1 << 1) // Core MP legacy mode
252#define IA32_FEATURE_AMD_EXT_TOPOLOGY	(1 << 22) // Topology extensions
253
254// x86 features from cpuid eax 0x80000001, edx register (AMD)
255// only care about the ones that are unique to this register
256#define IA32_FEATURE_AMD_EXT_SYSCALL	(1 << 11) // SYSCALL/SYSRET
257#define IA32_FEATURE_AMD_EXT_NX			(1 << 20) // no execute bit
258#define IA32_FEATURE_AMD_EXT_MMXEXT		(1 << 22) // mmx extensions
259#define IA32_FEATURE_AMD_EXT_FFXSR		(1 << 25) // fast FXSAVE/FXRSTOR
260#define IA32_FEATURE_AMD_EXT_PDPE1GB	(1 << 26) // Gibibyte pages
261#define IA32_FEATURE_AMD_EXT_RDTSCP		(1 << 27) // rdtscp instruction
262#define IA32_FEATURE_AMD_EXT_LONG		(1 << 29) // long mode
263#define IA32_FEATURE_AMD_EXT_3DNOWEXT	(1 << 30) // 3DNow! extensions
264#define IA32_FEATURE_AMD_EXT_3DNOW		(1 << 31) // 3DNow!
265
266// some of the features from cpuid eax 0x80000001, edx register (AMD) are also
267// available on Intel processors
268#define IA32_FEATURES_INTEL_EXT			(IA32_FEATURE_AMD_EXT_SYSCALL		\
269											| IA32_FEATURE_AMD_EXT_NX		\
270											| IA32_FEATURE_AMD_EXT_PDPE1GB	\
271											| IA32_FEATURE_AMD_EXT_RDTSCP	\
272											| IA32_FEATURE_AMD_EXT_LONG)
273
274// x86 defined features from cpuid eax 5, ecx register
275#define IA32_FEATURE_POWER_MWAIT		(1 << 0)
276#define IA32_FEATURE_INTERRUPT_MWAIT	(1 << 1)
277
278// x86 defined features from cpuid eax 6, eax register
279// reference https://software.intel.com/content/dam/develop/public/us/en/documents/253666-sdm-vol-2a.pdf (Table 3-8)
280#define IA32_FEATURE_DTS	(1 << 0) // Digital Thermal Sensor
281#define IA32_FEATURE_ITB	(1 << 1) // Intel Turbo Boost Technology
282#define IA32_FEATURE_ARAT	(1 << 2) // Always running APIC Timer
283#define IA32_FEATURE_PLN	(1 << 4) // Power Limit Notification
284#define IA32_FEATURE_ECMD	(1 << 5) // Extended Clock Modulation Duty
285#define IA32_FEATURE_PTM	(1 << 6) // Package Thermal Management
286#define IA32_FEATURE_HWP	(1 << 7) // Hardware P-states
287#define IA32_FEATURE_HWP_NOTIFY	(1 << 8) // HWP Notification
288#define IA32_FEATURE_HWP_ACTWIN	(1 << 9) // HWP Activity Window
289#define IA32_FEATURE_HWP_EPP	(1 << 10) // HWP Energy Performance Preference
290#define IA32_FEATURE_HWP_PLR	(1 << 11) // HWP Package Level Request
291#define IA32_FEATURE_HDC	(1 << 13) // Hardware Duty Cycling
292#define IA32_FEATURE_TBMT3	(1 << 14) // Turbo Boost Max Technology 3.0
293#define IA32_FEATURE_HWP_CAP	(1 << 15) // HWP Capabilities
294#define IA32_FEATURE_HWP_PECI	(1 << 16) // HWP PECI override
295#define IA32_FEATURE_HWP_FLEX	(1 << 17) // Flexible HWP
296#define IA32_FEATURE_HWP_FAST	(1 << 18) // Fast access for HWP_REQUEST MSR
297#define IA32_FEATURE_HW_FEEDBACK	(1 << 19) // HW_FEEDBACK*, PACKAGE_THERM*
298#define IA32_FEATURE_HWP_IGNIDL	(1 << 20) // Ignore Idle Logical Processor HWP
299
300// x86 defined features from cpuid eax 6, ecx register
301// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-11)
302#define IA32_FEATURE_APERFMPERF	(1 << 0) // IA32_APERF, IA32_MPERF
303#define IA32_FEATURE_EPB	(1 << 3) // IA32_ENERGY_PERF_BIAS
304
305// x86 features from cpuid eax 7, ebx register
306// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 3-8)
307#define IA32_FEATURE_TSC_ADJUST	(1 << 1) // IA32_TSC_ADJUST MSR supported
308#define IA32_FEATURE_SGX		(1 << 2) // Software Guard Extensions
309#define IA32_FEATURE_BMI1		(1 << 3) // Bit Manipulation Instruction Set 1
310#define IA32_FEATURE_HLE		(1 << 4) // Hardware Lock Elision
311#define IA32_FEATURE_AVX2		(1 << 5) // Advanced Vector Extensions 2
312#define IA32_FEATURE_SMEP		(1 << 7) // Supervisor-Mode Execution Prevention
313#define IA32_FEATURE_BMI2		(1 << 8) // Bit Manipulation Instruction Set 2
314#define IA32_FEATURE_ERMS		(1 << 9) // Enhanced REP MOVSB/STOSB
315#define IA32_FEATURE_INVPCID	(1 << 10) // INVPCID instruction
316#define IA32_FEATURE_RTM		(1 << 11) // Transactional Synchronization Extensions
317#define IA32_FEATURE_CQM		(1 << 12) // Platform Quality of Service Monitoring
318#define IA32_FEATURE_MPX		(1 << 14) // Memory Protection Extensions
319#define IA32_FEATURE_RDT_A		(1 << 15) // Resource Director Technology Allocation
320#define IA32_FEATURE_AVX512F	(1 << 16) // AVX-512 Foundation
321#define IA32_FEATURE_AVX512DQ	(1 << 17) // AVX-512 Doubleword and Quadword Instructions
322#define IA32_FEATURE_RDSEED		(1 << 18) // RDSEED instruction
323#define IA32_FEATURE_ADX		(1 << 19) // ADX (Multi-Precision Add-Carry Instruction Extensions)
324#define IA32_FEATURE_SMAP		(1 << 20) // Supervisor Mode Access Prevention
325#define IA32_FEATURE_AVX512IFMA	(1 << 21) // AVX-512 Integer Fused Multiply-Add Instructions
326#define IA32_FEATURE_PCOMMIT	(1 << 22) // PCOMMIT instruction
327#define IA32_FEATURE_CLFLUSHOPT	(1 << 23) // CLFLUSHOPT instruction
328#define IA32_FEATURE_CLWB		(1 << 24) // CLWB instruction
329#define IA32_FEATURE_INTEL_PT	(1 << 25) // Intel Processor Trace
330#define IA32_FEATURE_AVX512PF	(1 << 26) // AVX-512 Prefetch Instructions
331#define IA32_FEATURE_AVX512ER	(1 << 27) // AVX-512 Exponential and Reciprocal Instructions
332#define IA32_FEATURE_AVX512CD	(1 << 28) // AVX-512 Conflict Detection Instructions
333#define IA32_FEATURE_SHA_NI		(1 << 29) // SHA extensions
334#define IA32_FEATURE_AVX512BW	(1 << 30) // AVX-512 Byte and Word Instructions
335#define IA32_FEATURE_AVX512VI	(1 << 31) // AVX-512 Vector Length Extensions
336
337// x86 features from cpuid eax 7, ecx register
338// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 3-8)
339// https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features
340#define IA32_FEATURE_AVX512VMBI		(1 << 1) // AVX-512 Vector Bit Manipulation Instructions
341#define IA32_FEATURE_UMIP			(1 << 2) // User-mode Instruction Prevention
342#define IA32_FEATURE_PKU			(1 << 3) // Memory Protection Keys for User-mode pages
343#define IA32_FEATURE_OSPKE			(1 << 4) // PKU enabled by OS
344#define IA32_FEATURE_AVX512VMBI2	(1 << 6) // AVX-512 Vector Bit Manipulation Instructions 2
345#define IA32_FEATURE_GFNI			(1 << 8) // Galois Field instructions
346#define IA32_FEATURE_VAES			(1 << 9) // AES instruction set (VEX-256/EVEX)
347#define IA32_FEATURE_VPCLMULQDQ		(1 << 10) // CLMUL instruction set (VEX-256/EVEX)
348#define IA32_FEATURE_AVX512_VNNI	(1 << 11) // AVX-512 Vector Neural Network Instructions
349#define IA32_FEATURE_AVX512_BITALG	(1 << 12) // AVX-512 BITALG instructions
350#define IA32_FEATURE_AVX512_VPOPCNTDQ (1 << 14) // AVX-512 Vector Population Count D/Q
351#define IA32_FEATURE_LA57			(1 << 16) // 5-level page tables
352#define IA32_FEATURE_RDPID			(1 << 22) // RDPID Instruction
353#define IA32_FEATURE_SGX_LC			(1 << 30) // SGX Launch Configuration
354
355// x86 features from cpuid eax 7, edx register
356// https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features
357#define IA32_FEATURE_AVX512_4VNNIW	(1 << 2) // AVX-512 4-register Neural Network Instructions
358#define IA32_FEATURE_AVX512_4FMAPS	(1 << 3) // AVX-512 4-register Multiply Accumulation Single precision
359#define IA32_FEATURE_HYBRID_CPU		(1 << 15)	// CPUs are of several types
360#define IA32_FEATURE_IBRS			(1 << 26)	// IBRS / IBPB Speculation Control
361#define IA32_FEATURE_STIBP			(1 << 27)	// STIBP Speculation Control
362#define IA32_FEATURE_L1D_FLUSH		(1 << 28)	// L1D_FLUSH supported
363#define IA32_FEATURE_ARCH_CAPABILITIES	(1 << 29)	// IA32_ARCH_CAPABILITIES MSR
364#define IA32_FEATURE_SSBD			(1 << 31)	// Speculative Store Bypass Disable
365
366// x86 features from cpuid eax 0xd, ecx 1, eax register
367// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 3-8)
368#define IA32_FEATURE_XSAVEOPT		(1 << 0) // XSAVEOPT Instruction
369#define IA32_FEATURE_XSAVEC			(1 << 1) // XSAVEC and compacted XRSTOR
370#define IA32_FEATURE_XGETBV1		(1 << 2) // XGETBV with ECX=1 Instruction
371#define IA32_FEATURE_XSAVES			(1 << 3) // XSAVES and XRSTORS Instruction
372
373// x86 defined features from cpuid eax 0x80000007, edx register
374#define IA32_FEATURE_INVARIANT_TSC		(1 << 8)
375
376// x86 defined features from cpuid eax 0x80000008, ebx register
377#define IA32_FEATURE_CLZERO			(1 << 0)	// CLZERO instruction
378#define IA32_FEATURE_IBPB			(1 << 12)	// IBPB Support only (no IBRS)
379#define IA32_FEATURE_AMD_SSBD		(1 << 24)	// Speculative Store Bypass Disable
380#define IA32_FEATURE_VIRT_SSBD		(1 << 25)	// Virtualized Speculative Store Bypass Disable
381#define IA32_FEATURE_AMD_SSB_NO		(1 << 26)	// Speculative Store Bypass is fixed in hardware
382#define IA32_FEATURE_CPPC			(1 << 27)	// Collaborative Processor Performance Control
383
384
385// Memory type ranges
386#define IA32_MTR_UNCACHED				0
387#define IA32_MTR_WRITE_COMBINING		1
388#define IA32_MTR_WRITE_THROUGH			4
389#define IA32_MTR_WRITE_PROTECTED		5
390#define IA32_MTR_WRITE_BACK				6
391
392// EFLAGS register
393#define X86_EFLAGS_CARRY						0x00000001
394#define X86_EFLAGS_RESERVED1					0x00000002
395#define X86_EFLAGS_PARITY						0x00000004
396#define X86_EFLAGS_AUXILIARY_CARRY				0x00000010
397#define X86_EFLAGS_ZERO							0x00000040
398#define X86_EFLAGS_SIGN							0x00000080
399#define X86_EFLAGS_TRAP							0x00000100
400#define X86_EFLAGS_INTERRUPT					0x00000200
401#define X86_EFLAGS_DIRECTION					0x00000400
402#define X86_EFLAGS_OVERFLOW						0x00000800
403#define X86_EFLAGS_IO_PRIVILEG_LEVEL			0x00003000
404#define X86_EFLAGS_IO_PRIVILEG_LEVEL_SHIFT		12
405#define X86_EFLAGS_NESTED_TASK					0x00004000
406#define X86_EFLAGS_RESUME						0x00010000
407#define X86_EFLAGS_V86_MODE						0x00020000
408#define X86_EFLAGS_ALIGNMENT_CHECK				0x00040000	// also SMAP status
409#define X86_EFLAGS_VIRTUAL_INTERRUPT			0x00080000
410#define X86_EFLAGS_VIRTUAL_INTERRUPT_PENDING	0x00100000
411#define X86_EFLAGS_ID							0x00200000
412
413#define X86_EFLAGS_USER_FLAGS	(X86_EFLAGS_CARRY | X86_EFLAGS_PARITY \
414	| X86_EFLAGS_AUXILIARY_CARRY | X86_EFLAGS_ZERO | X86_EFLAGS_SIGN \
415	| X86_EFLAGS_DIRECTION | X86_EFLAGS_OVERFLOW)
416
417#define CR0_CACHE_DISABLE		(1UL << 30)
418#define CR0_NOT_WRITE_THROUGH	(1UL << 29)
419#define CR0_FPU_EMULATION		(1UL << 2)
420#define CR0_MONITOR_FPU			(1UL << 1)
421
422// Control Register CR4 flags ��2.5
423// https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf
424#define IA32_CR4_VME			(1UL << 0)
425#define IA32_CR4_PVI			(1UL << 1)
426#define IA32_CR4_TSD			(1UL << 2)
427#define IA32_CR4_DE				(1UL << 3)
428#define IA32_CR4_PSE			(1UL << 4)
429#define IA32_CR4_PAE			(1UL << 5)
430#define IA32_CR4_MCE			(1UL << 6)
431#define IA32_CR4_GLOBAL_PAGES	(1UL << 7)
432#define IA32_CR4_PCE			(1UL << 8)
433#define CR4_OS_FXSR				(1UL << 9)
434#define CR4_OS_XMM_EXCEPTION	(1UL << 10)
435#define IA32_CR4_UMIP			(1UL << 11)
436#define IA32_CR4_LA57			(1UL << 12)
437#define IA32_CR4_VMXE			(1UL << 13)
438#define IA32_CR4_SMXE			(1UL << 14)
439#define IA32_CR4_FSGSBASE		(1UL << 16)
440#define IA32_CR4_PCIDE			(1UL << 17)
441#define IA32_CR4_OSXSAVE		(1UL << 18)
442#define IA32_CR4_SMEP			(1UL << 20)
443#define IA32_CR4_SMAP			(1UL << 21)
444#define IA32_CR4_PKE			(1UL << 22)
445
446// Extended Control Register XCR0 flags ��13.3
447// https://software.intel.com/content/dam/develop/public/us/en/documents/253665-sdm-vol-1.pdf
448#define IA32_XCR0_X87			(1UL << 0)
449#define IA32_XCR0_SSE			(1UL << 1)
450#define IA32_XCR0_AVX			(1UL << 2)
451#define IA32_XCR0_BNDREG		(1UL << 3)
452#define IA32_XCR0_BNDCSR		(1UL << 4)
453#define IA32_XCR0_OPMASK		(1UL << 5)
454#define IA32_XCR0_ZMM_HI256		(1UL << 6)
455#define IA32_XCR0_HI16_ZMM		(1UL << 7)
456#define IA32_XCR0_PT			(1UL << 8)
457#define IA32_XCR0_PKRU			(1UL << 9)
458
459// page fault error codes (http://wiki.osdev.org/Page_Fault)
460#define PGFAULT_P						0x01	// Protection violation
461#define PGFAULT_W						0x02	// Write
462#define PGFAULT_U						0x04	// Usermode
463#define PGFAULT_RSVD					0x08	// Reserved bits
464#define PGFAULT_I						0x10	// Instruction fetch
465
466// iframe types
467#define IFRAME_TYPE_SYSCALL				0x1
468#define IFRAME_TYPE_OTHER				0x2
469#define IFRAME_TYPE_MASK				0xf
470
471
472#ifndef _ASSEMBLER
473
474
475struct X86PagingStructures;
476
477
478typedef struct x86_mtrr_info {
479	uint64	base;
480	uint64	size;
481	uint8	type;
482} x86_mtrr_info;
483
484typedef struct x86_cpu_module_info {
485	module_info	info;
486	uint32		(*count_mtrrs)(void);
487	void		(*init_mtrrs)(void);
488
489	void		(*set_mtrr)(uint32 index, uint64 base, uint64 length,
490					uint8 type);
491	status_t	(*get_mtrr)(uint32 index, uint64* _base, uint64* _length,
492					uint8* _type);
493	void		(*set_mtrrs)(uint8 defaultType, const x86_mtrr_info* infos,
494					uint32 count);
495} x86_cpu_module_info;
496
497// features
498enum x86_feature_type {
499	FEATURE_COMMON = 0,     // cpuid eax=1, ecx register
500	FEATURE_EXT,            // cpuid eax=1, edx register
501	FEATURE_EXT_AMD_ECX,	// cpuid eax=0x80000001, ecx register (AMD)
502	FEATURE_EXT_AMD,        // cpuid eax=0x80000001, edx register (AMD)
503	FEATURE_5_ECX,			// cpuid eax=5, ecx register
504	FEATURE_6_EAX,          // cpuid eax=6, eax registers
505	FEATURE_6_ECX,          // cpuid eax=6, ecx registers
506	FEATURE_7_EBX,          // cpuid eax=7, ebx registers
507	FEATURE_7_ECX,          // cpuid eax=7, ecx registers
508	FEATURE_7_EDX,          // cpuid eax=7, edx registers
509	FEATURE_EXT_7_EDX,		// cpuid eax=0x80000007, edx register
510	FEATURE_EXT_8_EBX,		// cpuid eax=0x80000008, ebx register
511	FEATURE_D_1_EAX,		// cpuid eax=0xd, ecx=1, eax register
512
513	FEATURE_NUM
514};
515
516enum x86_vendors {
517	VENDOR_INTEL = 0,
518	VENDOR_AMD,
519	VENDOR_CYRIX,
520	VENDOR_UMC,
521	VENDOR_NEXGEN,
522	VENDOR_CENTAUR,
523	VENDOR_RISE,
524	VENDOR_TRANSMETA,
525	VENDOR_NSC,
526	VENDOR_HYGON,
527
528	VENDOR_NUM,
529	VENDOR_UNKNOWN,
530};
531
532
533typedef struct arch_cpu_info {
534	// saved cpu info
535	enum x86_vendors	vendor;
536	uint32				feature[FEATURE_NUM];
537	char				model_name[49];
538	const char*			vendor_name;
539	int					type;
540	int					family;
541	int					extended_family;
542	int					stepping;
543	int					model;
544	int					extended_model;
545	uint32				patch_level;
546	uint8				hybrid_type;
547
548	uint32				logical_apic_id;
549
550	uint64				mperf_prev;
551	uint64				aperf_prev;
552	bigtime_t			perf_timestamp;
553	uint64				frequency;
554
555	struct X86PagingStructures* active_paging_structures;
556
557	size_t				dr6;	// temporary storage for debug registers (cf.
558	size_t				dr7;	// x86_exit_user_debug_at_kernel_entry())
559
560	// local TSS for this cpu
561	struct tss			tss;
562#ifndef __x86_64__
563	struct tss			double_fault_tss;
564	void*				kernel_tls;
565#endif
566} arch_cpu_info;
567
568
569// Reference Intel SDM Volume 3 9.11 "Microcode Update Facilities"
570// https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf
571// 9.11.1 Table 9-7. Microcode Update Field Definitions
572struct intel_microcode_header {
573	uint32 header_version;
574	uint32 update_revision;
575	uint32 date;
576	uint32 processor_signature;
577	uint32 checksum;
578	uint32 loader_revision;
579	uint32 processor_flags;
580	uint32 data_size;
581	uint32 total_size;
582	uint32 reserved[3];
583};
584
585
586struct intel_microcode_extended_signature_header {
587	uint32 extended_signature_count;
588	uint32 extended_checksum;
589	uint32 reserved[3];
590};
591
592
593struct intel_microcode_extended_signature {
594	uint32 processor_signature;
595	uint32 processor_flags;
596	uint32 checksum;
597};
598
599
600// AMD Microcode structures
601
602struct amd_container_header {
603	uint32 magic;
604};
605
606
607struct amd_section_header {
608	uint32 type;
609	uint32 size;
610};
611
612
613struct amd_equiv_cpu_entry {
614	uint32 installed_cpu;
615	uint32 fixed_errata_mask;
616	uint32 fixed_errata_compare;
617	uint16 equiv_cpu;
618	uint16 res;
619};
620
621
622struct amd_microcode_header {
623	uint32 data_code;
624	uint32 patch_id;
625	uint16 mc_patch_data_id;
626	uint8 mc_patch_data_len;
627	uint8 init_flag;
628	uint32 mc_patch_data_checksum;
629	uint32 nb_dev_id;
630	uint32 sb_dev_id;
631	uint16 processor_rev_id;
632	uint8 nb_rev_id;
633	uint8 sb_rev_id;
634	uint8 bios_api_rev;
635	uint8 reserved1[3];
636	uint32 match_reg[8];
637};
638
639
640extern void (*gCpuIdleFunc)(void);
641
642
643#ifdef __cplusplus
644extern "C" {
645#endif
646
647struct arch_thread;
648
649#ifdef __x86_64__
650void __x86_setup_system_time(uint64 conversionFactor,
651	uint64 conversionFactorNsecs);
652#else
653void __x86_setup_system_time(uint32 conversionFactor,
654	uint32 conversionFactorNsecs, bool conversionFactorNsecsShift);
655#endif
656
657status_t __x86_patch_errata_percpu(int cpu);
658
659void x86_userspace_thread_exit(void);
660void x86_end_userspace_thread_exit(void);
661
662addr_t x86_get_stack_frame();
663uint32 x86_count_mtrrs(void);
664void x86_set_mtrr(uint32 index, uint64 base, uint64 length, uint8 type);
665status_t x86_get_mtrr(uint32 index, uint64* _base, uint64* _length,
666	uint8* _type);
667void x86_set_mtrrs(uint8 defaultType, const x86_mtrr_info* infos,
668	uint32 count);
669void x86_init_fpu();
670bool x86_check_feature(uint32 feature, enum x86_feature_type type);
671void* x86_get_double_fault_stack(int32 cpu, size_t* _size);
672int32 x86_double_fault_get_cpu(void);
673
674void x86_invalid_exception(iframe* frame);
675void x86_fatal_exception(iframe* frame);
676void x86_unexpected_exception(iframe* frame);
677void x86_hardware_interrupt(iframe* frame);
678void x86_page_fault_exception(iframe* iframe);
679
680#ifndef __x86_64__
681
682void x86_swap_pgdir(addr_t newPageDir);
683
684uint64 x86_read_msr(uint32 registerNumber);
685void x86_write_msr(uint32 registerNumber, uint64 value);
686
687void x86_context_switch(struct arch_thread* oldState,
688	struct arch_thread* newState);
689
690void x86_fnsave(void* fpuState);
691void x86_frstor(const void* fpuState);
692
693void x86_fxsave(void* fpuState);
694void x86_fxrstor(const void* fpuState);
695
696void x86_noop_swap(void* oldFpuState, const void* newFpuState);
697void x86_fnsave_swap(void* oldFpuState, const void* newFpuState);
698void x86_fxsave_swap(void* oldFpuState, const void* newFpuState);
699
700#endif
701
702
703static inline void
704arch_cpu_idle(void)
705{
706	gCpuIdleFunc();
707}
708
709
710static inline void
711arch_cpu_pause(void)
712{
713	asm volatile("pause" : : : "memory");
714}
715
716
717#ifdef __cplusplus
718}	// extern "C" {
719#endif
720
721#endif	// !_ASSEMBLER
722
723#endif	/* _KERNEL_ARCH_x86_CPU_H */
724