Merge branches 'fixes', 'pgt-next' and 'versatile' into devel
[pandora-kernel.git] / arch / arm / kernel / setup.c
index 9d4a844..d149539 100644 (file)
@@ -75,9 +75,9 @@ extern void reboot_setup(char *str);
 
 unsigned int processor_id;
 EXPORT_SYMBOL(processor_id);
-unsigned int __machine_arch_type;
+unsigned int __machine_arch_type __read_mostly;
 EXPORT_SYMBOL(__machine_arch_type);
-unsigned int cacheid;
+unsigned int cacheid __read_mostly;
 EXPORT_SYMBOL(cacheid);
 
 unsigned int __atags_pointer __initdata;
@@ -91,24 +91,24 @@ EXPORT_SYMBOL(system_serial_low);
 unsigned int system_serial_high;
 EXPORT_SYMBOL(system_serial_high);
 
-unsigned int elf_hwcap;
+unsigned int elf_hwcap __read_mostly;
 EXPORT_SYMBOL(elf_hwcap);
 
 
 #ifdef MULTI_CPU
-struct processor processor;
+struct processor processor __read_mostly;
 #endif
 #ifdef MULTI_TLB
-struct cpu_tlb_fns cpu_tlb;
+struct cpu_tlb_fns cpu_tlb __read_mostly;
 #endif
 #ifdef MULTI_USER
-struct cpu_user_fns cpu_user;
+struct cpu_user_fns cpu_user __read_mostly;
 #endif
 #ifdef MULTI_CACHE
-struct cpu_cache_fns cpu_cache;
+struct cpu_cache_fns cpu_cache __read_mostly;
 #endif
 #ifdef CONFIG_OUTER_CACHE
-struct outer_cache_fns outer_cache;
+struct outer_cache_fns outer_cache __read_mostly;
 EXPORT_SYMBOL(outer_cache);
 #endif
 
@@ -126,6 +126,7 @@ EXPORT_SYMBOL(elf_platform);
 static const char *cpu_name;
 static const char *machine_name;
 static char __initdata cmd_line[COMMAND_LINE_SIZE];
+struct machine_desc *machine_desc __initdata;
 
 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
 static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
@@ -225,8 +226,8 @@ int cpu_architecture(void)
                 * Register 0 and check for VMSAv7 or PMSAv7 */
                asm("mrc        p15, 0, %0, c0, c1, 4"
                    : "=r" (mmfr0));
-               if ((mmfr0 & 0x0000000f) == 0x00000003 ||
-                   (mmfr0 & 0x000000f0) == 0x00000030)
+               if ((mmfr0 & 0x0000000f) >= 0x00000003 ||
+                   (mmfr0 & 0x000000f0) >= 0x00000030)
                        cpu_arch = CPU_ARCH_ARMv7;
                else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
                         (mmfr0 & 0x000000f0) == 0x00000020)
@@ -307,7 +308,22 @@ static void __init cacheid_init(void)
  * already provide the required functionality.
  */
 extern struct proc_info_list *lookup_processor_type(unsigned int);
-extern struct machine_desc *lookup_machine_type(unsigned int);
+
+static void __init early_print(const char *str, ...)
+{
+       extern void printascii(const char *);
+       char buf[256];
+       va_list ap;
+
+       va_start(ap, str);
+       vsnprintf(buf, sizeof(buf), str, ap);
+       va_end(ap);
+
+#ifdef CONFIG_DEBUG_LL
+       printascii(buf);
+#endif
+       printk("%s", buf);
+}
 
 static void __init feat_v6_fixup(void)
 {
@@ -425,21 +441,29 @@ void cpu_init(void)
 
 static struct machine_desc * __init setup_machine(unsigned int nr)
 {
-       struct machine_desc *list;
+       extern struct machine_desc __arch_info_begin[], __arch_info_end[];
+       struct machine_desc *p;
 
        /*
         * locate machine in the list of supported machines.
         */
-       list = lookup_machine_type(nr);
-       if (!list) {
-               printk("Machine configuration botched (nr %d), unable "
-                      "to continue.\n", nr);
-               while (1);
-       }
+       for (p = __arch_info_begin; p < __arch_info_end; p++)
+               if (nr == p->nr) {
+                       printk("Machine: %s\n", p->name);
+                       return p;
+               }
+
+       early_print("\n"
+               "Error: unrecognized/unsupported machine ID (r1 = 0x%08x).\n\n"
+               "Available machine support:\n\nID (hex)\tNAME\n", nr);
+
+       for (p = __arch_info_begin; p < __arch_info_end; p++)
+               early_print("%08x\t%s\n", p->nr, p->name);
 
-       printk("Machine: %s\n", list->name);
+       early_print("\nPlease check your kernel config and/or bootloader.\n");
 
-       return list;
+       while (true)
+               /* can't use cpu_relax() here as it may require MMU setup */;
 }
 
 static int __init arm_add_memory(phys_addr_t start, unsigned long size)
@@ -518,25 +542,21 @@ setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
 #endif
 }
 
