xref: /haiku/headers/private/kernel/arch/x86/arch_cpu.h (revision e5d65858f2361fe0552495b61620c84dcee6bc00)
1 /*
2  * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
3  * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
4  * Distributed under the terms of the MIT License.
5  *
6  * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
7  * Distributed under the terms of the NewOS License.
8  */
9 #ifndef _KERNEL_ARCH_x86_CPU_H
10 #define _KERNEL_ARCH_x86_CPU_H
11 
12 
13 #ifndef _ASSEMBLER
14 
15 #include <module.h>
16 #include <arch/x86/descriptors.h>
17 
18 #ifdef __x86_64__
19 #	include <arch/x86/64/iframe.h>
20 #else
21 #	include <arch/x86/32/iframe.h>
22 #endif
23 
24 #endif	// !_ASSEMBLER
25 
26 
27 // MSR registers (possibly Intel specific)
28 #define IA32_MSR_TSC					0x10
29 #define IA32_MSR_APIC_BASE				0x1b
30 
31 #define IA32_MSR_MTRR_CAPABILITIES		0xfe
32 #define IA32_MSR_SYSENTER_CS			0x174
33 #define IA32_MSR_SYSENTER_ESP			0x175
34 #define IA32_MSR_SYSENTER_EIP			0x176
35 #define IA32_MSR_ENERGY_PERF_BIAS		0x1b0
36 #define IA32_MSR_MTRR_DEFAULT_TYPE		0x2ff
37 #define IA32_MSR_MTRR_PHYSICAL_BASE_0	0x200
38 #define IA32_MSR_MTRR_PHYSICAL_MASK_0	0x201
39 
40 #define IA32_MSR_EFER					0xc0000080
41 
42 // MSR EFER bits
43 // reference
44 #define IA32_MSR_EFER_SYSCALL			(1 << 0)
45 #define IA32_MSR_EFER_NX				(1 << 11)
46 
47 // x86_64 MSRs.
48 #define IA32_MSR_STAR					0xc0000081
49 #define IA32_MSR_LSTAR					0xc0000082
50 #define IA32_MSR_FMASK					0xc0000084
51 #define IA32_MSR_FS_BASE				0xc0000100
52 #define IA32_MSR_GS_BASE				0xc0000101
53 #define IA32_MSR_KERNEL_GS_BASE			0xc0000102
54 
55 // K8 MSR registers
56 #define K8_MSR_IPM						0xc0010055
57 
58 // x86 features from cpuid eax 1, edx register
59 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-5)
60 #define IA32_FEATURE_FPU	(1 << 0) // x87 fpu
61 #define IA32_FEATURE_VME	(1 << 1) // virtual 8086
62 #define IA32_FEATURE_DE		(1 << 2) // debugging extensions
63 #define IA32_FEATURE_PSE	(1 << 3) // page size extensions
64 #define IA32_FEATURE_TSC	(1 << 4) // rdtsc instruction
65 #define IA32_FEATURE_MSR	(1 << 5) // rdmsr/wrmsr instruction
66 #define IA32_FEATURE_PAE	(1 << 6) // extended 3 level page table addressing
67 #define IA32_FEATURE_MCE	(1 << 7) // machine check exception
68 #define IA32_FEATURE_CX8	(1 << 8) // cmpxchg8b instruction
69 #define IA32_FEATURE_APIC	(1 << 9) // local apic on chip
70 //							(1 << 10) // Reserved
71 #define IA32_FEATURE_SEP	(1 << 11) // SYSENTER/SYSEXIT
72 #define IA32_FEATURE_MTRR	(1 << 12) // MTRR
73 #define IA32_FEATURE_PGE	(1 << 13) // paging global bit
74 #define IA32_FEATURE_MCA	(1 << 14) // machine check architecture
75 #define IA32_FEATURE_CMOV	(1 << 15) // cmov instruction
76 #define IA32_FEATURE_PAT	(1 << 16) // page attribute table
77 #define IA32_FEATURE_PSE36	(1 << 17) // page size extensions with 4MB pages
78 #define IA32_FEATURE_PSN	(1 << 18) // processor serial number
79 #define IA32_FEATURE_CLFSH	(1 << 19) // cflush instruction
80 //							(1 << 20) // Reserved
81 #define IA32_FEATURE_DS		(1 << 21) // debug store
82 #define IA32_FEATURE_ACPI	(1 << 22) // thermal monitor and clock ctrl
83 #define IA32_FEATURE_MMX	(1 << 23) // mmx instructions
84 #define IA32_FEATURE_FXSR	(1 << 24) // FXSAVE/FXRSTOR instruction
85 #define IA32_FEATURE_SSE	(1 << 25) // SSE
86 #define IA32_FEATURE_SSE2	(1 << 26) // SSE2
87 #define IA32_FEATURE_SS		(1 << 27) // self snoop
88 #define IA32_FEATURE_HTT	(1 << 28) // hyperthreading
89 #define IA32_FEATURE_TM		(1 << 29) // thermal monitor
90 #define IA32_FEATURE_IA64	(1 << 30) // IA64 processor emulating x86
91 #define IA32_FEATURE_PBE	(1 << 31) // pending break enable
92 
93 // x86 features from cpuid eax 1, ecx register
94 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-4)
95 #define IA32_FEATURE_EXT_SSE3		(1 << 0) // SSE3
96 #define IA32_FEATURE_EXT_PCLMULQDQ	(1 << 1) // PCLMULQDQ Instruction
97 #define IA32_FEATURE_EXT_DTES64		(1 << 2) // 64-Bit Debug Store
98 #define IA32_FEATURE_EXT_MONITOR	(1 << 3) // MONITOR/MWAIT
99 #define IA32_FEATURE_EXT_DSCPL		(1 << 4) // CPL qualified debug store
100 #define IA32_FEATURE_EXT_VMX		(1 << 5) // Virtual Machine Extensions
101 #define IA32_FEATURE_EXT_SMX		(1 << 6) // Safer Mode Extensions
102 #define IA32_FEATURE_EXT_EST		(1 << 7) // Enhanced SpeedStep
103 #define IA32_FEATURE_EXT_TM2		(1 << 8) // Thermal Monitor 2
104 #define IA32_FEATURE_EXT_SSSE3		(1 << 9) // Supplemental SSE-3
105 #define IA32_FEATURE_EXT_CNXTID		(1 << 10) // L1 Context ID
106 //									(1 << 11) // Reserved
107 #define IA32_FEATURE_EXT_FMA		(1 << 12) // Fused Multiply Add
108 #define IA32_FEATURE_EXT_CX16		(1 << 13) // CMPXCHG16B
109 #define IA32_FEATURE_EXT_XTPR		(1 << 14) // xTPR Update Control
110 #define IA32_FEATURE_EXT_PDCM		(1 << 15) // Perfmon and Debug Capability
111 //									(1 << 16) // Reserved
112 #define IA32_FEATURE_EXT_PCID		(1 << 17) // Process Context Identifiers
113 #define IA32_FEATURE_EXT_DCA		(1 << 18) // Direct Cache Access
114 #define IA32_FEATURE_EXT_SSE4_1		(1 << 19) // SSE4.1
115 #define IA32_FEATURE_EXT_SSE4_2		(1 << 20) // SSE4.2
116 #define IA32_FEATURE_EXT_X2APIC		(1 << 21) // Extended xAPIC Support
117 #define IA32_FEATURE_EXT_MOVBE 		(1 << 22) // MOVBE Instruction
118 #define IA32_FEATURE_EXT_POPCNT		(1 << 23) // POPCNT Instruction
119 #define IA32_FEATURE_EXT_TSCDEADLINE (1 << 24) // Time Stamp Counter Deadline
120 #define IA32_FEATURE_EXT_AES		(1 << 25) // AES Instruction Extensions
121 #define IA32_FEATURE_EXT_XSAVE		(1 << 26) // XSAVE/XSTOR States
122 #define IA32_FEATURE_EXT_OSXSAVE	(1 << 27) // OS-Enabled XSAVE
123 #define IA32_FEATURE_EXT_AVX		(1 << 28) // Advanced Vector Extensions
124 #define IA32_FEATURE_EXT_F16C		(1 << 29) // 16-bit FP conversion
125 #define IA32_FEATURE_EXT_RDRND		(1 << 30) // RDRAND instruction
126 #define IA32_FEATURE_EXT_HYPERVISOR	(1 << 31) // Running on a hypervisor
127 
128 // x86 features from cpuid eax 0x80000001, edx register (AMD)
129 // only care about the ones that are unique to this register
130 #define IA32_FEATURE_AMD_EXT_SYSCALL	(1 << 11) // SYSCALL/SYSRET
131 #define IA32_FEATURE_AMD_EXT_NX			(1 << 20) // no execute bit
132 #define IA32_FEATURE_AMD_EXT_MMXEXT		(1 << 22) // mmx extensions
133 #define IA32_FEATURE_AMD_EXT_FFXSR		(1 << 25) // fast FXSAVE/FXRSTOR
134 #define IA32_FEATURE_AMD_EXT_RDTSCP		(1 << 27) // rdtscp instruction
135 #define IA32_FEATURE_AMD_EXT_LONG		(1 << 29) // long mode
136 #define IA32_FEATURE_AMD_EXT_3DNOWEXT	(1 << 30) // 3DNow! extensions
137 #define IA32_FEATURE_AMD_EXT_3DNOW		(1 << 31) // 3DNow!
138 
139 // some of the features from cpuid eax 0x80000001, edx register (AMD) are also
140 // available on Intel processors
141 #define IA32_FEATURES_INTEL_EXT			(IA32_FEATURE_AMD_EXT_SYSCALL		\
142 											| IA32_FEATURE_AMD_EXT_NX		\
143 											| IA32_FEATURE_AMD_EXT_RDTSCP	\
144 											| IA32_FEATURE_AMD_EXT_LONG)
145 
146 // x86 defined features from cpuid eax 6, eax register
147 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-11)
148 #define IA32_FEATURE_DTS	(1 << 0) //Digital Thermal Sensor
149 #define IA32_FEATURE_ITB	(1 << 1) //Intel Turbo Boost Technology
150 #define IA32_FEATURE_ARAT	(1 << 2) //Always running APIC Timer
151 #define IA32_FEATURE_PLN	(1 << 4) //Power Limit Notification
152 #define IA32_FEATURE_ECMD	(1 << 5) //Extended Clock Modulation Duty
153 #define IA32_FEATURE_PTM	(1 << 6) //Package Thermal Management
154 
155 // x86 defined features from cpuid eax 6, ecx register
156 // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-11)
157 #define IA32_FEATURE_APERFMPERF	(1 << 0) //IA32_APERF, IA32_MPERF
158 #define IA32_FEATURE_EPB	(1 << 3) //IA32_ENERGY_PERF_BIAS
159 
160 // cr4 flags
161 #define IA32_CR4_PAE					(1UL << 5)
162 #define IA32_CR4_GLOBAL_PAGES			(1UL << 7)
163 
164 // Memory type ranges
165 #define IA32_MTR_UNCACHED				0
166 #define IA32_MTR_WRITE_COMBINING		1
167 #define IA32_MTR_WRITE_THROUGH			4
168 #define IA32_MTR_WRITE_PROTECTED		5
169 #define IA32_MTR_WRITE_BACK				6
170 
171 // EFLAGS register
172 #define X86_EFLAGS_CARRY						0x00000001
173 #define X86_EFLAGS_RESERVED1					0x00000002
174 #define X86_EFLAGS_PARITY						0x00000004
175 #define X86_EFLAGS_AUXILIARY_CARRY				0x00000010
176 #define X86_EFLAGS_ZERO							0x00000040
177 #define X86_EFLAGS_SIGN							0x00000080
178 #define X86_EFLAGS_TRAP							0x00000100
179 #define X86_EFLAGS_INTERRUPT					0x00000200
180 #define X86_EFLAGS_DIRECTION					0x00000400
181 #define X86_EFLAGS_OVERFLOW						0x00000800
182 #define X86_EFLAGS_IO_PRIVILEG_LEVEL			0x00003000
183 #define X86_EFLAGS_IO_PRIVILEG_LEVEL_SHIFT		12
184 #define X86_EFLAGS_NESTED_TASK					0x00004000
185 #define X86_EFLAGS_RESUME						0x00010000
186 #define X86_EFLAGS_V86_MODE						0x00020000
187 #define X86_EFLAGS_ALIGNMENT_CHECK				0x00040000
188 #define X86_EFLAGS_VIRTUAL_INTERRUPT			0x00080000
189 #define X86_EFLAGS_VIRTUAL_INTERRUPT_PENDING	0x00100000
190 #define X86_EFLAGS_ID							0x00200000
191 
192 #define X86_EFLAGS_USER_FLAGS	(X86_EFLAGS_CARRY | X86_EFLAGS_PARITY \
193 	| X86_EFLAGS_AUXILIARY_CARRY | X86_EFLAGS_ZERO | X86_EFLAGS_SIGN \
194 	| X86_EFLAGS_DIRECTION | X86_EFLAGS_OVERFLOW)
195 
196 
197 // iframe types
198 #define IFRAME_TYPE_SYSCALL				0x1
199 #define IFRAME_TYPE_OTHER				0x2
200 #define IFRAME_TYPE_MASK				0xf
201 
202 
203 #ifndef _ASSEMBLER
204 
205 
206 struct X86PagingStructures;
207 
208 
209 typedef struct x86_mtrr_info {
210 	uint64	base;
211 	uint64	size;
212 	uint8	type;
213 } x86_mtrr_info;
214 
215 typedef struct x86_optimized_functions {
216 	void 	(*memcpy)(void* dest, const void* source, size_t count);
217 	void*	memcpy_end;
218 	void 	(*memset)(void* dest, int value, size_t count);
219 	void*	memset_end;
220 } x86_optimized_functions;
221 
222 typedef struct x86_cpu_module_info {
223 	module_info	info;
224 	uint32		(*count_mtrrs)(void);
225 	void		(*init_mtrrs)(void);
226 
227 	void		(*set_mtrr)(uint32 index, uint64 base, uint64 length,
228 					uint8 type);
229 	status_t	(*get_mtrr)(uint32 index, uint64* _base, uint64* _length,
230 					uint8* _type);
231 	void		(*set_mtrrs)(uint8 defaultType, const x86_mtrr_info* infos,
232 					uint32 count);
233 
234 	void		(*get_optimized_functions)(x86_optimized_functions* functions);
235 } x86_cpu_module_info;
236 
237 // features
238 enum x86_feature_type {
239 	FEATURE_COMMON = 0,     // cpuid eax=1, ecx register
240 	FEATURE_EXT,            // cpuid eax=1, edx register
241 	FEATURE_EXT_AMD,        // cpuid eax=0x80000001, edx register (AMD)
242 	FEATURE_6_EAX,          // cpuid eax=6, eax registers
243 	FEATURE_6_ECX,          // cpuid eax=6, ecx registers
244 
245 	FEATURE_NUM
246 };
247 
248 enum x86_vendors {
249 	VENDOR_INTEL = 0,
250 	VENDOR_AMD,
251 	VENDOR_CYRIX,
252 	VENDOR_UMC,
253 	VENDOR_NEXGEN,
254 	VENDOR_CENTAUR,
255 	VENDOR_RISE,
256 	VENDOR_TRANSMETA,
257 	VENDOR_NSC,
258 
259 	VENDOR_NUM,
260 	VENDOR_UNKNOWN,
261 };
262 
263 
264 typedef struct arch_cpu_info {
265 	// saved cpu info
266 	enum x86_vendors	vendor;
267 	uint32				feature[FEATURE_NUM];
268 	char				model_name[49];
269 	const char*			vendor_name;
270 	int					type;
271 	int					family;
272 	int					extended_family;
273 	int					stepping;
274 	int					model;
275 	int					extended_model;
276 
277 	struct X86PagingStructures* active_paging_structures;
278 
279 	size_t				dr6;	// temporary storage for debug registers (cf.
280 	size_t				dr7;	// x86_exit_user_debug_at_kernel_entry())
281 
282 	// local TSS for this cpu
283 	struct tss			tss;
284 #ifndef __x86_64__
285 	struct tss			double_fault_tss;
286 #endif
287 } arch_cpu_info;
288 
289 
290 #undef PAUSE
291 #define PAUSE() asm volatile ("pause;")
292 
293 #define nop() __asm__ ("nop"::)
294 
295 #define x86_read_cr0() ({ \
296 	size_t _v; \
297 	__asm__("mov	%%cr0,%0" : "=r" (_v)); \
298 	_v; \
299 })
300 
301 #define x86_write_cr0(value) \
302 	__asm__("mov	%0,%%cr0" : : "r" (value))
303 
304 #define x86_read_cr2() ({ \
305 	size_t _v; \
306 	__asm__("mov	%%cr2,%0" : "=r" (_v)); \
307 	_v; \
308 })
309 
310 #define x86_read_cr3() ({ \
311 	size_t _v; \
312 	__asm__("mov	%%cr3,%0" : "=r" (_v)); \
313 	_v; \
314 })
315 
316 #define x86_write_cr3(value) \
317 	__asm__("mov	%0,%%cr3" : : "r" (value))
318 
319 #define x86_read_cr4() ({ \
320 	size_t _v; \
321 	__asm__("mov	%%cr4,%0" : "=r" (_v)); \
322 	_v; \
323 })
324 
325 #define x86_write_cr4(value) \
326 	__asm__("mov	%0,%%cr4" : : "r" (value))
327 
328 #define x86_read_dr3() ({ \
329 	size_t _v; \
330 	__asm__("mov	%%dr3,%0" : "=r" (_v)); \
331 	_v; \
332 })
333 
334 #define x86_write_dr3(value) \
335 	__asm__("mov	%0,%%dr3" : : "r" (value))
336 
337 #define invalidate_TLB(va) \
338 	__asm__("invlpg (%0)" : : "r" (va))
339 
340 #define wbinvd() \
341 	__asm__("wbinvd")
342 
343 #define out8(value,port) \
344 	__asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port))
345 
346 #define out16(value,port) \
347 	__asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port))
348 
349 #define out32(value,port) \
350 	__asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port))
351 
352 #define in8(port) ({ \
353 	uint8 _v; \
354 	__asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \
355 	_v; \
356 })
357 
358 #define in16(port) ({ \
359 	uint16 _v; \
360 	__asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \
361 	_v; \
362 })
363 
364 #define in32(port) ({ \
365 	uint32 _v; \
366 	__asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \
367 	_v; \
368 })
369 
370 #define out8_p(value,port) \
371 	__asm__ ("outb %%al,%%dx\n" \
372 		"\tjmp 1f\n" \
373 		"1:\tjmp 1f\n" \
374 		"1:" : : "a" (value), "d" (port))
375 
376 #define in8_p(port) ({ \
377 	uint8 _v; \
378 	__asm__ volatile ("inb %%dx,%%al\n" \
379 		"\tjmp 1f\n" \
380 		"1:\tjmp 1f\n" \
381 		"1:" : "=a" (_v) : "d" (port)); \
382 	_v; \
383 })
384 
385 
386 #ifdef __cplusplus
387 extern "C" {
388 #endif
389 
390 struct arch_thread;
391 
392 #ifdef __x86_64__
393 void __x86_setup_system_time(uint64 conversionFactor,
394 	uint64 conversionFactorNsecs);
395 #else
396 void __x86_setup_system_time(uint32 conversionFactor,
397 	uint32 conversionFactorNsecs, bool conversionFactorNsecsShift);
398 #endif
399 
400 void x86_context_switch(struct arch_thread* oldState,
401 	struct arch_thread* newState);
402 void x86_userspace_thread_exit(void);
403 void x86_end_userspace_thread_exit(void);
404 void x86_swap_pgdir(addr_t newPageDir);
405 void x86_fxsave(void* fpuState);
406 void x86_fxrstor(const void* fpuState);
407 void x86_noop_swap(void* oldFpuState, const void* newFpuState);
408 void x86_fxsave_swap(void* oldFpuState, const void* newFpuState);
409 addr_t x86_get_stack_frame();
410 uint64 x86_read_msr(uint32 registerNumber);
411 void x86_write_msr(uint32 registerNumber, uint64 value);
412 uint32 x86_count_mtrrs(void);
413 void x86_set_mtrr(uint32 index, uint64 base, uint64 length, uint8 type);
414 status_t x86_get_mtrr(uint32 index, uint64* _base, uint64* _length,
415 	uint8* _type);
416 void x86_set_mtrrs(uint8 defaultType, const x86_mtrr_info* infos,
417 	uint32 count);
418 void x86_init_fpu();
419 bool x86_check_feature(uint32 feature, enum x86_feature_type type);
420 void* x86_get_double_fault_stack(int32 cpu, size_t* _size);
421 int32 x86_double_fault_get_cpu(void);
422 
423 void x86_invalid_exception(iframe* frame);
424 void x86_fatal_exception(iframe* frame);
425 void x86_unexpected_exception(iframe* frame);
426 void x86_hardware_interrupt(iframe* frame);
427 void x86_page_fault_exception(iframe* iframe);
428 
429 #ifndef __x86_64__
430 
431 void x86_fnsave(void* fpuState);
432 void x86_frstor(const void* fpuState);
433 void x86_fnsave_swap(void* oldFpuState, const void* newFpuState);
434 
435 #endif
436 
437 
438 #ifdef __cplusplus
439 }	// extern "C" {
440 #endif
441 
442 #endif	// !_ASSEMBLER
443 
444 #endif	/* _KERNEL_ARCH_x86_CPU_H */
445