diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /include/asm-x86_64/processor.h |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'include/asm-x86_64/processor.h')
-rw-r--r-- | include/asm-x86_64/processor.h | 462 |
1 files changed, 462 insertions, 0 deletions
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h new file mode 100644 index 000000000000..45ab74e8f141 --- /dev/null +++ b/include/asm-x86_64/processor.h | |||
@@ -0,0 +1,462 @@ | |||
1 | /* | ||
2 | * include/asm-x86_64/processor.h | ||
3 | * | ||
4 | * Copyright (C) 1994 Linus Torvalds | ||
5 | */ | ||
6 | |||
7 | #ifndef __ASM_X86_64_PROCESSOR_H | ||
8 | #define __ASM_X86_64_PROCESSOR_H | ||
9 | |||
10 | #include <asm/segment.h> | ||
11 | #include <asm/page.h> | ||
12 | #include <asm/types.h> | ||
13 | #include <asm/sigcontext.h> | ||
14 | #include <asm/cpufeature.h> | ||
15 | #include <linux/config.h> | ||
16 | #include <linux/threads.h> | ||
17 | #include <asm/msr.h> | ||
18 | #include <asm/current.h> | ||
19 | #include <asm/system.h> | ||
20 | #include <asm/mmsegment.h> | ||
21 | #include <asm/percpu.h> | ||
22 | #include <linux/personality.h> | ||
23 | |||
24 | #define TF_MASK 0x00000100 | ||
25 | #define IF_MASK 0x00000200 | ||
26 | #define IOPL_MASK 0x00003000 | ||
27 | #define NT_MASK 0x00004000 | ||
28 | #define VM_MASK 0x00020000 | ||
29 | #define AC_MASK 0x00040000 | ||
30 | #define VIF_MASK 0x00080000 /* virtual interrupt flag */ | ||
31 | #define VIP_MASK 0x00100000 /* virtual interrupt pending */ | ||
32 | #define ID_MASK 0x00200000 | ||
33 | |||
34 | #define desc_empty(desc) \ | ||
35 | (!((desc)->a + (desc)->b)) | ||
36 | |||
37 | #define desc_equal(desc1, desc2) \ | ||
38 | (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b)) | ||
39 | |||
40 | /* | ||
41 | * Default implementation of macro that returns current | ||
42 | * instruction pointer ("program counter"). | ||
43 | */ | ||
44 | #define current_text_addr() ({ void *pc; asm volatile("leaq 1f(%%rip),%0\n1:":"=r"(pc)); pc; }) | ||
45 | |||
46 | /* | ||
47 | * CPU type and hardware bug flags. Kept separately for each CPU. | ||
48 | */ | ||
49 | |||
50 | struct cpuinfo_x86 { | ||
51 | __u8 x86; /* CPU family */ | ||
52 | __u8 x86_vendor; /* CPU vendor */ | ||
53 | __u8 x86_model; | ||
54 | __u8 x86_mask; | ||
55 | int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */ | ||
56 | __u32 x86_capability[NCAPINTS]; | ||
57 | char x86_vendor_id[16]; | ||
58 | char x86_model_id[64]; | ||
59 | int x86_cache_size; /* in KB */ | ||
60 | int x86_clflush_size; | ||
61 | int x86_cache_alignment; | ||
62 | int x86_tlbsize; /* number of 4K pages in DTLB/ITLB combined(in pages)*/ | ||
63 | __u8 x86_virt_bits, x86_phys_bits; | ||
64 | __u8 x86_num_cores; | ||
65 | __u8 x86_apicid; | ||
66 | __u32 x86_power; | ||
67 | __u32 x86_cpuid_level; /* Max CPUID function supported */ | ||
68 | unsigned long loops_per_jiffy; | ||
69 | } ____cacheline_aligned; | ||
70 | |||
71 | #define X86_VENDOR_INTEL 0 | ||
72 | #define X86_VENDOR_CYRIX 1 | ||
73 | #define X86_VENDOR_AMD 2 | ||
74 | #define X86_VENDOR_UMC 3 | ||
75 | #define X86_VENDOR_NEXGEN 4 | ||
76 | #define X86_VENDOR_CENTAUR 5 | ||
77 | #define X86_VENDOR_RISE 6 | ||
78 | #define X86_VENDOR_TRANSMETA 7 | ||
79 | #define X86_VENDOR_NUM 8 | ||
80 | #define X86_VENDOR_UNKNOWN 0xff | ||
81 | |||
82 | #ifdef CONFIG_SMP | ||
83 | extern struct cpuinfo_x86 cpu_data[]; | ||
84 | #define current_cpu_data cpu_data[smp_processor_id()] | ||
85 | #else | ||
86 | #define cpu_data (&boot_cpu_data) | ||
87 | #define current_cpu_data boot_cpu_data | ||
88 | #endif | ||
89 | |||
90 | extern char ignore_irq13; | ||
91 | |||
92 | extern void identify_cpu(struct cpuinfo_x86 *); | ||
93 | extern void print_cpu_info(struct cpuinfo_x86 *); | ||
94 | extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); | ||
95 | |||
96 | /* | ||
97 | * EFLAGS bits | ||
98 | */ | ||
99 | #define X86_EFLAGS_CF 0x00000001 /* Carry Flag */ | ||
100 | #define X86_EFLAGS_PF 0x00000004 /* Parity Flag */ | ||
101 | #define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */ | ||
102 | #define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */ | ||
103 | #define X86_EFLAGS_SF 0x00000080 /* Sign Flag */ | ||
104 | #define X86_EFLAGS_TF 0x00000100 /* Trap Flag */ | ||
105 | #define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */ | ||
106 | #define X86_EFLAGS_DF 0x00000400 /* Direction Flag */ | ||
107 | #define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */ | ||
108 | #define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */ | ||
109 | #define X86_EFLAGS_NT 0x00004000 /* Nested Task */ | ||
110 | #define X86_EFLAGS_RF 0x00010000 /* Resume Flag */ | ||
111 | #define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */ | ||
112 | #define X86_EFLAGS_AC 0x00040000 /* Alignment Check */ | ||
113 | #define X86_EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */ | ||
114 | #define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ | ||
115 | #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ | ||
116 | |||
117 | /* | ||
118 | * Intel CPU features in CR4 | ||
119 | */ | ||
120 | #define X86_CR4_VME 0x0001 /* enable vm86 extensions */ | ||
121 | #define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */ | ||
122 | #define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */ | ||
123 | #define X86_CR4_DE 0x0008 /* enable debugging extensions */ | ||
124 | #define X86_CR4_PSE 0x0010 /* enable page size extensions */ | ||
125 | #define X86_CR4_PAE 0x0020 /* enable physical address extensions */ | ||
126 | #define X86_CR4_MCE 0x0040 /* Machine check enable */ | ||
127 | #define X86_CR4_PGE 0x0080 /* enable global pages */ | ||
128 | #define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */ | ||
129 | #define X86_CR4_OSFXSR 0x0200 /* enable fast FPU save and restore */ | ||
130 | #define X86_CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */ | ||
131 | |||
132 | /* | ||
133 | * Save the cr4 feature set we're using (ie | ||
134 | * Pentium 4MB enable and PPro Global page | ||
135 | * enable), so that any CPU's that boot up | ||
136 | * after us can get the correct flags. | ||
137 | */ | ||
138 | extern unsigned long mmu_cr4_features; | ||
139 | |||
140 | static inline void set_in_cr4 (unsigned long mask) | ||
141 | { | ||
142 | mmu_cr4_features |= mask; | ||
143 | __asm__("movq %%cr4,%%rax\n\t" | ||
144 | "orq %0,%%rax\n\t" | ||
145 | "movq %%rax,%%cr4\n" | ||
146 | : : "irg" (mask) | ||
147 | :"ax"); | ||
148 | } | ||
149 | |||
150 | static inline void clear_in_cr4 (unsigned long mask) | ||
151 | { | ||
152 | mmu_cr4_features &= ~mask; | ||
153 | __asm__("movq %%cr4,%%rax\n\t" | ||
154 | "andq %0,%%rax\n\t" | ||
155 | "movq %%rax,%%cr4\n" | ||
156 | : : "irg" (~mask) | ||
157 | :"ax"); | ||
158 | } | ||
159 | |||
160 | |||
161 | /* | ||
162 | * User space process size. 47bits. | ||
163 | */ | ||
164 | #define TASK_SIZE (0x800000000000UL) | ||
165 | |||
166 | /* This decides where the kernel will search for a free chunk of vm | ||
167 | * space during mmap's. | ||
168 | */ | ||
169 | #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000) | ||
170 | #define TASK_UNMAPPED_32 PAGE_ALIGN(IA32_PAGE_OFFSET/3) | ||
171 | #define TASK_UNMAPPED_64 PAGE_ALIGN(TASK_SIZE/3) | ||
172 | #define TASK_UNMAPPED_BASE \ | ||
173 | (test_thread_flag(TIF_IA32) ? TASK_UNMAPPED_32 : TASK_UNMAPPED_64) | ||
174 | |||
175 | /* | ||
176 | * Size of io_bitmap. | ||
177 | */ | ||
178 | #define IO_BITMAP_BITS 65536 | ||
179 | #define IO_BITMAP_BYTES (IO_BITMAP_BITS/8) | ||
180 | #define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long)) | ||
181 | #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap) | ||
182 | #define INVALID_IO_BITMAP_OFFSET 0x8000 | ||
183 | |||
184 | struct i387_fxsave_struct { | ||
185 | u16 cwd; | ||
186 | u16 swd; | ||
187 | u16 twd; | ||
188 | u16 fop; | ||
189 | u64 rip; | ||
190 | u64 rdp; | ||
191 | u32 mxcsr; | ||
192 | u32 mxcsr_mask; | ||
193 | u32 st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ | ||
194 | u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg = 128 bytes */ | ||
195 | u32 padding[24]; | ||
196 | } __attribute__ ((aligned (16))); | ||
197 | |||
198 | union i387_union { | ||
199 | struct i387_fxsave_struct fxsave; | ||
200 | }; | ||
201 | |||
202 | struct tss_struct { | ||
203 | u32 reserved1; | ||
204 | u64 rsp0; | ||
205 | u64 rsp1; | ||
206 | u64 rsp2; | ||
207 | u64 reserved2; | ||
208 | u64 ist[7]; | ||
209 | u32 reserved3; | ||
210 | u32 reserved4; | ||
211 | u16 reserved5; | ||
212 | u16 io_bitmap_base; | ||
213 | /* | ||
214 | * The extra 1 is there because the CPU will access an | ||
215 | * additional byte beyond the end of the IO permission | ||
216 | * bitmap. The extra byte must be all 1 bits, and must | ||
217 | * be within the limit. Thus we have: | ||
218 | * | ||
219 | * 128 bytes, the bitmap itself, for ports 0..0x3ff | ||
220 | * 8 bytes, for an extra "long" of ~0UL | ||
221 | */ | ||
222 | unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; | ||
223 | } __attribute__((packed)) ____cacheline_aligned; | ||
224 | |||
225 | extern struct cpuinfo_x86 boot_cpu_data; | ||
226 | DECLARE_PER_CPU(struct tss_struct,init_tss); | ||
227 | |||
228 | #define ARCH_MIN_TASKALIGN 16 | ||
229 | |||
230 | struct thread_struct { | ||
231 | unsigned long rsp0; | ||
232 | unsigned long rsp; | ||
233 | unsigned long userrsp; /* Copy from PDA */ | ||
234 | unsigned long fs; | ||
235 | unsigned long gs; | ||
236 | unsigned short es, ds, fsindex, gsindex; | ||
237 | /* Hardware debugging registers */ | ||
238 | unsigned long debugreg0; | ||
239 | unsigned long debugreg1; | ||
240 | unsigned long debugreg2; | ||
241 | unsigned long debugreg3; | ||
242 | unsigned long debugreg6; | ||
243 | unsigned long debugreg7; | ||
244 | /* fault info */ | ||
245 | unsigned long cr2, trap_no, error_code; | ||
246 | /* floating point info */ | ||
247 | union i387_union i387 __attribute__((aligned(16))); | ||
248 | /* IO permissions. the bitmap could be moved into the GDT, that would make | ||
249 | switch faster for a limited number of ioperm using tasks. -AK */ | ||
250 | int ioperm; | ||
251 | unsigned long *io_bitmap_ptr; | ||
252 | unsigned io_bitmap_max; | ||
253 | /* cached TLS descriptors. */ | ||
254 | u64 tls_array[GDT_ENTRY_TLS_ENTRIES]; | ||
255 | } __attribute__((aligned(16))); | ||
256 | |||
257 | #define INIT_THREAD {} | ||
258 | |||
259 | #define INIT_MMAP \ | ||
260 | { &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL } | ||
261 | |||
262 | #define STACKFAULT_STACK 1 | ||
263 | #define DOUBLEFAULT_STACK 2 | ||
264 | #define NMI_STACK 3 | ||
265 | #define DEBUG_STACK 4 | ||
266 | #define MCE_STACK 5 | ||
267 | #define N_EXCEPTION_STACKS 5 /* hw limit: 7 */ | ||
268 | #define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) | ||
269 | #define EXCEPTION_STACK_ORDER 0 | ||
270 | |||
271 | #define start_thread(regs,new_rip,new_rsp) do { \ | ||
272 | asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0)); \ | ||
273 | load_gs_index(0); \ | ||
274 | (regs)->rip = (new_rip); \ | ||
275 | (regs)->rsp = (new_rsp); \ | ||
276 | write_pda(oldrsp, (new_rsp)); \ | ||
277 | (regs)->cs = __USER_CS; \ | ||
278 | (regs)->ss = __USER_DS; \ | ||
279 | (regs)->eflags = 0x200; \ | ||
280 | set_fs(USER_DS); \ | ||
281 | } while(0) | ||
282 | |||
283 | struct task_struct; | ||
284 | struct mm_struct; | ||
285 | |||
286 | /* Free all resources held by a thread. */ | ||
287 | extern void release_thread(struct task_struct *); | ||
288 | |||
289 | /* Prepare to copy thread state - unlazy all lazy status */ | ||
290 | extern void prepare_to_copy(struct task_struct *tsk); | ||
291 | |||
292 | /* | ||
293 | * create a kernel thread without removing it from tasklists | ||
294 | */ | ||
295 | extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | ||
296 | |||
297 | /* | ||
298 | * Return saved PC of a blocked thread. | ||
299 | * What is this good for? it will be always the scheduler or ret_from_fork. | ||
300 | */ | ||
301 | #define thread_saved_pc(t) (*(unsigned long *)((t)->thread.rsp - 8)) | ||
302 | |||
303 | extern unsigned long get_wchan(struct task_struct *p); | ||
304 | #define KSTK_EIP(tsk) \ | ||
305 | (((struct pt_regs *)(tsk->thread.rsp0 - sizeof(struct pt_regs)))->rip) | ||
306 | #define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */ | ||
307 | |||
308 | |||
309 | struct microcode_header { | ||
310 | unsigned int hdrver; | ||
311 | unsigned int rev; | ||
312 | unsigned int date; | ||
313 | unsigned int sig; | ||
314 | unsigned int cksum; | ||
315 | unsigned int ldrver; | ||
316 | unsigned int pf; | ||
317 | unsigned int datasize; | ||
318 | unsigned int totalsize; | ||
319 | unsigned int reserved[3]; | ||
320 | }; | ||
321 | |||
322 | struct microcode { | ||
323 | struct microcode_header hdr; | ||
324 | unsigned int bits[0]; | ||
325 | }; | ||
326 | |||
327 | typedef struct microcode microcode_t; | ||
328 | typedef struct microcode_header microcode_header_t; | ||
329 | |||
330 | /* microcode format is extended from prescott processors */ | ||
331 | struct extended_signature { | ||
332 | unsigned int sig; | ||
333 | unsigned int pf; | ||
334 | unsigned int cksum; | ||
335 | }; | ||
336 | |||
337 | struct extended_sigtable { | ||
338 | unsigned int count; | ||
339 | unsigned int cksum; | ||
340 | unsigned int reserved[3]; | ||
341 | struct extended_signature sigs[0]; | ||
342 | }; | ||
343 | |||
344 | /* '6' because it used to be for P6 only (but now covers Pentium 4 as well) */ | ||
345 | #define MICROCODE_IOCFREE _IO('6',0) | ||
346 | |||
347 | |||
348 | #define ASM_NOP1 K8_NOP1 | ||
349 | #define ASM_NOP2 K8_NOP2 | ||
350 | #define ASM_NOP3 K8_NOP3 | ||
351 | #define ASM_NOP4 K8_NOP4 | ||
352 | #define ASM_NOP5 K8_NOP5 | ||
353 | #define ASM_NOP6 K8_NOP6 | ||
354 | #define ASM_NOP7 K8_NOP7 | ||
355 | #define ASM_NOP8 K8_NOP8 | ||
356 | |||
357 | /* Opteron nops */ | ||
358 | #define K8_NOP1 ".byte 0x90\n" | ||
359 | #define K8_NOP2 ".byte 0x66,0x90\n" | ||
360 | #define K8_NOP3 ".byte 0x66,0x66,0x90\n" | ||
361 | #define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n" | ||
362 | #define K8_NOP5 K8_NOP3 K8_NOP2 | ||
363 | #define K8_NOP6 K8_NOP3 K8_NOP3 | ||
364 | #define K8_NOP7 K8_NOP4 K8_NOP3 | ||
365 | #define K8_NOP8 K8_NOP4 K8_NOP4 | ||
366 | |||
367 | #define ASM_NOP_MAX 8 | ||
368 | |||
369 | /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ | ||
370 | extern inline void rep_nop(void) | ||
371 | { | ||
372 | __asm__ __volatile__("rep;nop": : :"memory"); | ||
373 | } | ||
374 | |||
375 | /* Stop speculative execution */ | ||
376 | extern inline void sync_core(void) | ||
377 | { | ||
378 | int tmp; | ||
379 | asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory"); | ||
380 | } | ||
381 | |||
382 | #define cpu_has_fpu 1 | ||
383 | |||
384 | #define ARCH_HAS_PREFETCH | ||
385 | static inline void prefetch(void *x) | ||
386 | { | ||
387 | asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x)); | ||
388 | } | ||
389 | |||
390 | #define ARCH_HAS_PREFETCHW 1 | ||
391 | static inline void prefetchw(void *x) | ||
392 | { | ||
393 | alternative_input(ASM_NOP5, | ||
394 | "prefetchw (%1)", | ||
395 | X86_FEATURE_3DNOW, | ||
396 | "r" (x)); | ||
397 | } | ||
398 | |||
399 | #define ARCH_HAS_SPINLOCK_PREFETCH 1 | ||
400 | |||
401 | #define spin_lock_prefetch(x) prefetchw(x) | ||
402 | |||
403 | #define cpu_relax() rep_nop() | ||
404 | |||
405 | /* | ||
406 | * NSC/Cyrix CPU configuration register indexes | ||
407 | */ | ||
408 | #define CX86_CCR0 0xc0 | ||
409 | #define CX86_CCR1 0xc1 | ||
410 | #define CX86_CCR2 0xc2 | ||
411 | #define CX86_CCR3 0xc3 | ||
412 | #define CX86_CCR4 0xe8 | ||
413 | #define CX86_CCR5 0xe9 | ||
414 | #define CX86_CCR6 0xea | ||
415 | #define CX86_CCR7 0xeb | ||
416 | #define CX86_DIR0 0xfe | ||
417 | #define CX86_DIR1 0xff | ||
418 | #define CX86_ARR_BASE 0xc4 | ||
419 | #define CX86_RCR_BASE 0xdc | ||
420 | |||
421 | /* | ||
422 | * NSC/Cyrix CPU indexed register access macros | ||
423 | */ | ||
424 | |||
425 | #define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); }) | ||
426 | |||
427 | #define setCx86(reg, data) do { \ | ||
428 | outb((reg), 0x22); \ | ||
429 | outb((data), 0x23); \ | ||
430 | } while (0) | ||
431 | |||
432 | static inline void __monitor(const void *eax, unsigned long ecx, | ||
433 | unsigned long edx) | ||
434 | { | ||
435 | /* "monitor %eax,%ecx,%edx;" */ | ||
436 | asm volatile( | ||
437 | ".byte 0x0f,0x01,0xc8;" | ||
438 | : :"a" (eax), "c" (ecx), "d"(edx)); | ||
439 | } | ||
440 | |||
441 | static inline void __mwait(unsigned long eax, unsigned long ecx) | ||
442 | { | ||
443 | /* "mwait %eax,%ecx;" */ | ||
444 | asm volatile( | ||
445 | ".byte 0x0f,0x01,0xc9;" | ||
446 | : :"a" (eax), "c" (ecx)); | ||
447 | } | ||
448 | |||
449 | #define stack_current() \ | ||
450 | ({ \ | ||
451 | struct thread_info *ti; \ | ||
452 | asm("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK)); \ | ||
453 | ti->task; \ | ||
454 | }) | ||
455 | |||
456 | #define cache_line_size() (boot_cpu_data.x86_cache_alignment) | ||
457 | |||
458 | extern unsigned long boot_option_idle_override; | ||
459 | /* Boot loader type from the setup header */ | ||
460 | extern int bootloader_type; | ||
461 | |||
462 | #endif /* __ASM_X86_64_PROCESSOR_H */ | ||