2 * include/asm-i386/processor.h
4 * Copyright (C) 1994 Linus Torvalds
7 #ifndef __ASM_I386_PROCESSOR_H
8 #define __ASM_I386_PROCESSOR_H
11 #include <asm/math_emu.h>
12 #include <asm/segment.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]
30 __u8 x86
; /* CPU family */
31 __u8 x86_vendor
; /* CPU vendor */
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 */
38 int cpuid_level
; /* Maximum supported CPUID level, -1=no CPUID */
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
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
];
102 extern struct cpuinfo_x86 cpu_data
[];
103 #define current_cpu_data cpu_data[smp_processor_id()]
105 #define cpu_data &boot_cpu_data
106 #define current_cpu_data boot_cpu_data
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
)
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"
164 static inline void clear_in_cr4 (unsigned long mask
)
166 mmu_cr4_features
&= ~mask
;
167 __asm__("movl %%cr4,%%eax\n\t"
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 { \
197 outb((data), 0x23); \
201 * Bus types (default is ISA, but people can check others with these..)
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
{
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
{
250 long st_space
[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
251 unsigned char ftop
, changed
, lookahead
, no_update
, rm
, alimit
;
253 unsigned long entry_eip
;
257 struct i387_hard_struct hard
;
258 struct i387_soft_struct soft
;
266 unsigned short back_link
,__blh
;
268 unsigned short ss0
,__ss0h
;
270 unsigned short ss1
,__ss1h
;
272 unsigned short ss2
,__ss2h
;
275 unsigned long eflags
;
276 unsigned long eax
,ecx
,edx
,ebx
;
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
{
302 /* Hardware debugging registers */
303 unsigned long debugreg
[8]; /* %%db0-7 debug registers */
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
;
314 unsigned long io_bitmap
[IO_BITMAP_SIZE
+1];
317 #define INIT_THREAD { \
320 { [0 ... 7] = 0 }, /* debugging registers */ \
322 { { 0, }, }, /* 387 state */ \
324 0,{~0,} /* io permissions */ \
328 { &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
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 */ \
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)); \
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; \
357 /* Forward declaration, a strange C thing */
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; \
382 #define unlazy_fpu(tsk) do { \
383 if (tsk->flags & PF_USEDFPU) \
387 #define clear_fpu(tsk) do { \
388 if (tsk->flags & PF_USEDFPU) { \
389 tsk->flags &= ~PF_USEDFPU; \
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 */