-static void __init
-request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
+static void __init request_standard_resources(struct machine_desc *mdesc)
 {
+       struct memblock_region *region;
        struct resource *res;
-       int i;
 
        kernel_code.start   = virt_to_phys(_text);
        kernel_code.end     = virt_to_phys(_etext - 1);
        kernel_data.start   = virt_to_phys(_sdata);
        kernel_data.end     = virt_to_phys(_end - 1);
 
-       for (i = 0; i < mi->nr_banks; i++) {
-               if (mi->bank[i].size == 0)
-                       continue;
-
+       for_each_memblock(memory, region) {
                res = alloc_bootmem_low(sizeof(*res));
                res->name  = "System RAM";
-               res->start = mi->bank[i].start;
-               res->end   = mi->bank[i].start + mi->bank[i].size - 1;
+               res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
+               res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
                res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 
                request_resource(&iomem_resource, res);
@@ -650,15 +670,17 @@ static int __init parse_tag_revision(const struct tag *tag)
 
 __tagtable(ATAG_REVISION, parse_tag_revision);
 
-#ifndef CONFIG_CMDLINE_FORCE
 static int __init parse_tag_cmdline(const struct tag *tag)
 {
+#ifndef CONFIG_CMDLINE_FORCE
        strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
+#else
+       pr_warning("Ignoring tag cmdline (using the default kernel command line)\n");
+#endif /* CONFIG_CMDLINE_FORCE */
        return 0;
 }
 
 __tagtable(ATAG_CMDLINE, parse_tag_cmdline);
-#endif /* CONFIG_CMDLINE_FORCE */
 
 /*
  * Scan the tag table for this tag, and call its parse function.
@@ -705,17 +727,15 @@ static struct init_tags {
        { tag_size(tag_core), ATAG_CORE },
        { 1, PAGE_SIZE, 0xff },
        { tag_size(tag_mem32), ATAG_MEM },
-       { MEM_SIZE, PHYS_OFFSET },
+       { MEM_SIZE },
        { 0, ATAG_NONE }
 };
 
-static void (*init_machine)(void) __initdata;
-
 static int __init customize_machine(void)
 {
        /* customizes platform devices, or adds new ones */
-       if (init_machine)
-               init_machine();
+       if (machine_desc->init_machine)
+               machine_desc->init_machine();
        return 0;
 }
 arch_initcall(customize_machine);
@@ -806,10 +826,13 @@ void __init setup_arch(char **cmdline_p)
        struct machine_desc *mdesc;
        char *from = default_command_line;
 
+       init_tags.mem.start = PHYS_OFFSET;
+
        unwind_init();
 
        setup_processor();
        mdesc = setup_machine(machine_arch_type);
+       machine_desc = mdesc;
        machine_name = mdesc->name;
 
        if (mdesc->soft_reboot)
@@ -817,8 +840,25 @@ void __init setup_arch(char **cmdline_p)
 
        if (__atags_pointer)
                tags = phys_to_virt(__atags_pointer);
-       else if (mdesc->boot_params)
-               tags = phys_to_virt(mdesc->boot_params);
+       else if (mdesc->boot_params) {
+#ifdef CONFIG_MMU
+               /*
+                * We still are executing with a minimal MMU mapping created
+                * with the presumption that the machine default for this
+                * is located in the first MB of RAM.  Anything else will
+                * fault and silently hang the kernel at this point.
+                */
+               if (mdesc->boot_params < PHYS_OFFSET ||
+                   mdesc->boot_params >= PHYS_OFFSET + SZ_1M) {
+                       printk(KERN_WARNING
+                              "Default boot params at physical 0x%08lx out of reach\n",
+                              mdesc->boot_params);
+               } else
+#endif
+               {
+                       tags = phys_to_virt(mdesc->boot_params);
+               }
+       }
 
 #if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
        /*
@@ -858,7 +898,7 @@ void __init setup_arch(char **cmdline_p)
        arm_memblock_init(&meminfo, mdesc);
 
        paging_init(mdesc);
-       request_standard_resources(&meminfo, mdesc);
+       request_standard_resources(mdesc);
 
 #ifdef CONFIG_SMP
        if (is_smp())
@@ -869,13 +909,9 @@ void __init setup_arch(char **cmdline_p)
        cpu_init();
        tcm_init();
 
-       /*
-        * Set up various architecture-specific pointers
-        */
-       arch_nr_irqs = mdesc->nr_irqs;
-       init_arch_irq = mdesc->init_irq;
-       system_timer = mdesc->timer;
-       init_machine = mdesc->init_machine;
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+       handle_arch_irq = mdesc->handle_irq;
+#endif
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
@@ -885,6 +921,9 @@ void __init setup_arch(char **cmdline_p)
 #endif
 #endif
        early_trap_init();
+
+       if (mdesc->init_early)
+               mdesc->init_early();
 }