]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kernel/setup_64.c
x86: unify CPU feature string names
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / setup_64.c
index 8618178db8427ce1b9bd69cff01e663d31d91ae8..c8939dfddfba3c0f7bdd63e3d21d6d38e67712fc 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/ctype.h>
 #include <linux/uaccess.h>
+#include <linux/init_ohci1394_dma.h>
 
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
@@ -53,6 +54,7 @@
 #include <video/edid.h>
 #include <asm/e820.h>
 #include <asm/dma.h>
+#include <asm/gart.h>
 #include <asm/mpspec.h>
 #include <asm/mmu_context.h>
 #include <asm/proto.h>
@@ -64,6 +66,7 @@
 #include <asm/cacheflush.h>
 #include <asm/mce.h>
 #include <asm/ds.h>
+#include <asm/topology.h>
 
 #ifdef CONFIG_PARAVIRT
 #include <asm/paravirt.h>
@@ -78,6 +81,8 @@
 struct cpuinfo_x86 boot_cpu_data __read_mostly;
 EXPORT_SYMBOL(boot_cpu_data);
 
+__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
+
 unsigned long mmu_cr4_features;
 
 /* Boot loader ID as an integer, for the benefit of proc_dointvec */
@@ -177,7 +182,8 @@ contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
        unsigned long bootmap_size, bootmap;
 
        bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
-       bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
+       bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size,
+                                PAGE_SIZE);
        if (bootmap == -1L)
                panic("Cannot find bootmem map of size %ld\n", bootmap_size);
        bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
@@ -243,47 +249,17 @@ static inline void __init reserve_crashkernel(void)
 {}
 #endif
 
-#define EBDA_ADDR_POINTER 0x40E
-
-unsigned __initdata ebda_addr;
-unsigned __initdata ebda_size;
-
-static void discover_ebda(void)
-{
-       /*
-        * there is a real-mode segmented pointer pointing to the
-        * 4K EBDA area at 0x40E
-        */
-       ebda_addr = *(unsigned short *)__va(EBDA_ADDR_POINTER);
-       /*
-        * There can be some situations, like paravirtualized guests,
-        * in which there is no available ebda information. In such
-        * case, just skip it
-        */
-       if (!ebda_addr) {
-               ebda_size = 0;
-               return;
-       }
-
-       ebda_addr <<= 4;
-
-       ebda_size = *(unsigned short *)__va(ebda_addr);
-
-       /* Round EBDA up to pages */
-       if (ebda_size == 0)
-               ebda_size = 1;
-       ebda_size <<= 10;
-       ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE);
-       if (ebda_size > 64*1024)
-               ebda_size = 64*1024;
-}
-
 /* Overridden in paravirt.c if CONFIG_PARAVIRT */
-void __attribute__((weak)) memory_setup(void)
+void __attribute__((weak)) __init memory_setup(void)
 {
        machine_specific_memory_setup();
 }
 
