* add p cc
[mascara-docs.git] / i386 / linux / linux-2.3.21 / include / asm-i386 / processor.h
blob939ca0b31706d3d092d2ca1f95c13c2d626f36a3
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 #define cpu_has_tsc \
110 (cpu_data[smp_processor_id()].x86_capability & X86_FEATURE_TSC)
112 extern char ignore_irq13;
114 extern void identify_cpu(struct cpuinfo_x86 *);
115 extern void print_cpu_info(struct cpuinfo_x86 *);
116 extern void dodgy_tsc(void);
119 * Generic CPUID function
121 extern inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
123 __asm__("cpuid"
124 : "=a" (*eax),
125 "=b" (*ebx),
126 "=c" (*ecx),
127 "=d" (*edx)
128 : "a" (op)
129 : "cc");
134 * Intel CPU features in CR4
136 #define X86_CR4_VME 0x0001 /* enable vm86 extensions */
137 #define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */
138 #define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */
139 #define X86_CR4_DE 0x0008 /* enable debugging extensions */
140 #define X86_CR4_PSE 0x0010 /* enable page size extensions */
141 #define X86_CR4_PAE 0x0020 /* enable physical address extensions */
142 #define X86_CR4_MCE 0x0040 /* Machine check enable */
143 #define X86_CR4_PGE 0x0080 /* enable global pages */
144 #define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */
147 * Save the cr4 feature set we're using (ie
148 * Pentium 4MB enable and PPro Global page
149 * enable), so that any CPU's that boot up
150 * after us can get the correct flags.
152 extern unsigned long mmu_cr4_features;
154 static inline void set_in_cr4 (unsigned long mask)
156 mmu_cr4_features |= mask;
157 __asm__("movl %%cr4,%%eax\n\t"
158 "orl %0,%%eax\n\t"
159 "movl %%eax,%%cr4\n"
160 : : "irg" (mask)
161 :"ax");
164 static inline void clear_in_cr4 (unsigned long mask)
166 mmu_cr4_features &= ~mask;
167 __asm__("movl %%cr4,%%eax\n\t"
168 "andl %0,%%eax\n\t"
169 "movl %%eax,%%cr4\n"
170 : : "irg" (~mask)
171 :"ax");
175 * Cyrix CPU configuration register indexes
177 #define CX86_CCR0 0xc0
178 #define CX86_CCR1 0xc1
179 #define CX86_CCR2 0xc2
180 #define CX86_CCR3 0xc3
181 #define CX86_CCR4 0xe8
182 #define CX86_CCR5 0xe9
183 #define CX86_CCR6 0xea
184 #define CX86_DIR0 0xfe
185 #define CX86_DIR1 0xff
186 #define CX86_ARR_BASE 0xc4
187 #define CX86_RCR_BASE 0xdc
190 * Cyrix CPU indexed register access macros
193 #define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
195 #define setCx86(reg, data) do { \
196 outb((reg), 0x22); \
197 outb((data), 0x23); \
198 } while (0)
201 * Bus types (default is ISA, but people can check others with these..)
203 extern int EISA_bus;
204 extern int MCA_bus;
206 /* from system description table in BIOS. Mostly for MCA use, but
207 others may find it useful. */
208 extern unsigned int machine_id;
209 extern unsigned int machine_submodel_id;
210 extern unsigned int BIOS_revision;
211 extern unsigned int mca_pentium_flag;
214 * User space process size: 3GB (default).
216 #define TASK_SIZE (PAGE_OFFSET)
218 /* This decides where the kernel will search for a free chunk of vm
219 * space during mmap's.
221 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
224 * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
226 #define IO_BITMAP_SIZE 32
227 #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
228 #define INVALID_IO_BITMAP_OFFSET 0x8000
230 struct i387_hard_struct {
231 long cwd;
232 long swd;
233 long twd;
234 long fip;
235 long fcs;
236 long foo;
237 long fos;
238 long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
239 long status; /* software status information */
242 struct i387_soft_struct {
243 long cwd;
244 long swd;
245 long twd;
246 long fip;
247 long fcs;
248 long foo;
249 long fos;
250 long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
251 unsigned char ftop, changed, lookahead, no_update, rm, alimit;
252 struct info *info;
253 unsigned long entry_eip;
256 union i387_union {
257 struct i387_hard_struct hard;
258 struct i387_soft_struct soft;
261 typedef struct {
262 unsigned long seg;
263 } mm_segment_t;
265 struct tss_struct {
266 unsigned short back_link,__blh;
267 unsigned long esp0;
268 unsigned short ss0,__ss0h;
269 unsigned long esp1;
270 unsigned short ss1,__ss1h;
271 unsigned long esp2;
272 unsigned short ss2,__ss2h;
273 unsigned long __cr3;
274 unsigned long eip;
275 unsigned long eflags;
276 unsigned long eax,ecx,edx,ebx;
277 unsigned long esp;
278 unsigned long ebp;
279 unsigned long esi;
280 unsigned long edi;
281 unsigned short es, __esh;
282 unsigned short cs, __csh;
283 unsigned short ss, __ssh;
284 unsigned short ds, __dsh;
285 unsigned short fs, __fsh;
286 unsigned short gs, __gsh;
287 unsigned short ldt, __ldth;
288 unsigned short trace, bitmap;
289 unsigned long io_bitmap[IO_BITMAP_SIZE+1];
291 * pads the TSS to be cacheline-aligned (size is 0x100)
293 unsigned long __cacheline_filler[5];
296 struct thread_struct {
297 unsigned long esp0;
298 unsigned long eip;
299 unsigned long esp;
300 unsigned long fs;
301 unsigned long gs;
302 /* Hardware debugging registers */
303 unsigned long debugreg[8]; /* %%db0-7 debug registers */
304 /* fault info */
305 unsigned long cr2, trap_no, error_code;
306 /* floating point info */
307 union i387_union i387;
308 /* virtual 86 mode info */
309 struct vm86_struct * vm86_info;
310 unsigned long screen_bitmap;
311 unsigned long v86flags, v86mask, v86mode, saved_esp0;
312 /* IO permissions */
313 int ioperm;
314 unsigned long io_bitmap[IO_BITMAP_SIZE+1];
317 #define INIT_THREAD { \
318 0, \
319 0, 0, 0, 0, \
320 { [0 ... 7] = 0 }, /* debugging registers */ \
321 0, 0, 0, \
322 { { 0, }, }, /* 387 state */ \
323 0,0,0,0,0,0, \
324 0,{~0,} /* io permissions */ \
327 #define INIT_MMAP \
328 { &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
330 #define INIT_TSS { \
331 0,0, /* back_link, __blh */ \
332 sizeof(init_stack) + (long) &init_stack, /* esp0 */ \
333 __KERNEL_DS, 0, /* ss0 */ \
334 0,0,0,0,0,0, /* stack1, stack2 */ \
335 0, /* cr3 */ \
336 0,0, /* eip,eflags */ \
337 0,0,0,0, /* eax,ecx,edx,ebx */ \
338 0,0,0,0, /* esp,ebp,esi,edi */ \
339 0,0,0,0,0,0, /* es,cs,ss */ \
340 0,0,0,0,0,0, /* ds,fs,gs */ \
341 __LDT(0),0, /* ldt */ \
342 0, INVALID_IO_BITMAP_OFFSET, /* tace, bitmap */ \
343 {~0, } /* ioperm */ \
346 #define start_thread(regs, new_eip, new_esp) do { \
347 __asm__("movl %w0,%%fs ; movl %w0,%%gs": :"r" (0)); \
348 set_fs(USER_DS); \
349 regs->xds = __USER_DS; \
350 regs->xes = __USER_DS; \
351 regs->xss = __USER_DS; \
352 regs->xcs = __USER_CS; \
353 regs->eip = new_eip; \
354 regs->esp = new_esp; \
355 } while (0)
357 /* Forward declaration, a strange C thing */
358 struct task_struct;
359 struct mm_struct;
361 /* Free all resources held by a thread. */
362 extern void release_thread(struct task_struct *);
364 * create a kernel thread without removing it from tasklists
366 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
368 /* Copy and release all segment info associated with a VM */
369 extern void copy_segments(struct task_struct *p, struct mm_struct * mm);
370 extern void release_segments(struct mm_struct * mm);
371 extern void forget_segments(void);
374 * FPU lazy state save handling..
376 #define save_fpu(tsk) do { \
377 asm volatile("fnsave %0\n\tfwait":"=m" (tsk->thread.i387)); \
378 tsk->flags &= ~PF_USEDFPU; \
379 stts(); \
380 } while (0)
382 #define unlazy_fpu(tsk) do { \
383 if (tsk->flags & PF_USEDFPU) \
384 save_fpu(tsk); \
385 } while (0)
387 #define clear_fpu(tsk) do { \
388 if (tsk->flags & PF_USEDFPU) { \
389 tsk->flags &= ~PF_USEDFPU; \
390 stts(); \
392 } while (0)
395 * Return saved PC of a blocked thread.
397 extern inline unsigned long thread_saved_pc(struct thread_struct *t)
399 return ((unsigned long *)t->esp)[3];
402 #define THREAD_SIZE (2*PAGE_SIZE)
403 extern struct task_struct * alloc_task_struct(void);
404 extern void free_task_struct(struct task_struct *);
406 #define init_task (init_task_union.task)
407 #define init_stack (init_task_union.stack)
409 #endif /* __ASM_I386_PROCESSOR_H */