1
2
3
4
5
6
7#ifndef __ASM_I386_PROCESSOR_H
8#define __ASM_I386_PROCESSOR_H
9
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 <asm/sigcontext.h>
16#include <asm/cpufeature.h>
17#include <asm/msr.h>
18#include <asm/system.h>
19#include <linux/cache.h>
20#include <linux/config.h>
21#include <linux/threads.h>
22
23
24extern int tsc_disable;
25
26struct desc_struct {
27 unsigned long a,b;
28};
29
30#define desc_empty(desc) \
31 (!((desc)->a + (desc)->b))
32
33#define desc_equal(desc1, desc2) \
34 (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
35
36
37
38
39#define current_text_addr() ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; })
40
41
42
43
44
45
46
47struct cpuinfo_x86 {
48 __u8 x86;
49 __u8 x86_vendor;
50 __u8 x86_model;
51 __u8 x86_mask;
52 char wp_works_ok;
53 char hlt_works_ok;
54 char hard_math;
55 char rfu;
56 int cpuid_level;
57 unsigned long x86_capability[NCAPINTS];
58 char x86_vendor_id[16];
59 char x86_model_id[64];
60 int x86_cache_size;
61
62 int x86_cache_alignment;
63 int fdiv_bug;
64 int f00f_bug;
65 int coma_bug;
66 unsigned long loops_per_jiffy;
67} __attribute__((__aligned__(SMP_CACHE_BYTES)));
68
69#define X86_VENDOR_INTEL 0
70#define X86_VENDOR_CYRIX 1
71#define X86_VENDOR_AMD 2
72#define X86_VENDOR_UMC 3
73#define X86_VENDOR_NEXGEN 4
74#define X86_VENDOR_CENTAUR 5
75#define X86_VENDOR_RISE 6
76#define X86_VENDOR_TRANSMETA 7
77#define X86_VENDOR_NSC 8
78#define X86_VENDOR_NUM 9
79#define X86_VENDOR_UNKNOWN 0xff
80
81
82
83
84
85extern struct cpuinfo_x86 boot_cpu_data;
86extern struct cpuinfo_x86 new_cpu_data;
87extern struct tss_struct init_tss[NR_CPUS];
88extern struct tss_struct doublefault_tss;
89
90#ifdef CONFIG_SMP
91extern struct cpuinfo_x86 cpu_data[];
92#define current_cpu_data cpu_data[smp_processor_id()]
93#else
94#define cpu_data (&boot_cpu_data)
95#define current_cpu_data boot_cpu_data
96#endif
97
98extern char ignore_fpu_irq;
99
100extern void identify_cpu(struct cpuinfo_x86 *);
101extern void print_cpu_info(struct cpuinfo_x86 *);
102extern void dodgy_tsc(void);
103
104
105
106
107#define X86_EFLAGS_CF 0x00000001
108#define X86_EFLAGS_PF 0x00000004
109#define X86_EFLAGS_AF 0x00000010
110#define X86_EFLAGS_ZF 0x00000040
111#define X86_EFLAGS_SF 0x00000080
112#define X86_EFLAGS_TF 0x00000100
113#define X86_EFLAGS_IF 0x00000200
114#define X86_EFLAGS_DF 0x00000400
115#define X86_EFLAGS_OF 0x00000800
116#define X86_EFLAGS_IOPL 0x00003000
117#define X86_EFLAGS_NT 0x00004000
118#define X86_EFLAGS_RF 0x00010000
119#define X86_EFLAGS_VM 0x00020000
120#define X86_EFLAGS_AC 0x00040000
121#define X86_EFLAGS_VIF 0x00080000
122#define X86_EFLAGS_VIP 0x00100000
123#define X86_EFLAGS_ID 0x00200000
124
125
126
127
128static inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
129{
130 __asm__("cpuid"
131 : "=a" (*eax),
132 "=b" (*ebx),
133 "=c" (*ecx),
134 "=d" (*edx)
135 : "0" (op));
136}
137
138
139
140
141static inline unsigned int cpuid_eax(unsigned int op)
142{
143 unsigned int eax;
144
145 __asm__("cpuid"
146 : "=a" (eax)
147 : "0" (op)
148 : "bx", "cx", "dx");
149 return eax;
150}
151static inline unsigned int cpuid_ebx(unsigned int op)
152{
153 unsigned int eax, ebx;
154
155 __asm__("cpuid"
156 : "=a" (eax), "=b" (ebx)
157 : "0" (op)
158 : "cx", "dx" );
159 return ebx;
160}
161static inline unsigned int cpuid_ecx(unsigned int op)
162{
163 unsigned int eax, ecx;
164
165 __asm__("cpuid"
166 : "=a" (eax), "=c" (ecx)
167 : "0" (op)
168 : "bx", "dx" );
169 return ecx;
170}
171static inline unsigned int cpuid_edx(unsigned int op)
172{
173 unsigned int eax, edx;
174
175 __asm__("cpuid"
176 : "=a" (eax), "=d" (edx)
177 : "0" (op)
178 : "bx", "cx");
179 return edx;
180}
181
182#define load_cr3(pgdir) \
183 asm volatile("movl %0,%%cr3": :"r" (__pa(pgdir)))
184
185
186
187
188
189#define X86_CR4_VME 0x0001
190#define X86_CR4_PVI 0x0002
191#define X86_CR4_TSD 0x0004
192#define X86_CR4_DE 0x0008
193#define X86_CR4_PSE 0x0010
194#define X86_CR4_PAE 0x0020
195#define X86_CR4_MCE 0x0040
196#define X86_CR4_PGE 0x0080
197#define X86_CR4_PCE 0x0100
198#define X86_CR4_OSFXSR 0x0200
199#define X86_CR4_OSXMMEXCPT 0x0400
200
201
202
203
204
205
206
207extern unsigned long mmu_cr4_features;
208
209static inline void set_in_cr4 (unsigned long mask)
210{
211 mmu_cr4_features |= mask;
212 __asm__("movl %%cr4,%%eax\n\t"
213 "orl %0,%%eax\n\t"
214 "movl %%eax,%%cr4\n"
215 : : "irg" (mask)
216 :"ax");
217}
218
219static inline void clear_in_cr4 (unsigned long mask)
220{
221 mmu_cr4_features &= ~mask;
222 __asm__("movl %%cr4,%%eax\n\t"
223 "andl %0,%%eax\n\t"
224 "movl %%eax,%%cr4\n"
225 : : "irg" (~mask)
226 :"ax");
227}
228
229
230
231
232
233#define CX86_PCR0 0x20
234#define CX86_GCR 0xb8
235#define CX86_CCR0 0xc0
236#define CX86_CCR1 0xc1
237#define CX86_CCR2 0xc2
238#define CX86_CCR3 0xc3
239#define CX86_CCR4 0xe8
240#define CX86_CCR5 0xe9
241#define CX86_CCR6 0xea
242#define CX86_CCR7 0xeb
243#define CX86_PCR1 0xf0
244#define CX86_DIR0 0xfe
245#define CX86_DIR1 0xff
246#define CX86_ARR_BASE 0xc4
247#define CX86_RCR_BASE 0xdc
248
249
250
251
252
253#define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
254
255#define setCx86(reg, data) do { \
256 outb((reg), 0x22); \
257 outb((data), 0x23); \
258} while (0)
259
260
261
262
263extern int MCA_bus;
264
265static inline void __monitor(const void *eax, unsigned long ecx,
266 unsigned long edx)
267{
268
269 asm volatile(
270 ".byte 0x0f,0x01,0xc8;"
271 : :"a" (eax), "c" (ecx), "d"(edx));
272}
273
274static inline void __mwait(unsigned long eax, unsigned long ecx)
275{
276
277 asm volatile(
278 ".byte 0x0f,0x01,0xc9;"
279 : :"a" (eax), "c" (ecx));
280}
281
282
283
284extern unsigned int machine_id;
285extern unsigned int machine_submodel_id;
286extern unsigned int BIOS_revision;
287extern unsigned int mca_pentium_flag;
288
289
290
291
292#define TASK_SIZE (PAGE_OFFSET)
293
294
295
296
297#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
298
299
300
301
302#define IO_BITMAP_BITS 65536
303#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
304#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
305#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
306#define INVALID_IO_BITMAP_OFFSET 0x8000
307
308struct i387_fsave_struct {
309 long cwd;
310 long swd;
311 long twd;
312 long fip;
313 long fcs;
314 long foo;
315 long fos;
316 long st_space[20];
317 long status;
318};
319
320struct i387_fxsave_struct {
321 unsigned short cwd;
322 unsigned short swd;
323 unsigned short twd;
324 unsigned short fop;
325 long fip;
326 long fcs;
327 long foo;
328 long fos;
329 long mxcsr;
330 long mxcsr_mask;
331 long st_space[32];
332 long xmm_space[32];
333 long padding[56];
334} __attribute__ ((aligned (16)));
335
336struct i387_soft_struct {
337 long cwd;
338 long swd;
339 long twd;
340 long fip;
341 long fcs;
342 long foo;
343 long fos;
344 long st_space[20];
345 unsigned char ftop, changed, lookahead, no_update, rm, alimit;
346 struct info *info;
347 unsigned long entry_eip;
348};
349
350union i387_union {
351 struct i387_fsave_struct fsave;
352 struct i387_fxsave_struct fxsave;
353 struct i387_soft_struct soft;
354};
355
356typedef struct {
357 unsigned long seg;
358} mm_segment_t;
359
360struct tss_struct {
361 unsigned short back_link,__blh;
362 unsigned long esp0;
363 unsigned short ss0,__ss0h;
364 unsigned long esp1;
365 unsigned short ss1,__ss1h;
366 unsigned long esp2;
367 unsigned short ss2,__ss2h;
368 unsigned long __cr3;
369 unsigned long eip;
370 unsigned long eflags;
371 unsigned long eax,ecx,edx,ebx;
372 unsigned long esp;
373 unsigned long ebp;
374 unsigned long esi;
375 unsigned long edi;
376 unsigned short es, __esh;
377 unsigned short cs, __csh;
378 unsigned short ss, __ssh;
379 unsigned short ds, __dsh;
380 unsigned short fs, __fsh;
381 unsigned short gs, __gsh;
382 unsigned short ldt, __ldth;
383 unsigned short trace, io_bitmap_base;
384
385
386
387
388
389
390 unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
391
392
393
394 unsigned long __cacheline_filler[37];
395
396
397
398 unsigned long stack[64];
399} __attribute__((packed));
400
401#define ARCH_MIN_TASKALIGN 16
402
403struct thread_struct {
404
405 struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
406 unsigned long esp0;
407 unsigned long sysenter_cs;
408 unsigned long eip;
409 unsigned long esp;
410 unsigned long fs;
411 unsigned long gs;
412
413 unsigned long debugreg[8];
414
415 unsigned long cr2, trap_no, error_code;
416
417 union i387_union i387;
418
419 struct vm86_struct __user * vm86_info;
420 unsigned long screen_bitmap;
421 unsigned long v86flags, v86mask, saved_esp0;
422 unsigned int saved_fs, saved_gs;
423
424 unsigned long *io_bitmap_ptr;
425};
426
427#define INIT_THREAD { \
428 .vm86_info = NULL, \
429 .sysenter_cs = __KERNEL_CS, \
430 .io_bitmap_ptr = NULL, \
431}
432
433
434
435
436
437
438
439#define INIT_TSS { \
440 .esp0 = sizeof(init_stack) + (long)&init_stack, \
441 .ss0 = __KERNEL_DS, \
442 .esp1 = sizeof(init_tss[0]) + (long)&init_tss[0], \
443 .ss1 = __KERNEL_CS, \
444 .ldt = GDT_ENTRY_LDT, \
445 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
446 .io_bitmap = { [ 0 ... IO_BITMAP_LONGS] = ~0 }, \
447}
448
449static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread)
450{
451 tss->esp0 = thread->esp0;
452
453 if (unlikely(tss->ss1 != thread->sysenter_cs)) {
454 tss->ss1 = thread->sysenter_cs;
455 wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
456 }
457}
458
459#define start_thread(regs, new_eip, new_esp) do { \
460 __asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0)); \
461 set_fs(USER_DS); \
462 regs->xds = __USER_DS; \
463 regs->xes = __USER_DS; \
464 regs->xss = __USER_DS; \
465 regs->xcs = __USER_CS; \
466 regs->eip = new_eip; \
467 regs->esp = new_esp; \
468} while (0)
469
470
471struct task_struct;
472struct mm_struct;
473
474
475extern void release_thread(struct task_struct *);
476
477
478extern void prepare_to_copy(struct task_struct *tsk);
479
480
481
482
483extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
484
485extern unsigned long thread_saved_pc(struct task_struct *tsk);
486void show_trace(struct task_struct *task, unsigned long *stack);
487
488unsigned long get_wchan(struct task_struct *p);
489
490#define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
491#define KSTK_TOP(info) \
492({ \
493 unsigned long *__ptr = (unsigned long *)(info); \
494 (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
495})
496
497#define task_pt_regs(task) \
498({ \
499 struct pt_regs *__regs__; \
500 __regs__ = (struct pt_regs *)KSTK_TOP((task)->thread_info); \
501 __regs__ - 1; \
502})
503
504#define KSTK_EIP(task) (task_pt_regs(task)->eip)
505#define KSTK_ESP(task) (task_pt_regs(task)->esp)
506
507
508struct microcode_header {
509 unsigned int hdrver;
510 unsigned int rev;
511 unsigned int date;
512 unsigned int sig;
513 unsigned int cksum;
514 unsigned int ldrver;
515 unsigned int pf;
516 unsigned int datasize;
517 unsigned int totalsize;
518 unsigned int reserved[3];
519};
520
521struct microcode {
522 struct microcode_header hdr;
523 unsigned int bits[0];
524};
525
526typedef struct microcode microcode_t;
527typedef struct microcode_header microcode_header_t;
528
529
530struct extended_signature {
531 unsigned int sig;
532 unsigned int pf;
533 unsigned int cksum;
534};
535
536struct extended_sigtable {
537 unsigned int count;
538 unsigned int cksum;
539 unsigned int reserved[3];
540 struct extended_signature sigs[0];
541};
542
543#define MICROCODE_IOCFREE _IO('6',0)
544
545
546static inline void rep_nop(void)
547{
548 __asm__ __volatile__("rep;nop": : :"memory");
549}
550
551#define cpu_relax() rep_nop()
552
553
554#define GENERIC_NOP1 ".byte 0x90\n"
555#define GENERIC_NOP2 ".byte 0x89,0xf6\n"
556#define GENERIC_NOP3 ".byte 0x8d,0x76,0x00\n"
557#define GENERIC_NOP4 ".byte 0x8d,0x74,0x26,0x00\n"
558#define GENERIC_NOP5 GENERIC_NOP1 GENERIC_NOP4
559#define GENERIC_NOP6 ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n"
560#define GENERIC_NOP7 ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n"
561#define GENERIC_NOP8 GENERIC_NOP1 GENERIC_NOP7
562
563
564#define K8_NOP1 GENERIC_NOP1
565#define K8_NOP2 ".byte 0x66,0x90\n"
566#define K8_NOP3 ".byte 0x66,0x66,0x90\n"
567#define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n"
568#define K8_NOP5 K8_NOP3 K8_NOP2
569#define K8_NOP6 K8_NOP3 K8_NOP3
570#define K8_NOP7 K8_NOP4 K8_NOP3
571#define K8_NOP8 K8_NOP4 K8_NOP4
572
573
574
575#define K7_NOP1 GENERIC_NOP1
576#define K7_NOP2 ".byte 0x8b,0xc0\n"
577#define K7_NOP3 ".byte 0x8d,0x04,0x20\n"
578#define K7_NOP4 ".byte 0x8d,0x44,0x20,0x00\n"
579#define K7_NOP5 K7_NOP4 ASM_NOP1
580#define K7_NOP6 ".byte 0x8d,0x80,0,0,0,0\n"
581#define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n"
582#define K7_NOP8 K7_NOP7 ASM_NOP1
583
584#ifdef CONFIG_MK8
585#define ASM_NOP1 K8_NOP1
586#define ASM_NOP2 K8_NOP2
587#define ASM_NOP3 K8_NOP3
588#define ASM_NOP4 K8_NOP4
589#define ASM_NOP5 K8_NOP5
590#define ASM_NOP6 K8_NOP6
591#define ASM_NOP7 K8_NOP7
592#define ASM_NOP8 K8_NOP8
593#elif defined(CONFIG_MK7)
594#define ASM_NOP1 K7_NOP1
595#define ASM_NOP2 K7_NOP2
596#define ASM_NOP3 K7_NOP3
597#define ASM_NOP4 K7_NOP4
598#define ASM_NOP5 K7_NOP5
599#define ASM_NOP6 K7_NOP6
600#define ASM_NOP7 K7_NOP7
601#define ASM_NOP8 K7_NOP8
602#else
603#define ASM_NOP1 GENERIC_NOP1
604#define ASM_NOP2 GENERIC_NOP2
605#define ASM_NOP3 GENERIC_NOP3
606#define ASM_NOP4 GENERIC_NOP4
607#define ASM_NOP5 GENERIC_NOP5
608#define ASM_NOP6 GENERIC_NOP6
609#define ASM_NOP7 GENERIC_NOP7
610#define ASM_NOP8 GENERIC_NOP8
611#endif
612
613#define ASM_NOP_MAX 8
614
615
616
617
618
619
620#define ARCH_HAS_PREFETCH
621extern inline void prefetch(const void *x)
622{
623 alternative_input(ASM_NOP4,
624 "prefetchnta (%1)",
625 X86_FEATURE_XMM,
626 "r" (x));
627}
628
629#define ARCH_HAS_PREFETCH
630#define ARCH_HAS_PREFETCHW
631#define ARCH_HAS_SPINLOCK_PREFETCH
632
633
634
635extern inline void prefetchw(const void *x)
636{
637 alternative_input(ASM_NOP4,
638 "prefetchw (%1)",
639 X86_FEATURE_3DNOW,
640 "r" (x));
641}
642#define spin_lock_prefetch(x) prefetchw(x)
643
644extern void select_idle_routine(const struct cpuinfo_x86 *c);
645
646#define cache_line_size() (boot_cpu_data.x86_cache_alignment)
647
648#ifdef CONFIG_SCHED_SMT
649#define ARCH_HAS_SCHED_DOMAIN
650#define ARCH_HAS_SCHED_WAKE_IDLE
651#endif
652
653#endif
654