+/*
+ * setup_arch - architecture-specific boot-time initializations
+ *
+ * Note: On x86_64, fixmaps are ready for use even before this is called.
+ */
 void __init setup_arch(char **cmdline_p)
 {
        unsigned i;
@@ -333,20 +309,32 @@ void __init setup_arch(char **cmdline_p)
 
        parse_early_param();
 
+#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
+       if (init_ohci1394_dma_early)
+               init_ohci1394_dma_on_all_controllers();
+#endif
+
        finish_e820_parsing();
 
+       early_gart_iommu_check();
+
        e820_register_active_regions(0, 0, -1UL);
        /*
         * partially used pages are not usable - thus
         * we are rounding upwards:
         */
        end_pfn = e820_end_of_ram();
+       /* update e820 for memory not covered by WB MTRRs */
+       mtrr_bp_init();
+       if (mtrr_trim_uncached_memory(end_pfn)) {
+               e820_register_active_regions(0, 0, -1UL);
+               end_pfn = e820_end_of_ram();
+       }
+
        num_physpages = end_pfn;
 
        check_efer();
 
-       discover_ebda();
-
        init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
        if (efi_enabled)
                efi_init();
@@ -356,8 +344,12 @@ void __init setup_arch(char **cmdline_p)
        io_delay_init();
 
 #ifdef CONFIG_SMP
-       /* setup to use the static apicid table during kernel startup */
-       x86_cpu_to_apicid_ptr = (void *)&x86_cpu_to_apicid_init;
+       /* setup to use the early static init tables during kernel startup */
+       x86_cpu_to_apicid_early_ptr = (void *)x86_cpu_to_apicid_init;
+       x86_bios_cpu_apicid_early_ptr = (void *)x86_bios_cpu_apicid_init;
+#ifdef CONFIG_NUMA
+       x86_cpu_to_node_map_early_ptr = (void *)x86_cpu_to_node_map_init;
+#endif
 #endif
 
 #ifdef CONFIG_ACPI
@@ -389,33 +381,7 @@ void __init setup_arch(char **cmdline_p)
        contig_initmem_init(0, end_pfn);
 #endif
 
-       /* Reserve direct mapping */
-       reserve_bootmem_generic(table_start << PAGE_SHIFT,
-                               (table_end - table_start) << PAGE_SHIFT);
-
-       /* reserve kernel */
-       reserve_bootmem_generic(__pa_symbol(&_text),
-                               __pa_symbol(&_end) - __pa_symbol(&_text));
-
-       /*
-        * reserve physical page 0 - it's a special BIOS page on many boxes,
-        * enabling clean reboots, SMP operation, laptop functions.
-        */
-       reserve_bootmem_generic(0, PAGE_SIZE);
-
-       /* reserve ebda region */
-       if (ebda_addr)
-               reserve_bootmem_generic(ebda_addr, ebda_size);
-#ifdef CONFIG_NUMA
-       /* reserve nodemap region */
-       if (nodemap_addr)
-               reserve_bootmem_generic(nodemap_addr, nodemap_size);
-#endif
-
-#ifdef CONFIG_SMP
-       /* Reserve SMP trampoline */
-       reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, 2*PAGE_SIZE);
-#endif
+       early_res_to_bootmem();
 
 #ifdef CONFIG_ACPI_SLEEP
        /*
@@ -424,10 +390,8 @@ void __init setup_arch(char **cmdline_p)
        acpi_reserve_bootmem();
 #endif
 
-       if (efi_enabled) {
-               efi_map_memmap();
+       if (efi_enabled)
                efi_reserve_bootmem();
-       }
 
        /*
        * Find and reserve possible boot-time SMP configuration:
@@ -445,6 +409,8 @@ void __init setup_arch(char **cmdline_p)
                        initrd_start = ramdisk_image + PAGE_OFFSET;
                        initrd_end = initrd_start+ramdisk_size;
                } else {
+                       /* Assumes everything on node 0 */
+                       free_bootmem(ramdisk_image, ramdisk_size);
                        printk(KERN_ERR "initrd extends beyond end of memory "
                               "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
                               ramdisk_end, end_of_mem);
@@ -458,12 +424,6 @@ void __init setup_arch(char **cmdline_p)
 
        early_quirks();
 
-       /*
-        * set this early, so we dont allocate cpu0
-        * if MADT list doesnt list BSP first
-        * mpparse.c/MP_processor_info() allocates logical cpu numbers.
-        */
-       cpu_set(0, cpu_present_map);
 #ifdef CONFIG_ACPI
        /*
         * Read APIC and some other early information from ACPI tables.
@@ -544,9 +504,6 @@ static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
                printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
                c->x86_cache_size, ecx & 0xFF);
        }
-
-       if (n >= 0x80000007)
-               cpuid(0x80000007, &dummy, &dummy, &dummy, &c->x86_power);
        if (n >= 0x80000008) {
                cpuid(0x80000008, &eax, &dummy, &dummy, &dummy);
                c->x86_virt_bits = (eax >> 8) & 0xff;
@@ -577,7 +534,7 @@ static int nearby_node(int apicid)
  * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
  * Assumes number of cores is a power of two.
  */
-static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
+static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_SMP
        unsigned bits;
@@ -624,7 +581,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
 #endif
 }
 
-static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
+static void __cpuinit early_init_amd_mc(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_SMP
        unsigned bits, ecx;
@@ -682,6 +639,15 @@ static __cpuinit int amd_apic_timer_broken(void)
        return 0;
 }
 
+static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
+{
+       early_init_amd_mc(c);
+
+       /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */
+       if (c->x86_power & (1<<8))
+               set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
+}
+
 static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 {
        unsigned level;
@@ -731,10 +697,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
        }
        display_cacheinfo(c);
 
-       /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */
-       if (c->x86_power & (1<<8))
-               set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
-
        /* Multi core CPU? */
        if (c->extended_cpuid_level >= 0x80000008)
                amd_detect_cmp(c);
@@ -751,10 +713,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
        /* MFENCE stops RDTSC speculation */
        set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
 
-       /* Family 10 doesn't support C states in MWAIT so don't use it */
-       if (c->x86 == 0x10 && !force_mwait)
-               clear_cpu_cap(c, X86_FEATURE_MWAIT);
-
        if (amd_apic_timer_broken())
                disable_apic_timer = 1;
 }
@@ -845,6 +803,13 @@ static void srat_detect_node(void)
 #endif
 }
 
