1#ifndef __ASM_X86_PROCESSOR_H
2#define __ASM_X86_PROCESSOR_H
3
4#include <asm/processor-flags.h>
5
6
7#include <asm/vm86.h>
8#define Xgt_desc_struct desc_ptr
9
10
11struct task_struct;
12struct mm_struct;
13
14#include <asm/vm86.h>
15#include <asm/math_emu.h>
16#include <asm/segment.h>
17#include <asm/types.h>
18#include <asm/sigcontext.h>
19#include <asm/current.h>
20#include <asm/cpufeature.h>
21#include <asm/system.h>
22#include <asm/page.h>
23#include <asm/percpu.h>
24#include <asm/msr.h>
25#include <asm/desc_defs.h>
26#include <asm/nops.h>
27#include <linux/personality.h>
28#include <linux/cpumask.h>
29#include <linux/cache.h>
30#include <linux/threads.h>
31#include <linux/init.h>
32
33
34
35
36
37static inline void *current_text_addr(void)
38{
39 void *pc;
40 asm volatile("mov $1f,%0\n1:":"=r" (pc));
41 return pc;
42}
43
44#ifdef CONFIG_X86_VSMP
45#define ARCH_MIN_TASKALIGN (1 << INTERNODE_CACHE_SHIFT)
46#define ARCH_MIN_MMSTRUCT_ALIGN (1 << INTERNODE_CACHE_SHIFT)
47#else
48#define ARCH_MIN_TASKALIGN 16
49#define ARCH_MIN_MMSTRUCT_ALIGN 0
50#endif
51
52
53
54
55
56
57
58struct cpuinfo_x86 {
59 __u8 x86;
60 __u8 x86_vendor;
61 __u8 x86_model;
62 __u8 x86_mask;
63#ifdef CONFIG_X86_32
64 char wp_works_ok;
65 char hlt_works_ok;
66 char hard_math;
67 char rfu;
68 char fdiv_bug;
69 char f00f_bug;
70 char coma_bug;
71 char pad0;
72#else
73
74 int x86_tlbsize;
75 __u8 x86_virt_bits, x86_phys_bits;
76
77 __u8 x86_coreid_bits;
78
79 __u32 extended_cpuid_level;
80#endif
81 int cpuid_level;
82 __u32 x86_capability[NCAPINTS];
83 char x86_vendor_id[16];
84 char x86_model_id[64];
85 int x86_cache_size;
86
87 int x86_cache_alignment;
88 int x86_power;
89 unsigned long loops_per_jiffy;
90#ifdef CONFIG_SMP
91 cpumask_t llc_shared_map;
92#endif
93 u16 x86_max_cores;
94 u16 apicid;
95 u16 x86_clflush_size;
96#ifdef CONFIG_SMP
97 u16 booted_cores;
98 u16 phys_proc_id;
99 u16 cpu_core_id;
100 u16 cpu_index;
101#endif
102} __attribute__((__aligned__(SMP_CACHE_BYTES)));
103
104#define X86_VENDOR_INTEL 0
105#define X86_VENDOR_CYRIX 1
106#define X86_VENDOR_AMD 2
107#define X86_VENDOR_UMC 3
108#define X86_VENDOR_NEXGEN 4
109#define X86_VENDOR_CENTAUR 5
110#define X86_VENDOR_TRANSMETA 7
111#define X86_VENDOR_NSC 8
112#define X86_VENDOR_NUM 9
113#define X86_VENDOR_UNKNOWN 0xff
114
115
116
117
118extern struct cpuinfo_x86 boot_cpu_data;
119extern struct cpuinfo_x86 new_cpu_data;
120extern struct tss_struct doublefault_tss;
121extern __u32 cleared_cpu_caps[NCAPINTS];
122
123#ifdef CONFIG_SMP
124DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
125#define cpu_data(cpu) per_cpu(cpu_info, cpu)
126#define current_cpu_data cpu_data(smp_processor_id())
127#else
128#define cpu_data(cpu) boot_cpu_data
129#define current_cpu_data boot_cpu_data
130#endif
131
132void cpu_detect(struct cpuinfo_x86 *c);
133
134extern void identify_cpu(struct cpuinfo_x86 *);
135extern void identify_boot_cpu(void);
136extern void identify_secondary_cpu(struct cpuinfo_x86 *);
137extern void print_cpu_info(struct cpuinfo_x86 *);
138extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
139extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
140extern unsigned short num_cache_leaves;
141
142#if defined(CONFIG_X86_HT) || defined(CONFIG_X86_64)
143extern void detect_ht(struct cpuinfo_x86 *c);
144#else
145static inline void detect_ht(struct cpuinfo_x86 *c) {}
146#endif
147
148static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
149 unsigned int *ecx, unsigned int *edx)
150{
151
152 __asm__("cpuid"
153 : "=a" (*eax),
154 "=b" (*ebx),
155 "=c" (*ecx),
156 "=d" (*edx)
157 : "0" (*eax), "2" (*ecx));
158}
159
160static inline void load_cr3(pgd_t *pgdir)
161{
162 write_cr3(__pa(pgdir));
163}
164
165#ifdef CONFIG_X86_32
166
167struct x86_hw_tss {
168 unsigned short back_link, __blh;
169 unsigned long sp0;
170 unsigned short ss0, __ss0h;
171 unsigned long sp1;
172 unsigned short ss1, __ss1h;
173 unsigned long sp2;
174 unsigned short ss2, __ss2h;
175 unsigned long __cr3;
176 unsigned long ip;
177 unsigned long flags;
178 unsigned long ax, cx, dx, bx;
179 unsigned long sp, bp, si, di;
180 unsigned short es, __esh;
181 unsigned short cs, __csh;
182 unsigned short ss, __ssh;
183 unsigned short ds, __dsh;
184 unsigned short fs, __fsh;
185 unsigned short gs, __gsh;
186 unsigned short ldt, __ldth;
187 unsigned short trace, io_bitmap_base;
188} __attribute__((packed));
189#else
190struct x86_hw_tss {
191 u32 reserved1;
192 u64 sp0;
193 u64 sp1;
194 u64 sp2;
195 u64 reserved2;
196 u64 ist[7];
197 u32 reserved3;
198 u32 reserved4;
199 u16 reserved5;
200 u16 io_bitmap_base;
201} __attribute__((packed)) ____cacheline_aligned;
202#endif
203
204
205
206
207#define IO_BITMAP_BITS 65536
208#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
209#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
210#define IO_BITMAP_OFFSET offsetof(struct tss_struct, io_bitmap)
211#define INVALID_IO_BITMAP_OFFSET 0x8000
212#define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000
213
214struct tss_struct {
215 struct x86_hw_tss x86_tss;
216
217
218
219
220
221
222
223 unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
224
225
226
227 unsigned long io_bitmap_max;
228 struct thread_struct *io_bitmap_owner;
229
230
231
232 unsigned long __cacheline_filler[35];
233
234
235
236 unsigned long stack[64];
237} __attribute__((packed));
238
239DECLARE_PER_CPU(struct tss_struct, init_tss);
240
241
242struct orig_ist {
243 unsigned long ist[7];
244};
245
246#define MXCSR_DEFAULT 0x1f80
247
248struct i387_fsave_struct {
249 u32 cwd;
250 u32 swd;
251 u32 twd;
252 u32 fip;
253 u32 fcs;
254 u32 foo;
255 u32 fos;
256 u32 st_space[20];
257 u32 status;
258};
259
260struct i387_fxsave_struct {
261 u16 cwd;
262 u16 swd;
263 u16 twd;
264 u16 fop;
265 union {
266 struct {
267 u64 rip;
268 u64 rdp;
269 };
270 struct {
271 u32 fip;
272 u32 fcs;
273 u32 foo;
274 u32 fos;
275 };
276 };
277 u32 mxcsr;
278 u32 mxcsr_mask;
279 u32 st_space[32];
280 u32 xmm_space[64];
281 u32 padding[24];
282} __attribute__((aligned(16)));
283
284struct i387_soft_struct {
285 u32 cwd;
286 u32 swd;
287 u32 twd;
288 u32 fip;
289 u32 fcs;
290 u32 foo;
291 u32 fos;
292 u32 st_space[20];
293 u8 ftop, changed, lookahead, no_update, rm, alimit;
294 struct info *info;
295 u32 entry_eip;
296};
297
298union i387_union {
299 struct i387_fsave_struct fsave;
300 struct i387_fxsave_struct fxsave;
301 struct i387_soft_struct soft;
302};
303
304#ifdef CONFIG_X86_32
305DECLARE_PER_CPU(u8, cpu_llc_id);
306#else
307DECLARE_PER_CPU(struct orig_ist, orig_ist);
308#endif
309
310extern void print_cpu_info(struct cpuinfo_x86 *);
311extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
312extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
313extern unsigned short num_cache_leaves;
314
315struct thread_struct {
316
317 struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
318 unsigned long sp0;
319 unsigned long sp;
320#ifdef CONFIG_X86_32
321 unsigned long sysenter_cs;
322#else
323 unsigned long usersp;
324 unsigned short es, ds, fsindex, gsindex;
325#endif
326 unsigned long ip;
327 unsigned long fs;
328 unsigned long gs;
329
330 unsigned long debugreg0;
331 unsigned long debugreg1;
332 unsigned long debugreg2;
333 unsigned long debugreg3;
334 unsigned long debugreg6;
335 unsigned long debugreg7;
336
337 unsigned long cr2, trap_no, error_code;
338
339 union i387_union i387 __attribute__((aligned(16)));;
340#ifdef CONFIG_X86_32
341
342 struct vm86_struct __user *vm86_info;
343 unsigned long screen_bitmap;
344 unsigned long v86flags, v86mask, saved_sp0;
345 unsigned int saved_fs, saved_gs;
346#endif
347
348 unsigned long *io_bitmap_ptr;
349 unsigned long iopl;
350
351 unsigned io_bitmap_max;
352
353 unsigned long debugctlmsr;
354
355
356 unsigned long ds_area_msr;
357};
358
359static inline unsigned long native_get_debugreg(int regno)
360{
361 unsigned long val = 0;
362
363 switch (regno) {
364 case 0:
365 asm("mov %%db0, %0" :"=r" (val)); break;
366 case 1:
367 asm("mov %%db1, %0" :"=r" (val)); break;
368 case 2:
369 asm("mov %%db2, %0" :"=r" (val)); break;
370 case 3:
371 asm("mov %%db3, %0" :"=r" (val)); break;
372 case 6:
373 asm("mov %%db6, %0" :"=r" (val)); break;
374 case 7:
375 asm("mov %%db7, %0" :"=r" (val)); break;
376 default:
377 BUG();
378 }
379 return val;
380}
381
382static inline void native_set_debugreg(int regno, unsigned long value)
383{
384 switch (regno) {
385 case 0:
386 asm("mov %0,%%db0" : /* no output */ :"r" (value));
387 break;
388 case 1:
389 asm("mov %0,%%db1" : /* no output */ :"r" (value));
390 break;
391 case 2:
392 asm("mov %0,%%db2" : /* no output */ :"r" (value));
393 break;
394 case 3:
395 asm("mov %0,%%db3" : /* no output */ :"r" (value));
396 break;
397 case 6:
398 asm("mov %0,%%db6" : /* no output */ :"r" (value));
399 break;
400 case 7:
401 asm("mov %0,%%db7" : /* no output */ :"r" (value));
402 break;
403 default:
404 BUG();
405 }
406}
407
408
409
410
411static inline void native_set_iopl_mask(unsigned mask)
412{
413#ifdef CONFIG_X86_32
414 unsigned int reg;
415 __asm__ __volatile__ ("pushfl;"
416 "popl %0;"
417 "andl %1, %0;"
418 "orl %2, %0;"
419 "pushl %0;"
420 "popfl"
421 : "=&r" (reg)
422 : "i" (~X86_EFLAGS_IOPL), "r" (mask));
423#endif
424}
425
426static inline void native_load_sp0(struct tss_struct *tss,
427 struct thread_struct *thread)
428{
429 tss->x86_tss.sp0 = thread->sp0;
430#ifdef CONFIG_X86_32
431
432 if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) {
433 tss->x86_tss.ss1 = thread->sysenter_cs;
434 wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
435 }
436#endif
437}
438
439static inline void native_swapgs(void)
440{
441#ifdef CONFIG_X86_64
442 asm volatile("swapgs" ::: "memory");
443#endif
444}
445
446#ifdef CONFIG_PARAVIRT
447#include <asm/paravirt.h>
448#else
449#define __cpuid native_cpuid
450#define paravirt_enabled() 0
451
452
453
454
455#define get_debugreg(var, register) \
456 (var) = native_get_debugreg(register)
457#define set_debugreg(value, register) \
458 native_set_debugreg(register, value)
459
460static inline void load_sp0(struct tss_struct *tss,
461 struct thread_struct *thread)
462{
463 native_load_sp0(tss, thread);
464}
465
466#define set_iopl_mask native_set_iopl_mask
467#define SWAPGS swapgs
468#endif
469
470
471
472
473
474
475
476extern unsigned long mmu_cr4_features;
477
478static inline void set_in_cr4(unsigned long mask)
479{
480 unsigned cr4;
481 mmu_cr4_features |= mask;
482 cr4 = read_cr4();
483 cr4 |= mask;
484 write_cr4(cr4);
485}
486
487static inline void clear_in_cr4(unsigned long mask)
488{
489 unsigned cr4;
490 mmu_cr4_features &= ~mask;
491 cr4 = read_cr4();
492 cr4 &= ~mask;
493 write_cr4(cr4);
494}
495
496struct microcode_header {
497 unsigned int hdrver;
498 unsigned int rev;
499 unsigned int date;
500 unsigned int sig;
501 unsigned int cksum;
502 unsigned int ldrver;
503 unsigned int pf;
504 unsigned int datasize;
505 unsigned int totalsize;
506 unsigned int reserved[3];
507};
508
509struct microcode {
510 struct microcode_header hdr;
511 unsigned int bits[0];
512};
513
514typedef struct microcode microcode_t;
515typedef struct microcode_header microcode_header_t;
516
517
518struct extended_signature {
519 unsigned int sig;
520 unsigned int pf;
521 unsigned int cksum;
522};
523
524struct extended_sigtable {
525 unsigned int count;
526 unsigned int cksum;
527 unsigned int reserved[3];
528 struct extended_signature sigs[0];
529};
530
531typedef struct {
532 unsigned long seg;
533} mm_segment_t;
534
535
536
537
538
539extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
540
541
542extern void release_thread(struct task_struct *);
543
544
545extern void prepare_to_copy(struct task_struct *tsk);
546
547unsigned long get_wchan(struct task_struct *p);
548
549
550
551
552
553
554static inline void cpuid(unsigned int op,
555 unsigned int *eax, unsigned int *ebx,
556 unsigned int *ecx, unsigned int *edx)
557{
558 *eax = op;
559 *ecx = 0;
560 __cpuid(eax, ebx, ecx, edx);
561}
562
563
564static inline void cpuid_count(unsigned int op, int count,
565 unsigned int *eax, unsigned int *ebx,
566 unsigned int *ecx, unsigned int *edx)
567{
568 *eax = op;
569 *ecx = count;
570 __cpuid(eax, ebx, ecx, edx);
571}
572
573
574
575
576static inline unsigned int cpuid_eax(unsigned int op)
577{
578 unsigned int eax, ebx, ecx, edx;
579
580 cpuid(op, &eax, &ebx, &ecx, &edx);
581 return eax;
582}
583static inline unsigned int cpuid_ebx(unsigned int op)
584{
585 unsigned int eax, ebx, ecx, edx;
586
587 cpuid(op, &eax, &ebx, &ecx, &edx);
588 return ebx;
589}
590static inline unsigned int cpuid_ecx(unsigned int op)
591{
592 unsigned int eax, ebx, ecx, edx;
593
594 cpuid(op, &eax, &ebx, &ecx, &edx);
595 return ecx;
596}
597static inline unsigned int cpuid_edx(unsigned int op)
598{
599 unsigned int eax, ebx, ecx, edx;
600
601 cpuid(op, &eax, &ebx, &ecx, &edx);
602 return edx;
603}
604
605
606static inline void rep_nop(void)
607{
608 __asm__ __volatile__("rep;nop": : :"memory");
609}
610
611
612static inline void sync_core(void)
613{
614 int tmp;
615 asm volatile("cpuid" : "=a" (tmp) : "0" (1)
616 : "ebx", "ecx", "edx", "memory");
617}
618
619#define cpu_relax() rep_nop()
620
621static inline void __monitor(const void *eax, unsigned long ecx,
622 unsigned long edx)
623{
624
625 asm volatile(
626 ".byte 0x0f,0x01,0xc8;"
627 : :"a" (eax), "c" (ecx), "d"(edx));
628}
629
630static inline void __mwait(unsigned long eax, unsigned long ecx)
631{
632
633 asm volatile(
634 ".byte 0x0f,0x01,0xc9;"
635 : :"a" (eax), "c" (ecx));
636}
637
638static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
639{
640
641 asm volatile(
642 "sti; .byte 0x0f,0x01,0xc9;"
643 : :"a" (eax), "c" (ecx));
644}
645
646extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
647
648extern int force_mwait;
649
650extern void select_idle_routine(const struct cpuinfo_x86 *c);
651
652extern unsigned long boot_option_idle_override;
653
654extern void enable_sep_cpu(void);
655extern int sysenter_setup(void);
656
657
658extern struct desc_ptr early_gdt_descr;
659
660extern void cpu_set_gdt(int);
661extern void switch_to_new_gdt(void);
662extern void cpu_init(void);
663extern void init_gdt(int cpu);
664
665
666
667extern unsigned int machine_id;
668extern unsigned int machine_submodel_id;
669extern unsigned int BIOS_revision;
670
671
672extern int bootloader_type;
673
674extern char ignore_fpu_irq;
675#define cache_line_size() (boot_cpu_data.x86_cache_alignment)
676
677#define HAVE_ARCH_PICK_MMAP_LAYOUT 1
678#define ARCH_HAS_PREFETCHW
679#define ARCH_HAS_SPINLOCK_PREFETCH
680
681#ifdef CONFIG_X86_32
682#define BASE_PREFETCH ASM_NOP4
683#define ARCH_HAS_PREFETCH
684#else
685#define BASE_PREFETCH "prefetcht0 (%1)"
686#endif
687
688
689
690
691
692
693static inline void prefetch(const void *x)
694{
695 alternative_input(BASE_PREFETCH,
696 "prefetchnta (%1)",
697 X86_FEATURE_XMM,
698 "r" (x));
699}
700
701
702
703static inline void prefetchw(const void *x)
704{
705 alternative_input(BASE_PREFETCH,
706 "prefetchw (%1)",
707 X86_FEATURE_3DNOW,
708 "r" (x));
709}
710
711#define spin_lock_prefetch(x) prefetchw(x)
712#ifdef CONFIG_X86_32
713
714
715
716#define TASK_SIZE (PAGE_OFFSET)
717#define STACK_TOP TASK_SIZE
718#define STACK_TOP_MAX STACK_TOP
719
720#define INIT_THREAD { \
721 .sp0 = sizeof(init_stack) + (long)&init_stack, \
722 .vm86_info = NULL, \
723 .sysenter_cs = __KERNEL_CS, \
724 .io_bitmap_ptr = NULL, \
725 .fs = __KERNEL_PERCPU, \
726}
727
728
729
730
731
732
733
734#define INIT_TSS { \
735 .x86_tss = { \
736 .sp0 = sizeof(init_stack) + (long)&init_stack, \
737 .ss0 = __KERNEL_DS, \
738 .ss1 = __KERNEL_CS, \
739 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
740 }, \
741 .io_bitmap = { [0 ... IO_BITMAP_LONGS] = ~0 }, \
742}
743
744#define start_thread(regs, new_eip, new_esp) do { \
745 __asm__("movl %0,%%gs": :"r" (0)); \
746 regs->fs = 0; \
747 set_fs(USER_DS); \
748 regs->ds = __USER_DS; \
749 regs->es = __USER_DS; \
750 regs->ss = __USER_DS; \
751 regs->cs = __USER_CS; \
752 regs->ip = new_eip; \
753 regs->sp = new_esp; \
754} while (0)
755
756
757extern unsigned long thread_saved_pc(struct task_struct *tsk);
758
759#define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
760#define KSTK_TOP(info) \
761({ \
762 unsigned long *__ptr = (unsigned long *)(info); \
763 (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
764})
765
766
767
768
769
770
771
772
773
774
775
776#define task_pt_regs(task) \
777({ \
778 struct pt_regs *__regs__; \
779 __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
780 __regs__ - 1; \
781})
782
783#define KSTK_ESP(task) (task_pt_regs(task)->sp)
784
785#else
786
787
788
789#define TASK_SIZE64 (0x800000000000UL - 4096)
790
791
792
793
794#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
795 0xc0000000 : 0xFFFFe000)
796
797#define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
798 IA32_PAGE_OFFSET : TASK_SIZE64)
799#define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? \
800 IA32_PAGE_OFFSET : TASK_SIZE64)
801
802#define STACK_TOP TASK_SIZE
803#define STACK_TOP_MAX TASK_SIZE64
804
805#define INIT_THREAD { \
806 .sp0 = (unsigned long)&init_stack + sizeof(init_stack) \
807}
808
809#define INIT_TSS { \
810 .x86_tss.sp0 = (unsigned long)&init_stack + sizeof(init_stack) \
811}
812
813#define start_thread(regs, new_rip, new_rsp) do { \
814 asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0)); \
815 load_gs_index(0); \
816 (regs)->ip = (new_rip); \
817 (regs)->sp = (new_rsp); \
818 write_pda(oldrsp, (new_rsp)); \
819 (regs)->cs = __USER_CS; \
820 (regs)->ss = __USER_DS; \
821 (regs)->flags = 0x200; \
822 set_fs(USER_DS); \
823} while (0)
824
825
826
827
828
829#define thread_saved_pc(t) (*(unsigned long *)((t)->thread.sp - 8))
830
831#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1)
832#define KSTK_ESP(tsk) -1
833#endif
834
835
836
837
838#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
839
840#define KSTK_EIP(task) (task_pt_regs(task)->ip)
841
842#endif
843