]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kernel/cpu/common.c
x86: add noclflush option
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / cpu / common.c
index d506201d397c5fb2e13b364189a37d058876dd46..56b7ea8e6c79b2330677c20292a1f21dd2ecc34c 100644 (file)
 #include "cpu.h"
 
 DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
-       [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 },
-       [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 },
-       [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 },
-       [GDT_ENTRY_DEFAULT_USER_DS] = { 0x0000ffff, 0x00cff200 },
+       [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
+       [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
+       [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
+       [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
        /*
         * Segments used for calling PnP BIOS have byte granularity.
         * They code segments and data segments have fixed 64k limits,
         * the transfer segment sizes are set at run time.
         */
-       [GDT_ENTRY_PNPBIOS_CS32] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
-       [GDT_ENTRY_PNPBIOS_CS16] = { 0x0000ffff, 0x00009a00 },/* 16-bit code */
-       [GDT_ENTRY_PNPBIOS_DS] = { 0x0000ffff, 0x00009200 }, /* 16-bit data */
-       [GDT_ENTRY_PNPBIOS_TS1] = { 0x00000000, 0x00009200 },/* 16-bit data */
-       [GDT_ENTRY_PNPBIOS_TS2] = { 0x00000000, 0x00009200 },/* 16-bit data */
+       /* 32-bit code */
+       [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
+       /* 16-bit code */
+       [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
+       /* 16-bit data */
+       [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
+       /* 16-bit data */
+       [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
+       /* 16-bit data */
+       [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
        /*
         * The APM segments have byte granularity and their bases
         * are set at run time.  All have 64k limits.
         */
-       [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
+       /* 32-bit code */
+       [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
        /* 16-bit code */
-       [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 },
-       [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */
+       [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
+       /* data */
+       [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
 
-       [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 },
-       [GDT_ENTRY_PERCPU] = { 0x00000000, 0x00000000 },
+       [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
+       [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
 } };
 EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
 
+__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
+
 static int cachesize_override __cpuinitdata = -1;
-static int disable_x86_fxsr __cpuinitdata;
 static int disable_x86_serial_nr __cpuinitdata = 1;
-static int disable_x86_sep __cpuinitdata;
 
 struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
 
-extern int disable_pse;
-
 static void __cpuinit default_init(struct cpuinfo_x86 * c)
 {
        /* Not much we can do here... */
@@ -207,16 +212,8 @@ static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
 
 static int __init x86_fxsr_setup(char * s)
 {
-       /* Tell all the other CPU's to not use it... */
-       disable_x86_fxsr = 1;
-
-       /*
-        * ... and clear the bits early in the boot_cpu_data
-        * so that the bootup process doesn't try to do this
-        * either.
-        */
-       clear_bit(X86_FEATURE_FXSR, boot_cpu_data.x86_capability);
-       clear_bit(X86_FEATURE_XMM, boot_cpu_data.x86_capability);
+       setup_clear_cpu_cap(X86_FEATURE_FXSR);
+       setup_clear_cpu_cap(X86_FEATURE_XMM);
        return 1;
 }
 __setup("nofxsr", x86_fxsr_setup);
@@ -224,7 +221,7 @@ __setup("nofxsr", x86_fxsr_setup);
 
 static int __init x86_sep_setup(char * s)
 {
-       disable_x86_sep = 1;
+       setup_clear_cpu_cap(X86_FEATURE_SEP);
        return 1;
 }
 __setup("nosep", x86_sep_setup);
@@ -300,6 +297,15 @@ static void __init early_cpu_detect(void)
        cpu_detect(c);
 
        get_cpu_vendor(c, 1);
+
+       switch (c->x86_vendor) {
+       case X86_VENDOR_AMD:
+               early_init_amd(c);
+               break;
+       case X86_VENDOR_INTEL:
+               early_init_intel(c);
+               break;
+       }
 }
 
 static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
@@ -357,8 +363,6 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
                init_scattered_cpuid_features(c);
        }
 
-       early_intel_workaround(c);
-
 #ifdef CONFIG_X86_HT
        c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff;
 #endif
@@ -392,7 +396,7 @@ __setup("serialnumber", x86_serial_nr_setup);
 /*
  * This does the hard work of actually picking apart the CPU stuff...
  */
-static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
+void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
 {
        int i;
 
@@ -418,20 +422,9 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
 
        generic_identify(c);
 
-       printk(KERN_DEBUG "CPU: After generic identify, caps:");
-       for (i = 0; i < NCAPINTS; i++)
-               printk(" %08lx", c->x86_capability[i]);
-       printk("\n");
-
-       if (this_cpu->c_identify) {
+       if (this_cpu->c_identify)
                this_cpu->c_identify(c);
 
-               printk(KERN_DEBUG "CPU: After vendor identify, caps:");
-               for (i = 0; i < NCAPINTS; i++)
-                       printk(" %08lx", c->x86_capability[i]);
-               printk("\n");
-       }
-
        /*
         * Vendor-specific initialization.  In this section we
         * canonicalize the feature flags, meaning if there are
@@ -453,23 +446,6 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
         * we do "generic changes."
         */
 
-       /* TSC disabled? */
-       if ( tsc_disable )
-               clear_bit(X86_FEATURE_TSC, c->x86_capability);
-
-       /* FXSR disabled? */
-       if (disable_x86_fxsr) {
-               clear_bit(X86_FEATURE_FXSR, c->x86_capability);
-               clear_bit(X86_FEATURE_XMM, c->x86_capability);
-       }
-
-       /* SEP disabled? */
-       if (disable_x86_sep)
-               clear_bit(X86_FEATURE_SEP, c->x86_capability);
-
-       if (disable_pse)
-               clear_bit(X86_FEATURE_PSE, c->x86_capability);
-
        /* If the model name is still unset, do table lookup. */
        if ( !c->x86_model_id[0] ) {
                char *p;
@@ -482,13 +458,6 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
                                c->x86, c->x86_model);
        }
 
-       /* Now the feature flags better reflect actual CPU features! */
-
-       printk(KERN_DEBUG "CPU: After all inits, caps:");
-       for (i = 0; i < NCAPINTS; i++)
-               printk(" %08lx", c->x86_capability[i]);
-       printk("\n");
-
        /*
         * On SMP, boot_cpu_data holds the common feature set between
         * all CPUs; so make sure that we indicate which features are
@@ -501,8 +470,14 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
                        boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
        }
 
+       /* Clear all flags overriden by options */
+       for (i = 0; i < NCAPINTS; i++)
+               c->x86_capability[i] ^= cleared_cpu_caps[i];
+
        /* Init Machine Check Exception if available. */
        mcheck_init(c);
+
+       select_idle_routine(c);
 }
 
 void __init identify_boot_cpu(void)
@@ -567,6 +542,13 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c)
 }
 #endif
 
+static __init int setup_noclflush(char *arg)
+{
+       setup_clear_cpu_cap(X86_FEATURE_CLFLSH);
+       return 1;
+}
+__setup("noclflush", setup_noclflush);
+
 void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
 {
        char *vendor = NULL;
@@ -625,8 +607,7 @@ void __init early_cpu_init(void)
        /* pse is not compatible with on-the-fly unmapping,
         * disable it even if the cpus claim to support it.
         */
-       clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability);
-       disable_pse = 1;
+       setup_clear_cpu_cap(X86_FEATURE_PSE);
 #endif
 }
 
@@ -634,7 +615,7 @@ void __init early_cpu_init(void)
 struct pt_regs * __devinit idle_regs(struct pt_regs *regs)
 {
        memset(regs, 0, sizeof(struct pt_regs));
-       regs->xfs = __KERNEL_PERCPU;
+       regs->fs = __KERNEL_PERCPU;
        return regs;
 }
 
@@ -642,7 +623,7 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs)
  * it's on the real one. */
 void switch_to_new_gdt(void)
 {
-       struct Xgt_desc_struct gdt_descr;
+       struct desc_ptr gdt_descr;
 
        gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
        gdt_descr.size = GDT_SIZE - 1;
@@ -672,12 +653,6 @@ void __cpuinit cpu_init(void)
 
        if (cpu_has_vme || cpu_has_tsc || cpu_has_de)
                clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
-       if (tsc_disable && cpu_has_tsc) {
-               printk(KERN_NOTICE "Disabling TSC...\n");
-               /**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/
-               clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability);
-               set_in_cr4(X86_CR4_TSD);
-       }
 
        load_idt(&idt_descr);
        switch_to_new_gdt();
@@ -691,7 +666,7 @@ void __cpuinit cpu_init(void)
                BUG();
        enter_lazy_tlb(&init_mm, curr);
 
-       load_esp0(t, thread);
+       load_sp0(t, thread);
        set_tss_desc(cpu,t);
        load_TR_desc();
        load_LDT(&init_mm.context);