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