+static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
+{
+       if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
+           (c->x86 == 0x6 && c->x86_model >= 0x0e))
+               set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
+}
+
 static void __cpuinit init_intel(struct cpuinfo_x86 *c)
 {
        /* Cache sizes */
@@ -908,12 +873,6 @@ static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
                c->x86_vendor = X86_VENDOR_UNKNOWN;
 }
 
-struct cpu_model_info {
-       int vendor;
-       int family;
-       char *model_names[16];
-};
-
 /* Do some early cpuid on the boot CPU to get some parameter that are
    needed before check_bugs. Everything advanced is in identify_cpu
    below. */
@@ -987,10 +946,17 @@ static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
                        c->x86_capability[2] = cpuid_edx(0x80860001);
        }
 
+       c->extended_cpuid_level = cpuid_eax(0x80000000);
+       if (c->extended_cpuid_level >= 0x80000007)
+               c->x86_power = cpuid_edx(0x80000007);
+
        switch (c->x86_vendor) {
        case X86_VENDOR_AMD:
                early_init_amd(c);
                break;
+       case X86_VENDOR_INTEL:
+               early_init_intel(c);
+               break;
        }
 
 }
@@ -1033,7 +999,6 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
                break;
        }
 
-       select_idle_routine(c);
        detect_ht(c);
 
        /*
@@ -1048,15 +1013,29 @@ 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];
+
 #ifdef CONFIG_X86_MCE
        mcheck_init(c);
 #endif
+       select_idle_routine(c);
+
        if (c != &boot_cpu_data)
                mtrr_ap_init();
 #ifdef CONFIG_NUMA
        numa_add_cpu(smp_processor_id());
 #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)
 {
@@ -1069,6 +1048,17 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
                printk(KERN_CONT "\n");
 }
 
+static __init int setup_disablecpuid(char *arg)
+{
+       int bit;
+       if (get_option(&arg, &bit) && bit < NCAPINTS*32)
+               setup_clear_cpu_cap(bit);
+       else
+               return 0;
+       return 1;
+}
+__setup("clearcpuid=", setup_disablecpuid);
+
 /*
  *     Get CPU information for use by the procfs.
  */
@@ -1078,82 +1068,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        struct cpuinfo_x86 *c = v;
        int cpu = 0, i;
 
-       /*
-        * These flag bits must match the definitions in <asm/cpufeature.h>.
-        * NULL means this bit is undefined or reserved; either way it doesn't
-        * have meaning as far as Linux is concerned.  Note that it's important
-        * to realize there is a difference between this table and CPUID -- if
-        * applications want to get the raw CPUID data, they should access
-        * /dev/cpu/<cpu_nr>/cpuid instead.
-        */
-       static const char *const x86_cap_flags[] = {
-               /* Intel-defined */
-               "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
-               "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
-               "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
-               "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
-
-               /* AMD-defined */
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL,
-               NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm",
-               "3dnowext", "3dnow",
-
-               /* Transmeta-defined */
-               "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-
-               /* Other (Linux-defined) */
-               "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
-               NULL, NULL, NULL, NULL,
-               "constant_tsc", "up", NULL, "arch_perfmon",
-               "pebs", "bts", NULL, "sync_rdtsc",
-               "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-
-               /* Intel-defined (#2) */
-               "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est",
-               "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
-               NULL, NULL, "dca", "sse4_1", "sse4_2", NULL, NULL, "popcnt",
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-
-               /* VIA/Cyrix/Centaur-defined */
-               NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
-               "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-
-               /* AMD-defined (#2) */
-               "lahf_lm", "cmp_legacy", "svm", "extapic",
-               "cr8_legacy", "abm", "sse4a", "misalignsse",
-               "3dnowprefetch", "osvw", "ibs", "sse5",
-               "skinit", "wdt", NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-
-               /* Auxiliary (Linux-defined) */
-               "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-       };
-       static const char *const x86_power_flags[] = {
-               "ts",   /* temperature sensor */
-               "fid",  /* frequency id control */
-               "vid",  /* voltage id control */
-               "ttp",  /* thermal trip */
-               "tm",
-               "stc",
-               "100mhzsteps",
-               "hwpstate",
-               "",     /* tsc invariant mapped to constant_tsc */
-               /* nothing */
-       };
-
-
 #ifdef CONFIG_SMP
        cpu = c->cpu_index;
 #endif
@@ -1258,7 +1172,7 @@ static void c_stop(struct seq_file *m, void *v)
 {
 }
 
-struct seq_operations cpuinfo_op = {
+const struct seq_operations cpuinfo_op = {
        .start = c_start,
        .next = c_next,
        .stop = c_stop,