[PATCH] ARM SMP: Rename cpu_present_mask to cpu_possible_map
[powerpc.git] / arch / arm / kernel / setup.c
index c2a7da3..c9b6977 100644 (file)
@@ -92,6 +92,14 @@ struct cpu_user_fns cpu_user;
 struct cpu_cache_fns cpu_cache;
 #endif
 
+struct stack {
+       u32 irq[3];
+       u32 abt[3];
+       u32 und[3];
+} ____cacheline_aligned;
+
+static struct stack stacks[NR_CPUS];
+
 char elf_platform[ELF_PLATFORM_SIZE];
 EXPORT_SYMBOL(elf_platform);
 
@@ -307,8 +315,6 @@ static void __init setup_processor(void)
               cpu_name, processor_id, (int)processor_id & 15,
               proc_arch[cpu_architecture()]);
 
-       dump_cpu_info(smp_processor_id());
-
        sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
        sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
        elf_hwcap = list->elf_hwcap;
@@ -316,6 +322,47 @@ static void __init setup_processor(void)
        cpu_proc_init();
 }
 
+/*
+ * cpu_init - initialise one CPU.
+ *
+ * cpu_init dumps the cache information, initialises SMP specific
+ * information, and sets up the per-CPU stacks.
+ */
+void cpu_init(void)
+{
+       unsigned int cpu = smp_processor_id();
+       struct stack *stk = &stacks[cpu];
+
+       if (cpu >= NR_CPUS) {
+               printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
+               BUG();
+       }
+
+       dump_cpu_info(cpu);
+
+       /*
+        * setup stacks for re-entrant exception handlers
+        */
+       __asm__ (
+       "msr    cpsr_c, %1\n\t"
+       "add    sp, %0, %2\n\t"
+       "msr    cpsr_c, %3\n\t"
+       "add    sp, %0, %4\n\t"
+       "msr    cpsr_c, %5\n\t"
+       "add    sp, %0, %6\n\t"
+       "msr    cpsr_c, %7"
+           :
+           : "r" (stk),
+             "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
+             "I" (offsetof(struct stack, irq[0])),
+             "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
+             "I" (offsetof(struct stack, abt[0])),
+             "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
+             "I" (offsetof(struct stack, und[0])),
+             "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
+           : "r14");
+}
+
 static struct machine_desc * __init setup_machine(unsigned int nr)
 {
        struct machine_desc *list;
@@ -349,6 +396,20 @@ static void __init early_initrd(char **p)
 }
 __early_param("initrd=", early_initrd);
 
+static void __init add_memory(unsigned long start, unsigned long size)
+{
+       /*
+        * Ensure that start/size are aligned to a page boundary.
+        * Size is appropriately rounded down, start is rounded up.
+        */
+       size -= start & ~PAGE_MASK;
+
+       meminfo.bank[meminfo.nr_banks].start = PAGE_ALIGN(start);
+       meminfo.bank[meminfo.nr_banks].size  = size & PAGE_MASK;
+       meminfo.bank[meminfo.nr_banks].node  = PHYS_TO_NID(start);
+       meminfo.nr_banks += 1;
+}
+
 /*
  * Pick out the memory size.  We look for mem=size@start,
  * where start and size are "size[KkMm]"
@@ -373,10 +434,7 @@ static void __init early_mem(char **p)
        if (**p == '@')
                start = memparse(*p + 1, p);
 
-       meminfo.bank[meminfo.nr_banks].start = start;
-       meminfo.bank[meminfo.nr_banks].size  = size;
-       meminfo.bank[meminfo.nr_banks].node  = PHYS_TO_NID(start);
-       meminfo.nr_banks += 1;
+       add_memory(start, size);
 }
 __early_param("mem=", early_mem);
 
@@ -518,11 +576,7 @@ static int __init parse_tag_mem32(const struct tag *tag)
                        tag->u.mem.start, tag->u.mem.size / 1024);
                return -EINVAL;
        }
-       meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start;
-       meminfo.bank[meminfo.nr_banks].size  = tag->u.mem.size;
-       meminfo.bank[meminfo.nr_banks].node  = PHYS_TO_NID(tag->u.mem.start);
-       meminfo.nr_banks += 1;
-
+       add_memory(tag->u.mem.start, tag->u.mem.size);
        return 0;
 }
 
@@ -683,8 +737,8 @@ void __init setup_arch(char **cmdline_p)
        if (mdesc->soft_reboot)
                reboot_setup("s");
 
-       if (mdesc->param_offset)
-               tags = phys_to_virt(mdesc->param_offset);
+       if (mdesc->boot_params)
+               tags = phys_to_virt(mdesc->boot_params);
 
        /*
         * If we have the old style parameters, convert them to
@@ -715,6 +769,8 @@ void __init setup_arch(char **cmdline_p)
        paging_init(&meminfo, mdesc);
        request_standard_resources(&meminfo, mdesc);
 
+       cpu_init();
+
        /*
         * Set up various architecture-specific pointers
         */