aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-i386/processor.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-i386/processor.h')
-rw-r--r--include/asm-i386/processor.h204
1 files changed, 111 insertions, 93 deletions
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index e0ddca94d50c..a52d65440429 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -20,6 +20,7 @@
20#include <linux/threads.h> 20#include <linux/threads.h>
21#include <asm/percpu.h> 21#include <asm/percpu.h>
22#include <linux/cpumask.h> 22#include <linux/cpumask.h>
23#include <linux/init.h>
23 24
24/* flag for disabling the tsc */ 25/* flag for disabling the tsc */
25extern int tsc_disable; 26extern int tsc_disable;
@@ -72,6 +73,7 @@ struct cpuinfo_x86 {
72#endif 73#endif
73 unsigned char x86_max_cores; /* cpuid returned max cores value */ 74 unsigned char x86_max_cores; /* cpuid returned max cores value */
74 unsigned char apicid; 75 unsigned char apicid;
76 unsigned short x86_clflush_size;
75#ifdef CONFIG_SMP 77#ifdef CONFIG_SMP
76 unsigned char booted_cores; /* number of cores as seen by OS */ 78 unsigned char booted_cores; /* number of cores as seen by OS */
77 __u8 phys_proc_id; /* Physical processor id. */ 79 __u8 phys_proc_id; /* Physical processor id. */
@@ -111,6 +113,8 @@ extern struct cpuinfo_x86 cpu_data[];
111extern int cpu_llc_id[NR_CPUS]; 113extern int cpu_llc_id[NR_CPUS];
112extern char ignore_fpu_irq; 114extern char ignore_fpu_irq;
113 115
116void __init cpu_detect(struct cpuinfo_x86 *c);
117
114extern void identify_cpu(struct cpuinfo_x86 *); 118extern void identify_cpu(struct cpuinfo_x86 *);
115extern void print_cpu_info(struct cpuinfo_x86 *); 119extern void print_cpu_info(struct cpuinfo_x86 *);
116extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); 120extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
@@ -143,8 +147,8 @@ static inline void detect_ht(struct cpuinfo_x86 *c) {}
143#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ 147#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */
144#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ 148#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
145 149
146static inline void __cpuid(unsigned int *eax, unsigned int *ebx, 150static inline fastcall void native_cpuid(unsigned int *eax, unsigned int *ebx,
147 unsigned int *ecx, unsigned int *edx) 151 unsigned int *ecx, unsigned int *edx)
148{ 152{
149 /* ecx is often an input as well as an output. */ 153 /* ecx is often an input as well as an output. */
150 __asm__("cpuid" 154 __asm__("cpuid"
@@ -155,59 +159,6 @@ static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
155 : "0" (*eax), "2" (*ecx)); 159 : "0" (*eax), "2" (*ecx));
156} 160}
157 161
158/*
159 * Generic CPUID function
160 * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
161 * resulting in stale register contents being returned.
162 */
163static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
164{
165 *eax = op;
166 *ecx = 0;
167 __cpuid(eax, ebx, ecx, edx);
168}
169
170/* Some CPUID calls want 'count' to be placed in ecx */
171static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
172 int *edx)
173{
174 *eax = op;
175 *ecx = count;
176 __cpuid(eax, ebx, ecx, edx);
177}
178
179/*
180 * CPUID functions returning a single datum
181 */
182static inline unsigned int cpuid_eax(unsigned int op)
183{
184 unsigned int eax, ebx, ecx, edx;
185
186 cpuid(op, &eax, &ebx, &ecx, &edx);
187 return eax;
188}
189static inline unsigned int cpuid_ebx(unsigned int op)
190{
191 unsigned int eax, ebx, ecx, edx;
192
193 cpuid(op, &eax, &ebx, &ecx, &edx);
194 return ebx;
195}
196static inline unsigned int cpuid_ecx(unsigned int op)
197{
198 unsigned int eax, ebx, ecx, edx;
199
200 cpuid(op, &eax, &ebx, &ecx, &edx);
201 return ecx;
202}
203static inline unsigned int cpuid_edx(unsigned int op)
204{
205 unsigned int eax, ebx, ecx, edx;
206
207 cpuid(op, &eax, &ebx, &ecx, &edx);
208 return edx;
209}
210
211#define load_cr3(pgdir) write_cr3(__pa(pgdir)) 162#define load_cr3(pgdir) write_cr3(__pa(pgdir))
212 163
213/* 164/*
@@ -473,6 +424,7 @@ struct thread_struct {
473 .vm86_info = NULL, \ 424 .vm86_info = NULL, \
474 .sysenter_cs = __KERNEL_CS, \ 425 .sysenter_cs = __KERNEL_CS, \
475 .io_bitmap_ptr = NULL, \ 426 .io_bitmap_ptr = NULL, \
427 .gs = __KERNEL_PDA, \
476} 428}
477 429
478/* 430/*
@@ -489,18 +441,9 @@ struct thread_struct {
489 .io_bitmap = { [ 0 ... IO_BITMAP_LONGS] = ~0 }, \ 441 .io_bitmap = { [ 0 ... IO_BITMAP_LONGS] = ~0 }, \
490} 442}
491 443
492static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread)
493{
494 tss->esp0 = thread->esp0;
495 /* This can only happen when SEP is enabled, no need to test "SEP"arately */
496 if (unlikely(tss->ss1 != thread->sysenter_cs)) {
497 tss->ss1 = thread->sysenter_cs;
498 wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
499 }
500}
501
502#define start_thread(regs, new_eip, new_esp) do { \ 444#define start_thread(regs, new_eip, new_esp) do { \
503 __asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0)); \ 445 __asm__("movl %0,%%fs": :"r" (0)); \
446 regs->xgs = 0; \
504 set_fs(USER_DS); \ 447 set_fs(USER_DS); \
505 regs->xds = __USER_DS; \ 448 regs->xds = __USER_DS; \
506 regs->xes = __USER_DS; \ 449 regs->xes = __USER_DS; \
@@ -510,33 +453,6 @@ static inline void load_esp0(struct tss_struct *tss, struct thread_struct *threa
510 regs->esp = new_esp; \ 453 regs->esp = new_esp; \
511} while (0) 454} while (0)
512 455
513/*
514 * These special macros can be used to get or set a debugging register
515 */
516#define get_debugreg(var, register) \
517 __asm__("movl %%db" #register ", %0" \
518 :"=r" (var))
519#define set_debugreg(value, register) \
520 __asm__("movl %0,%%db" #register \
521 : /* no output */ \
522 :"r" (value))
523
524/*
525 * Set IOPL bits in EFLAGS from given mask
526 */
527static inline void set_iopl_mask(unsigned mask)
528{
529 unsigned int reg;
530 __asm__ __volatile__ ("pushfl;"
531 "popl %0;"
532 "andl %1, %0;"
533 "orl %2, %0;"
534 "pushl %0;"
535 "popfl"
536 : "=&r" (reg)
537 : "i" (~X86_EFLAGS_IOPL), "r" (mask));
538}
539
540/* Forward declaration, a strange C thing */ 456/* Forward declaration, a strange C thing */
541struct task_struct; 457struct task_struct;
542struct mm_struct; 458struct mm_struct;
@@ -628,6 +544,105 @@ static inline void rep_nop(void)
628 544
629#define cpu_relax() rep_nop() 545#define cpu_relax() rep_nop()
630 546
547#ifdef CONFIG_PARAVIRT
548#include <asm/paravirt.h>
549#else
550#define paravirt_enabled() 0
551#define __cpuid native_cpuid
552
553static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread)
554{
555 tss->esp0 = thread->esp0;
556 /* This can only happen when SEP is enabled, no need to test "SEP"arately */
557 if (unlikely(tss->ss1 != thread->sysenter_cs)) {
558 tss->ss1 = thread->sysenter_cs;
559 wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
560 }
561}
562
563/*
564 * These special macros can be used to get or set a debugging register
565 */
566#define get_debugreg(var, register) \
567 __asm__("movl %%db" #register ", %0" \
568 :"=r" (var))
569#define set_debugreg(value, register) \
570 __asm__("movl %0,%%db" #register \
571 : /* no output */ \
572 :"r" (value))
573
574#define set_iopl_mask native_set_iopl_mask
575#endif /* CONFIG_PARAVIRT */
576
577/*
578 * Set IOPL bits in EFLAGS from given mask
579 */
580static fastcall inline void native_set_iopl_mask(unsigned mask)
581{
582 unsigned int reg;
583 __asm__ __volatile__ ("pushfl;"
584 "popl %0;"
585 "andl %1, %0;"
586 "orl %2, %0;"
587 "pushl %0;"
588 "popfl"
589 : "=&r" (reg)
590 : "i" (~X86_EFLAGS_IOPL), "r" (mask));
591}
592
593/*
594 * Generic CPUID function
595 * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
596 * resulting in stale register contents being returned.
597 */
598static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
599{
600 *eax = op;
601 *ecx = 0;
602 __cpuid(eax, ebx, ecx, edx);
603}
604
605/* Some CPUID calls want 'count' to be placed in ecx */
606static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
607 int *edx)
608{
609 *eax = op;
610 *ecx = count;
611 __cpuid(eax, ebx, ecx, edx);
612}
613
614/*
615 * CPUID functions returning a single datum
616 */
617static inline unsigned int cpuid_eax(unsigned int op)
618{
619 unsigned int eax, ebx, ecx, edx;
620
621 cpuid(op, &eax, &ebx, &ecx, &edx);
622 return eax;
623}
624static inline unsigned int cpuid_ebx(unsigned int op)
625{
626 unsigned int eax, ebx, ecx, edx;
627
628 cpuid(op, &eax, &ebx, &ecx, &edx);
629 return ebx;
630}
631static inline unsigned int cpuid_ecx(unsigned int op)
632{
633 unsigned int eax, ebx, ecx, edx;
634
635 cpuid(op, &eax, &ebx, &ecx, &edx);
636 return ecx;
637}
638static inline unsigned int cpuid_edx(unsigned int op)
639{
640 unsigned int eax, ebx, ecx, edx;
641
642 cpuid(op, &eax, &ebx, &ecx, &edx);
643 return edx;
644}
645
631/* generic versions from gas */ 646/* generic versions from gas */
632#define GENERIC_NOP1 ".byte 0x90\n" 647#define GENERIC_NOP1 ".byte 0x90\n"
633#define GENERIC_NOP2 ".byte 0x89,0xf6\n" 648#define GENERIC_NOP2 ".byte 0x89,0xf6\n"
@@ -727,4 +742,7 @@ extern unsigned long boot_option_idle_override;
727extern void enable_sep_cpu(void); 742extern void enable_sep_cpu(void);
728extern int sysenter_setup(void); 743extern int sysenter_setup(void);
729 744
745extern int init_gdt(int cpu, struct task_struct *idle);
746extern void secondary_cpu_init(void);
747
730#endif /* __ASM_I386_PROCESSOR_H */ 748#endif /* __ASM_I386_PROCESSOR_H */