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 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
)
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"
161 static inline void clear_in_cr4 (unsigned long mask
)
163 mmu_cr4_features
&= ~mask
;
164 __asm__("movl %%cr4,%%eax\n\t"
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 { \
194 outb((data), 0x23); \
198 * Bus types (default is ISA, but people can check others with these..)
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
{
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
{
247 long st_space
[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
248 unsigned char ftop
, changed
, lookahead
, no_update
, rm
, alimit
;
250 unsigned long entry_eip
;
254 struct i387_hard_struct hard
;
255 struct i387_soft_struct soft
;
263 unsigned short back_link
,__blh
;
265 unsigned short ss0
,__ss0h
;
267 unsigned short ss1
,__ss1h
;
269 unsigned short ss2
,__ss2h
;
272 unsigned long eflags
;
273 unsigned long eax
,ecx
,edx
,ebx
;
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
{
299 /* Hardware debugging registers */
300 unsigned long debugreg
[8]; /* %%db0-7 debug registers */
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
;
311 unsigned long io_bitmap
[IO_BITMAP_SIZE
+1];
314 #define INIT_THREAD { \
317 { [0 ... 7] = 0 }, /* debugging registers */ \
319 { { 0, }, }, /* 387 state */ \
321 0,{~0,} /* io permissions */ \
325 { &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
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 */ \
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)); \
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; \
354 /* Forward declaration, a strange C thing */
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; \
379 #define unlazy_fpu(tsk) do { \
380 if (tsk->flags & PF_USEDFPU) \
384 #define clear_fpu(tsk) do { \
385 if (tsk->flags & PF_USEDFPU) { \
386 tsk->flags &= ~PF_USEDFPU; \
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 */