2 * include/asm-x86_64/processor.h
4 * Copyright (C) 1994 Linus Torvalds
7 #ifndef _X86_64_PROCESSOR_H
8 #define _X86_64_PROCESSOR_H
10 #include <arch/segment.h>
11 #include <arch/page.h>
12 #include <arch/types.h>
13 #include <arch/sigcontext.h>
14 #include <arch/cpufeature.h>
15 /* #include <linux/threads.h> */
17 #include <arch/current.h>
18 #include <arch/system.h>
19 /* #include <arch/mmsegment.h> */
20 #include <arch/percpu.h>
21 /* #include <lwk/personality.h> */
22 #include <lwk/cpumask.h>
23 #include <lwk/cache.h>
25 #define TF_MASK 0x00000100
26 #define IF_MASK 0x00000200
27 #define IOPL_MASK 0x00003000
28 #define NT_MASK 0x00004000
29 #define VM_MASK 0x00020000
30 #define AC_MASK 0x00040000
31 #define VIF_MASK 0x00080000 /* virtual interrupt flag */
32 #define VIP_MASK 0x00100000 /* virtual interrupt pending */
33 #define ID_MASK 0x00200000
35 #define desc_empty(desc) \
36 (!((desc)->a | (desc)->b))
38 #define desc_equal(desc1, desc2) \
39 (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
42 * Default implementation of macro that returns current
43 * instruction pointer ("program counter").
45 #define current_text_addr() ({ void *pc; asm volatile("leaq 1f(%%rip),%0\n1:":"=r"(pc)); pc; })
47 #define X86_VENDOR_INTEL 0
48 #define X86_VENDOR_CYRIX 1
49 #define X86_VENDOR_AMD 2
50 #define X86_VENDOR_UMC 3
51 #define X86_VENDOR_NEXGEN 4
52 #define X86_VENDOR_CENTAUR 5
53 #define X86_VENDOR_RISE 6
54 #define X86_VENDOR_TRANSMETA 7
55 #define X86_VENDOR_NUM 8
56 #define X86_VENDOR_UNKNOWN 0xff
58 extern char ignore_irq13;
60 extern void identify_cpu(void);
65 #define X86_EFLAGS_CF 0x00000001 /* Carry Flag */
66 #define X86_EFLAGS_PF 0x00000004 /* Parity Flag */
67 #define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */
68 #define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */
69 #define X86_EFLAGS_SF 0x00000080 /* Sign Flag */
70 #define X86_EFLAGS_TF 0x00000100 /* Trap Flag */
71 #define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */
72 #define X86_EFLAGS_DF 0x00000400 /* Direction Flag */
73 #define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */
74 #define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */
75 #define X86_EFLAGS_NT 0x00004000 /* Nested Task */
76 #define X86_EFLAGS_RF 0x00010000 /* Resume Flag */
77 #define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */
78 #define X86_EFLAGS_AC 0x00040000 /* Alignment Check */
79 #define X86_EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */
80 #define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */
81 #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
84 * Intel CPU features in CR4
86 #define X86_CR4_VME 0x0001 /* enable vm86 extensions */
87 #define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */
88 #define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */
89 #define X86_CR4_DE 0x0008 /* enable debugging extensions */
90 #define X86_CR4_PSE 0x0010 /* enable page size extensions */
91 #define X86_CR4_PAE 0x0020 /* enable physical address extensions */
92 #define X86_CR4_MCE 0x0040 /* Machine check enable */
93 #define X86_CR4_PGE 0x0080 /* enable global pages */
94 #define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */
95 #define X86_CR4_OSFXSR 0x0200 /* enable fast FPU save and restore */
96 #define X86_CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */
99 * Save the cr4 feature set we're using (ie
100 * Pentium 4MB enable and PPro Global page
101 * enable), so that any CPU's that boot up
102 * after us can get the correct flags.
104 extern unsigned long mmu_cr4_features;
106 static inline void set_in_cr4 (unsigned long mask)
108 mmu_cr4_features |= mask;
109 __asm__("movq %%cr4,%%rax\n\t"
116 static inline void clear_in_cr4 (unsigned long mask)
118 mmu_cr4_features &= ~mask;
119 __asm__("movq %%cr4,%%rax\n\t"
130 #define IO_BITMAP_BITS 65536
131 #define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
132 #define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
133 #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
134 #define INVALID_IO_BITMAP_OFFSET 0x8000
136 struct i387_fxsave_struct {
145 u32 st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
146 u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */
148 } __attribute__ ((aligned (16)));
151 struct i387_fxsave_struct fxsave;
166 * The extra 1 is there because the CPU will access an
167 * additional byte beyond the end of the IO permission
168 * bitmap. The extra byte must be all 1 bits, and must
169 * be within the limit. Thus we have:
171 * 128 bytes, the bitmap itself, for ports 0..0x3ff
172 * 8 bytes, for an extra "long" of ~0UL
174 unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
175 } __attribute__((packed)) ____cacheline_aligned;
177 DECLARE_PER_CPU(struct tss_struct,tss);
179 #ifdef CONFIG_X86_VSMP
180 #define ARCH_MIN_TASKALIGN (1 << INTERNODE_CACHE_SHIFT)
181 #define ARCH_MIN_MMSTRUCT_ALIGN (1 << INTERNODE_CACHE_SHIFT)
183 #define ARCH_MIN_TASKALIGN 16
184 #define ARCH_MIN_MMSTRUCT_ALIGN 0
187 struct thread_struct {
190 unsigned long userrsp; /* Copy from PDA */
193 unsigned short es, ds, fsindex, gsindex;
194 /* Hardware debugging registers */
195 unsigned long debugreg0;
196 unsigned long debugreg1;
197 unsigned long debugreg2;
198 unsigned long debugreg3;
199 unsigned long debugreg6;
200 unsigned long debugreg7;
202 unsigned long cr2, trap_no, error_code;
203 /* floating point info */
204 union i387_union i387 __attribute__((aligned(16)));
205 /* IO permissions. the bitmap could be moved into the GDT, that would make
206 switch faster for a limited number of ioperm using tasks. -AK */
208 unsigned long *io_bitmap_ptr;
209 unsigned io_bitmap_max;
210 /* cached TLS descriptors. */
211 u64 tls_array[GDT_ENTRY_TLS_ENTRIES];
212 } __attribute__((aligned(16)));
214 #define BOOTSTRAP_THREAD { \
215 .rsp0 = (unsigned long)&bootstrap_stack + sizeof(bootstrap_stack) \
218 #define BOOTSTRAP_TSS { \
219 .rsp0 = (unsigned long)&bootstrap_stack + sizeof(bootstrap_stack) \
223 { &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
225 #define start_thread(regs,new_rip,new_rsp) do { \
226 asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0)); \
228 (regs)->rip = (new_rip); \
229 (regs)->rsp = (new_rsp); \
230 write_pda(oldrsp, (new_rsp)); \
231 (regs)->cs = __USER_CS; \
232 (regs)->ss = __USER_DS; \
233 (regs)->eflags = 0x200; \
237 #define get_debugreg(var, register) \
238 __asm__("movq %%db" #register ", %0" \
240 #define set_debugreg(value, register) \
241 __asm__("movq %0,%%db" #register \
247 /* Free all resources held by a thread. */
248 extern void release_thread(struct task_struct *);
250 /* Prepare to copy thread state - unlazy all lazy status */
251 extern void prepare_to_copy(struct task_struct *tsk);
254 * create a kernel thread without removing it from tasklists
256 extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
259 * Return saved PC of a blocked thread.
260 * What is this good for? it will be always the scheduler or ret_from_fork.
262 #define thread_saved_pc(t) (*(unsigned long *)((t)->thread.rsp - 8))
264 extern unsigned long get_wchan(struct task_struct *p);
265 #define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.rsp0 - 1)
266 #define KSTK_EIP(tsk) (task_pt_regs(tsk)->rip)
267 #define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */
270 struct microcode_header {
278 unsigned int datasize;
279 unsigned int totalsize;
280 unsigned int reserved[3];
284 struct microcode_header hdr;
285 unsigned int bits[0];
288 typedef struct microcode microcode_t;
289 typedef struct microcode_header microcode_header_t;
291 /* microcode format is extended from prescott processors */
292 struct extended_signature {
298 struct extended_sigtable {
301 unsigned int reserved[3];
302 struct extended_signature sigs[0];
306 #define ASM_NOP1 K8_NOP1
307 #define ASM_NOP2 K8_NOP2
308 #define ASM_NOP3 K8_NOP3
309 #define ASM_NOP4 K8_NOP4
310 #define ASM_NOP5 K8_NOP5
311 #define ASM_NOP6 K8_NOP6
312 #define ASM_NOP7 K8_NOP7
313 #define ASM_NOP8 K8_NOP8
316 #define K8_NOP1 ".byte 0x90\n"
317 #define K8_NOP2 ".byte 0x66,0x90\n"
318 #define K8_NOP3 ".byte 0x66,0x66,0x90\n"
319 #define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n"
320 #define K8_NOP5 K8_NOP3 K8_NOP2
321 #define K8_NOP6 K8_NOP3 K8_NOP3
322 #define K8_NOP7 K8_NOP4 K8_NOP3
323 #define K8_NOP8 K8_NOP4 K8_NOP4
325 #define ASM_NOP_MAX 8
327 /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
328 static inline void rep_nop(void)
330 __asm__ __volatile__("rep;nop": : :"memory");
333 /* Stop speculative execution */
334 static inline void sync_core(void)
337 asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
340 #define cpu_has_fpu 1
342 #define ARCH_HAS_PREFETCH
343 static inline void prefetch(void *x)
345 asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x));
348 #define ARCH_HAS_PREFETCHW 1
349 static inline void prefetchw(void *x)
351 asm volatile("prefetchtw %0" :: "m" (*(unsigned long *)x));
354 #define ARCH_HAS_SPINLOCK_PREFETCH 1
356 #define spin_lock_prefetch(x) prefetchw(x)
358 #define cpu_relax() rep_nop()
360 static inline void serialize_cpu(void)
362 __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
365 static inline void __monitor(const void *eax, unsigned long ecx,
368 /* "monitor %eax,%ecx,%edx;" */
370 ".byte 0x0f,0x01,0xc8;"
371 : :"a" (eax), "c" (ecx), "d"(edx));
374 static inline void __mwait(unsigned long eax, unsigned long ecx)
376 /* "mwait %eax,%ecx;" */
378 ".byte 0x0f,0x01,0xc9;"
379 : :"a" (eax), "c" (ecx));
382 #define stack_current() \
384 struct thread_info *ti; \
385 asm("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK)); \
389 #define cache_line_size() (boot_cpu_data.x86_cache_alignment)
391 extern unsigned long boot_option_idle_override;
392 /* Boot loader type from the setup header */
393 extern int bootloader_type;
395 #define HAVE_ARCH_PICK_MMAP_LAYOUT 1
397 #endif /* _X86_64_PROCESSOR_H */