diff options
Diffstat (limited to 'arch/arm/kernel/setup.c')
-rw-r--r-- | arch/arm/kernel/setup.c | 90 |
1 files changed, 58 insertions, 32 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 6dce209a623b..ed11fb08b05a 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/screen_info.h> | 20 | #include <linux/screen_info.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/kexec.h> | 22 | #include <linux/kexec.h> |
23 | #include <linux/of_fdt.h> | ||
23 | #include <linux/crash_dump.h> | 24 | #include <linux/crash_dump.h> |
24 | #include <linux/root_dev.h> | 25 | #include <linux/root_dev.h> |
25 | #include <linux/cpu.h> | 26 | #include <linux/cpu.h> |
@@ -42,6 +43,7 @@ | |||
42 | #include <asm/cachetype.h> | 43 | #include <asm/cachetype.h> |
43 | #include <asm/tlbflush.h> | 44 | #include <asm/tlbflush.h> |
44 | 45 | ||
46 | #include <asm/prom.h> | ||
45 | #include <asm/mach/arch.h> | 47 | #include <asm/mach/arch.h> |
46 | #include <asm/mach/irq.h> | 48 | #include <asm/mach/irq.h> |
47 | #include <asm/mach/time.h> | 49 | #include <asm/mach/time.h> |
@@ -309,7 +311,7 @@ static void __init cacheid_init(void) | |||
309 | */ | 311 | */ |
310 | extern struct proc_info_list *lookup_processor_type(unsigned int); | 312 | extern struct proc_info_list *lookup_processor_type(unsigned int); |
311 | 313 | ||
312 | static void __init early_print(const char *str, ...) | 314 | void __init early_print(const char *str, ...) |
313 | { | 315 | { |
314 | extern void printascii(const char *); | 316 | extern void printascii(const char *); |
315 | char buf[256]; | 317 | char buf[256]; |
@@ -439,25 +441,12 @@ void cpu_init(void) | |||
439 | : "r14"); | 441 | : "r14"); |
440 | } | 442 | } |
441 | 443 | ||
442 | static struct machine_desc * __init setup_machine(unsigned int nr) | 444 | void __init dump_machine_table(void) |
443 | { | 445 | { |
444 | extern struct machine_desc __arch_info_begin[], __arch_info_end[]; | ||
445 | struct machine_desc *p; | 446 | struct machine_desc *p; |
446 | 447 | ||
447 | /* | 448 | early_print("Available machine support:\n\nID (hex)\tNAME\n"); |
448 | * locate machine in the list of supported machines. | 449 | for_each_machine_desc(p) |
449 | */ | ||
450 | for (p = __arch_info_begin; p < __arch_info_end; p++) | ||
451 | if (nr == p->nr) { | ||
452 | printk("Machine: %s\n", p->name); | ||
453 | return p; | ||
454 | } | ||
455 | |||
456 | early_print("\n" | ||
457 | "Error: unrecognized/unsupported machine ID (r1 = 0x%08x).\n\n" | ||
458 | "Available machine support:\n\nID (hex)\tNAME\n", nr); | ||
459 | |||
460 | for (p = __arch_info_begin; p < __arch_info_end; p++) | ||
461 | early_print("%08x\t%s\n", p->nr, p->name); | 450 | early_print("%08x\t%s\n", p->nr, p->name); |
462 | 451 | ||
463 | early_print("\nPlease check your kernel config and/or bootloader.\n"); | 452 | early_print("\nPlease check your kernel config and/or bootloader.\n"); |
@@ -466,7 +455,7 @@ static struct machine_desc * __init setup_machine(unsigned int nr) | |||
466 | /* can't use cpu_relax() here as it may require MMU setup */; | 455 | /* can't use cpu_relax() here as it may require MMU setup */; |
467 | } | 456 | } |
468 | 457 | ||
469 | static int __init arm_add_memory(phys_addr_t start, unsigned long size) | 458 | int __init arm_add_memory(phys_addr_t start, unsigned long size) |
470 | { | 459 | { |
471 | struct membank *bank = &meminfo.bank[meminfo.nr_banks]; | 460 | struct membank *bank = &meminfo.bank[meminfo.nr_banks]; |
472 | 461 | ||
@@ -801,23 +790,29 @@ static void __init squash_mem_tags(struct tag *tag) | |||
801 | tag->hdr.tag = ATAG_NONE; | 790 | tag->hdr.tag = ATAG_NONE; |
802 | } | 791 | } |
803 | 792 | ||
804 | void __init setup_arch(char **cmdline_p) | 793 | static struct machine_desc * __init setup_machine_tags(unsigned int nr) |
805 | { | 794 | { |
806 | struct tag *tags = (struct tag *)&init_tags; | 795 | struct tag *tags = (struct tag *)&init_tags; |
807 | struct machine_desc *mdesc; | 796 | struct machine_desc *mdesc = NULL, *p; |
808 | char *from = default_command_line; | 797 | char *from = default_command_line; |
809 | 798 | ||
810 | init_tags.mem.start = PHYS_OFFSET; | 799 | init_tags.mem.start = PHYS_OFFSET; |
811 | 800 | ||
812 | unwind_init(); | 801 | /* |
813 | 802 | * locate machine in the list of supported machines. | |
814 | setup_processor(); | 803 | */ |
815 | mdesc = setup_machine(machine_arch_type); | 804 | for_each_machine_desc(p) |
816 | machine_desc = mdesc; | 805 | if (nr == p->nr) { |
817 | machine_name = mdesc->name; | 806 | printk("Machine: %s\n", p->name); |
807 | mdesc = p; | ||
808 | break; | ||
809 | } | ||
818 | 810 | ||
819 | if (mdesc->soft_reboot) | 811 | if (!mdesc) { |
820 | reboot_setup("s"); | 812 | early_print("\nError: unrecognized/unsupported machine ID" |
813 | " (r1 = 0x%08x).\n\n", nr); | ||
814 | dump_machine_table(); /* does not return */ | ||
815 | } | ||
821 | 816 | ||
822 | if (__atags_pointer) | 817 | if (__atags_pointer) |
823 | tags = phys_to_virt(__atags_pointer); | 818 | tags = phys_to_virt(__atags_pointer); |
@@ -849,8 +844,17 @@ void __init setup_arch(char **cmdline_p) | |||
849 | if (tags->hdr.tag != ATAG_CORE) | 844 | if (tags->hdr.tag != ATAG_CORE) |
850 | convert_to_tag_list(tags); | 845 | convert_to_tag_list(tags); |
851 | #endif | 846 | #endif |
852 | if (tags->hdr.tag != ATAG_CORE) | 847 | |
848 | if (tags->hdr.tag != ATAG_CORE) { | ||
849 | #if defined(CONFIG_OF) | ||
850 | /* | ||
851 | * If CONFIG_OF is set, then assume this is a reasonably | ||
852 | * modern system that should pass boot parameters | ||
853 | */ | ||
854 | early_print("Warning: Neither atags nor dtb found\n"); | ||
855 | #endif | ||
853 | tags = (struct tag *)&init_tags; | 856 | tags = (struct tag *)&init_tags; |
857 | } | ||
854 | 858 | ||
855 | if (mdesc->fixup) | 859 | if (mdesc->fixup) |
856 | mdesc->fixup(mdesc, tags, &from, &meminfo); | 860 | mdesc->fixup(mdesc, tags, &from, &meminfo); |
@@ -862,14 +866,34 @@ void __init setup_arch(char **cmdline_p) | |||
862 | parse_tags(tags); | 866 | parse_tags(tags); |
863 | } | 867 | } |
864 | 868 | ||
869 | /* parse_early_param needs a boot_command_line */ | ||
870 | strlcpy(boot_command_line, from, COMMAND_LINE_SIZE); | ||
871 | |||
872 | return mdesc; | ||
873 | } | ||
874 | |||
875 | |||
876 | void __init setup_arch(char **cmdline_p) | ||
877 | { | ||
878 | struct machine_desc *mdesc; | ||
879 | |||
880 | unwind_init(); | ||
881 | |||
882 | setup_processor(); | ||
883 | mdesc = setup_machine_fdt(__atags_pointer); | ||
884 | if (!mdesc) | ||
885 | mdesc = setup_machine_tags(machine_arch_type); | ||
886 | machine_desc = mdesc; | ||
887 | machine_name = mdesc->name; | ||
888 | |||
889 | if (mdesc->soft_reboot) | ||
890 | reboot_setup("s"); | ||
891 | |||
865 | init_mm.start_code = (unsigned long) _text; | 892 | init_mm.start_code = (unsigned long) _text; |
866 | init_mm.end_code = (unsigned long) _etext; | 893 | init_mm.end_code = (unsigned long) _etext; |
867 | init_mm.end_data = (unsigned long) _edata; | 894 | init_mm.end_data = (unsigned long) _edata; |
868 | init_mm.brk = (unsigned long) _end; | 895 | init_mm.brk = (unsigned long) _end; |
869 | 896 | ||
870 | /* parse_early_param needs a boot_command_line */ | ||
871 | strlcpy(boot_command_line, from, COMMAND_LINE_SIZE); | ||
872 | |||
873 | /* populate cmd_line too for later use, preserving boot_command_line */ | 897 | /* populate cmd_line too for later use, preserving boot_command_line */ |
874 | strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE); | 898 | strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE); |
875 | *cmdline_p = cmd_line; | 899 | *cmdline_p = cmd_line; |
@@ -881,6 +905,8 @@ void __init setup_arch(char **cmdline_p) | |||
881 | paging_init(mdesc); | 905 | paging_init(mdesc); |
882 | request_standard_resources(mdesc); | 906 | request_standard_resources(mdesc); |
883 | 907 | ||
908 | unflatten_device_tree(); | ||
909 | |||
884 | #ifdef CONFIG_SMP | 910 | #ifdef CONFIG_SMP |
885 | if (is_smp()) | 911 | if (is_smp()) |
886 | smp_init_cpus(); | 912 | smp_init_cpus(); |