Merge master.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6
[pandora-kernel.git] / arch / x86_64 / kernel / setup.c
index 99f038e..116a491 100644 (file)
@@ -40,6 +40,9 @@
 #include <linux/acpi.h>
 #include <linux/kallsyms.h>
 #include <linux/edd.h>
+#include <linux/mmzone.h>
+#include <linux/kexec.h>
+
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -348,7 +351,7 @@ static __init void parse_cmdline_early (char ** cmdline_p)
                if (!memcmp(from, "mem=", 4))
                        parse_memopt(from+4, &from); 
 
-#ifdef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NUMA
                if (!memcmp(from, "numa=", 5))
                        numa_setup(from+5); 
 #endif
@@ -365,6 +368,27 @@ static __init void parse_cmdline_early (char ** cmdline_p)
                if (!memcmp(from, "noexec=", 7))
                        nonx_setup(from + 7);
 
+#ifdef CONFIG_KEXEC
+               /* crashkernel=size@addr specifies the location to reserve for
+                * a crash kernel.  By reserving this memory we guarantee
+                * that linux never set's it up as a DMA target.
+                * Useful for holding code to do something appropriate
+                * after a kernel panic.
+                */
+               else if (!memcmp(from, "crashkernel=", 12)) {
+                       unsigned long size, base;
+                       size = memparse(from+12, &from);
+                       if (*from == '@') {
+                               base = memparse(from+1, &from);
+                               /* FIXME: Do I want a sanity check
+                                * to validate the memory range?
+                                */
+                               crashk_res.start = base;
+                               crashk_res.end   = base + size - 1;
+                       }
+               }
+#endif
+
        next_char:
                c = *(from++);
                if (!c)
@@ -377,17 +401,20 @@ static __init void parse_cmdline_early (char ** cmdline_p)
        *cmdline_p = command_line;
 }
 
-#ifndef CONFIG_DISCONTIGMEM
-static void __init contig_initmem_init(void)
+#ifndef CONFIG_NUMA
+static void __init
+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);
-        if (bootmap == -1L) 
-                panic("Cannot find bootmem map of size %ld\n",bootmap_size);
-        bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
-        e820_bootmem_free(&contig_page_data, 0, end_pfn << PAGE_SHIFT); 
-        reserve_bootmem(bootmap, bootmap_size);
+       unsigned long bootmap_size, bootmap;
+
+       memory_present(0, start_pfn, end_pfn);
+       bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
+       bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
+       if (bootmap == -1L)
+               panic("Cannot find bootmem map of size %ld\n",bootmap_size);
+       bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
+       e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT);
+       reserve_bootmem(bootmap, bootmap_size);
 } 
 #endif
 
@@ -554,10 +581,10 @@ void __init setup_arch(char **cmdline_p)
        acpi_numa_init();
 #endif
 
-#ifdef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NUMA
        numa_initmem_init(0, end_pfn); 
 #else
-       contig_initmem_init(); 
+       contig_initmem_init(0, end_pfn);
 #endif
 
        /* Reserve direct mapping */
@@ -618,6 +645,15 @@ void __init setup_arch(char **cmdline_p)
                }
        }
 #endif
+#ifdef CONFIG_KEXEC
+       if (crashk_res.start != crashk_res.end) {
+               reserve_bootmem(crashk_res.start,
+                       crashk_res.end - crashk_res.start + 1);
+       }
+#endif
+
+       sparse_init();
+
        paging_init();
 
        check_ioapic();
@@ -669,7 +705,7 @@ void __init setup_arch(char **cmdline_p)
 #endif
 }
 
-static int __init get_model_name(struct cpuinfo_x86 *c)
+static int __cpuinit get_model_name(struct cpuinfo_x86 *c)
 {
        unsigned int *v;
 
@@ -685,7 +721,7 @@ static int __init get_model_name(struct cpuinfo_x86 *c)
 }
 
 
-static void __init display_cacheinfo(struct cpuinfo_x86 *c)
+static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
 {
        unsigned int n, dummy, eax, ebx, ecx, edx;
 
@@ -729,8 +765,6 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
        int cpu = smp_processor_id();
        int node = 0;
        unsigned bits;
-       if (c->x86_num_cores == 1)
-               return;
 
        bits = 0;
        while ((1 << bits) < c->x86_num_cores)
@@ -796,7 +830,7 @@ static int __init init_amd(struct cpuinfo_x86 *c)
        return r;
 }
 
-static void __init detect_ht(struct cpuinfo_x86 *c)
+static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_SMP
        u32     eax, ebx, ecx, edx;
@@ -857,7 +891,7 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
 /*
  * find out the number of processor cores on the die
  */
-static int __init intel_num_cpu_cores(struct cpuinfo_x86 *c)
+static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
 {
        unsigned int eax;
 
@@ -875,7 +909,7 @@ static int __init intel_num_cpu_cores(struct cpuinfo_x86 *c)
                return 1;
 }
 
-static void __init init_intel(struct cpuinfo_x86 *c)
+static void __cpuinit init_intel(struct cpuinfo_x86 *c)
 {
        /* Cache sizes */
        unsigned n;
@@ -895,7 +929,7 @@ static void __init init_intel(struct cpuinfo_x86 *c)
        c->x86_num_cores = intel_num_cpu_cores(c);
 }
 
-void __init get_cpu_vendor(struct cpuinfo_x86 *c)
+void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
 {
        char *v = c->x86_vendor_id;
 
@@ -916,7 +950,7 @@ struct cpu_model_info {
 /* 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. */
-void __init early_identify_cpu(struct cpuinfo_x86 *c)
+void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
 {
        u32 tfms;
 
@@ -970,7 +1004,7 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c)
 /*
  * This does the hard work of actually picking apart the CPU stuff...
  */
-void __init identify_cpu(struct cpuinfo_x86 *c)
+void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
 {
        int i;
        u32 xlvl;
@@ -1040,14 +1074,17 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
 #ifdef CONFIG_X86_MCE
        mcheck_init(c);
 #endif
+       if (c == &boot_cpu_data)
+               mtrr_bp_init();
+       else
+               mtrr_ap_init();
 #ifdef CONFIG_NUMA
-       if (c != &boot_cpu_data)
-               numa_add_cpu(c - cpu_data);
+       numa_add_cpu(smp_processor_id());
 #endif
 }
  
 
-void __init print_cpu_info(struct cpuinfo_x86 *c)
+void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
 {
        if (c->x86_model_id[0])
                printk("%s", c->x86_model_id);