Import 2.3.18pre1
[davej-history.git] / include / asm-i386 / processor.h
blob99b291d405f5372178aec8059d83cb8ee3f6fc97
1 /*
2 * include/asm-i386/processor.h
4 * Copyright (C) 1994 Linus Torvalds
5 */
7 #ifndef __ASM_I386_PROCESSOR_H
8 #define __ASM_I386_PROCESSOR_H
10 #include <asm/vm86.h>
11 #include <asm/math_emu.h>
12 #include <asm/segment.h>
13 #include <asm/page.h>
14 #include <asm/types.h>
15 #include <linux/threads.h>
18 * Default implementation of macro that returns current
19 * instruction pointer ("program counter").
21 #define current_text_addr() ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; })
24 * CPU type and hardware bug flags. Kept separately for each CPU.
25 * Members of this structure are referenced in head.S, so think twice
26 * before touching them. [mj]
29 struct cpuinfo_x86 {
30 __u8 x86; /* CPU family */
31 __u8 x86_vendor; /* CPU vendor */
32 __u8 x86_model;
33 __u8 x86_mask;
34 char wp_works_ok; /* It doesn't on 386's */
35 char hlt_works_ok; /* Problems on some 486Dx4's and old 386's */
36 char hard_math;
37 char rfu;
38 int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */
39 __u32 x86_capability;
40 char x86_vendor_id[16];
41 char x86_model_id[64];
42 int x86_cache_size; /* in KB - valid for CPUS which support this
43 call */
44 int fdiv_bug;
45 int f00f_bug;
46 int coma_bug;
47 unsigned long loops_per_sec;
48 unsigned long *pgd_quick;
49 unsigned long *pte_quick;
50 unsigned long pgtable_cache_sz;
53 #define X86_VENDOR_INTEL 0
54 #define X86_VENDOR_CYRIX 1
55 #define X86_VENDOR_AMD 2
56 #define X86_VENDOR_UMC 3
57 #define X86_VENDOR_NEXGEN 4
58 #define X86_VENDOR_CENTAUR 5
59 #define X86_VENDOR_UNKNOWN 0xff
62 * capabilities of CPUs
65 #define X86_FEATURE_FPU 0x00000001 /* onboard FPU */
66 #define X86_FEATURE_VME 0x00000002 /* Virtual Mode Extensions */
67 #define X86_FEATURE_DE 0x00000004 /* Debugging Extensions */
68 #define X86_FEATURE_PSE 0x00000008 /* Page Size Extensions */
69 #define X86_FEATURE_TSC 0x00000010 /* Time Stamp Counter */
70 #define X86_FEATURE_MSR 0x00000020 /* Model-Specific Registers, RDMSR, WRMSR */
71 #define X86_FEATURE_PAE 0x00000040 /* Physical Address Extensions */
72 #define X86_FEATURE_MCE 0x00000080 /* Machine Check Exceptions */
73 #define X86_FEATURE_CX8 0x00000100 /* CMPXCHG8 instruction */
74 #define X86_FEATURE_APIC 0x00000200 /* onboard APIC */
75 #define X86_FEATURE_10 0x00000400
76 #define X86_FEATURE_SEP 0x00000800 /* Fast System Call */
77 #define X86_FEATURE_MTRR 0x00001000 /* Memory Type Range Registers */
78 #define X86_FEATURE_PGE 0x00002000 /* Page Global Enable */
79 #define X86_FEATURE_MCA 0x00004000 /* Machine Check Architecture */
80 #define X86_FEATURE_CMOV 0x00008000 /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
81 #define X86_FEATURE_PAT 0x00010000 /* Page Attribute Table */
82 #define X86_FEATURE_PSE36 0x00020000 /* 36-bit PSEs */
83 #define X86_FEATURE_18 0x00040000
84 #define X86_FEATURE_19 0x00080000
85 #define X86_FEATURE_20 0x00100000
86 #define X86_FEATURE_21 0x00200000
87 #define X86_FEATURE_22 0x00400000
88 #define X86_FEATURE_MMX 0x00800000 /* multimedia extensions */
89 #define X86_FEATURE_FXSR 0x01000000 /* FXSAVE and FXRSTOR instructions (fast save and restore of FPU context), and CR4.OSFXSR (OS uses these instructions) available */
90 #define X86_FEATURE_25 0x02000000
91 #define X86_FEATURE_26 0x04000000
92 #define X86_FEATURE_27 0x08000000
93 #define X86_FEATURE_28 0x10000000
94 #define X86_FEATURE_29 0x20000000
95 #define X86_FEATURE_30 0x40000000
96 #define X86_FEATURE_AMD3D 0x80000000
98 extern struct cpuinfo_x86 boot_cpu_data;
99 extern struct tss_struct init_tss[NR_CPUS];
101 #ifdef __SMP__
102 extern struct cpuinfo_x86 cpu_data[];
103 #define current_cpu_data cpu_data[smp_processor_id()]
104 #else
105 #define cpu_data &boot_cpu_data
106 #define current_cpu_data boot_cpu_data
107 #endif
109 extern char ignore_irq13;
111 extern void identify_cpu(struct cpuinfo_x86 *);
112 extern void print_cpu_info(struct cpuinfo_x86 *);
113 extern void dodgy_tsc(void);
116 * Generic CPUID function
118 extern inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
120 __asm__("cpuid"
121 : "=a" (*eax),
122 "=b" (*ebx),
123 "=c" (*ecx),
124 "=d" (*edx)
125 : "a" (op)
126 : "cc");
131 * Intel CPU features in CR4
133 #define X86_CR4_VME 0x0001 /* enable vm86 extensions */
134 #define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */
135 #define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */
136 #define X86_CR4_DE 0x0008 /* enable debugging extensions */
137 #define X86_CR4_PSE 0x0010 /* enable page size extensions */
138 #define X86_CR4_PAE 0x0020 /* enable physical address extensions */
139 #define X86_CR4_MCE 0x0040 /* Machine check enable */
140 #define X86_CR4_PGE 0x0080 /* enable global pages */
141 #define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */
144 * Save the cr4 feature set we're using (ie
145 * Pentium 4MB enable and PPro Global page
146 * enable), so that any CPU's that boot up
147 * after us can get the correct flags.
149 extern unsigned long mmu_cr4_features;
151 static inline void set_in_cr4 (unsigned long mask)
153 mmu_cr4_features |= mask;
154 __asm__("movl %%cr4,%%eax\n\t"
155 "orl %0,%%eax\n\t"
156 "movl %%eax,%%cr4\n"
157 : : "irg" (mask)
158 :"ax");
161 static inline void clear_in_cr4 (unsigned long mask)
163 mmu_cr4_features &= ~mask;
164 __asm__("movl %%cr4,%%eax\n\t"
165 "andl %0,%%eax\n\t"
166 "movl %%eax,%%cr4\n"
167 : : "irg" (~mask)
168 :"ax");
172 * Cyrix CPU configuration register indexes
174 #define CX86_CCR0 0xc0
175 #define CX86_CCR1 0xc1
176 #define CX86_CCR2 0xc2
177 #define CX86_CCR3 0xc3
178 #define CX86_CCR4 0xe8
179 #define CX86_CCR5 0xe9
180 #define CX86_CCR6 0xea
181 #define CX86_DIR0 0xfe
182 #define CX86_DIR1 0xff
183 #define CX86_ARR_BASE 0xc4
184 #define CX86_RCR_BASE 0xdc
187 * Cyrix CPU indexed register access macros
190 #define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
192 #define setCx86(reg, data) do { \
193 outb((reg), 0x22); \
194 outb((data), 0x23); \
195 } while (0)
198 * Bus types (default is ISA, but people can check others with these..)
200 extern int EISA_bus;
201 extern int MCA_bus;
203 /* from system description table in BIOS. Mostly for MCA use, but
204 others may find it useful. */
205 extern unsigned int machine_id;
206 extern unsigned int machine_submodel_id;
207 extern unsigned int BIOS_revision;
208 extern unsigned int mca_pentium_flag;
211 * User space process size: 3GB (default).
213 #define TASK_SIZE (PAGE_OFFSET)
215 /* This decides where the kernel will search for a free chunk of vm
216 * space during mmap's.
218 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
221 * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
223 #define IO_BITMAP_SIZE 32
224 #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
225 #define INVALID_IO_BITMAP_OFFSET 0x8000
227 struct i387_hard_struct {
228 long cwd;
229 long swd;
230 long twd;
231 long fip;
232 long fcs;
233 long foo;
234 long fos;
235 long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
236 long status; /* software status information */
239 struct i387_soft_struct {
240 long cwd;
241 long swd;
242 long twd;
243 long fip;
244 long fcs;
245 long foo;
246 long fos;
247 long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
248 unsigned char ftop, changed, lookahead, no_update, rm, alimit;
249 struct info *info;
250 unsigned long entry_eip;
253 union i387_union {
254 struct i387_hard_struct hard;
255 struct i387_soft_struct soft;
258 typedef struct {
259 unsigned long seg;
260 } mm_segment_t;
262 struct tss_struct {
263 unsigned short back_link,__blh;
264 unsigned long esp0;
265 unsigned short ss0,__ss0h;
266 unsigned long esp1;
267 unsigned short ss1,__ss1h;
268 unsigned long esp2;
269 unsigned short ss2,__ss2h;
270 unsigned long __cr3;
271 unsigned long eip;
272 unsigned long eflags;
273 unsigned long eax,ecx,edx,ebx;
274 unsigned long esp;
275 unsigned long ebp;
276 unsigned long esi;
277 unsigned long edi;
278 unsigned short es, __esh;
279 unsigned short cs, __csh;
280 unsigned short ss, __ssh;
281 unsigned short ds, __dsh;
282 unsigned short fs, __fsh;
283 unsigned short gs, __gsh;
284 unsigned short ldt, __ldth;
285 unsigned short trace, bitmap;
286 unsigned long io_bitmap[IO_BITMAP_SIZE+1];
288 * pads the TSS to be cacheline-aligned (size is 0x100)
290 unsigned long __cacheline_filler[5];
293 struct thread_struct {
294 unsigned long esp0;
295 unsigned long eip;
296 unsigned long esp;
297 unsigned long fs;
298 unsigned long gs;
299 /* Hardware debugging registers */
300 unsigned long debugreg[8]; /* %%db0-7 debug registers */
301 /* fault info */
302 unsigned long cr2, trap_no, error_code;
303 /* floating point info */
304 union i387_union i387;
305 /* virtual 86 mode info */
306 struct vm86_struct * vm86_info;
307 unsigned long screen_bitmap;
308 unsigned long v86flags, v86mask, v86mode, saved_esp0;
309 /* IO permissions */
310 int ioperm;
311 unsigned long io_bitmap[IO_BITMAP_SIZE+1];
314 #define INIT_THREAD { \
315 0, \
316 0, 0, 0, 0, \
317 { [0 ... 7] = 0 }, /* debugging registers */ \
318 0, 0, 0, \
319 { { 0, }, }, /* 387 state */ \
320 0,0,0,0,0,0, \
321 0,{~0,} /* io permissions */ \
324 #define INIT_MMAP \
325 { &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
327 #define INIT_TSS { \
328 0,0, /* back_link, __blh */ \
329 sizeof(init_stack) + (long) &init_stack, /* esp0 */ \
330 __KERNEL_DS, 0, /* ss0 */ \
331 0,0,0,0,0,0, /* stack1, stack2 */ \
332 0, /* cr3 */ \
333 0,0, /* eip,eflags */ \
334 0,0,0,0, /* eax,ecx,edx,ebx */ \
335 0,0,0,0, /* esp,ebp,esi,edi */ \
336 0,0,0,0,0,0, /* es,cs,ss */ \
337 0,0,0,0,0,0, /* ds,fs,gs */ \
338 __LDT(0),0, /* ldt */ \
339 0, INVALID_IO_BITMAP_OFFSET, /* tace, bitmap */ \
340 {~0, } /* ioperm */ \
343 #define start_thread(regs, new_eip, new_esp) do { \
344 __asm__("movl %w0,%%fs ; movl %w0,%%gs": :"r" (0)); \
345 set_fs(USER_DS); \
346 regs->xds = __USER_DS; \
347 regs->xes = __USER_DS; \
348 regs->xss = __USER_DS; \
349 regs->xcs = __USER_CS; \
350 regs->eip = new_eip; \
351 regs->esp = new_esp; \
352 } while (0)
354 /* Forward declaration, a strange C thing */
355 struct task_struct;
356 struct mm_struct;
358 /* Free all resources held by a thread. */
359 extern void release_thread(struct task_struct *);
361 * create a kernel thread without removing it from tasklists
363 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
365 /* Copy and release all segment info associated with a VM */
366 extern void copy_segments(struct task_struct *p, struct mm_struct * mm);
367 extern void release_segments(struct mm_struct * mm);
368 extern void forget_segments(void);
371 * FPU lazy state save handling..
373 #define save_fpu(tsk) do { \
374 asm volatile("fnsave %0\n\tfwait":"=m" (tsk->thread.i387)); \
375 tsk->flags &= ~PF_USEDFPU; \
376 stts(); \
377 } while (0)
379 #define unlazy_fpu(tsk) do { \
380 if (tsk->flags & PF_USEDFPU) \
381 save_fpu(tsk); \
382 } while (0)
384 #define clear_fpu(tsk) do { \
385 if (tsk->flags & PF_USEDFPU) { \
386 tsk->flags &= ~PF_USEDFPU; \
387 stts(); \
389 } while (0)
392 * Return saved PC of a blocked thread.
394 extern inline unsigned long thread_saved_pc(struct thread_struct *t)
396 return ((unsigned long *)t->esp)[3];
399 #define THREAD_SIZE (2*PAGE_SIZE)
400 extern struct task_struct * alloc_task_struct(void);
401 extern void free_task_struct(struct task_struct *);
403 #define init_task (init_task_union.task)
404 #define init_stack (init_task_union.stack)
406 #endif /* __ASM_I386_PROCESSOR_H */