|
@@ -20,6 +20,7 @@
|
|
|
#include <linux/screen_info.h>
|
|
|
#include <linux/init.h>
|
|
|
#include <linux/kexec.h>
|
|
|
+#include <linux/of_fdt.h>
|
|
|
#include <linux/crash_dump.h>
|
|
|
#include <linux/root_dev.h>
|
|
|
#include <linux/cpu.h>
|
|
@@ -42,6 +43,7 @@
|
|
|
#include <asm/cachetype.h>
|
|
|
#include <asm/tlbflush.h>
|
|
|
|
|
|
+#include <asm/prom.h>
|
|
|
#include <asm/mach/arch.h>
|
|
|
#include <asm/mach/irq.h>
|
|
|
#include <asm/mach/time.h>
|
|
@@ -309,7 +311,7 @@ static void __init cacheid_init(void)
|
|
|
*/
|
|
|
extern struct proc_info_list *lookup_processor_type(unsigned int);
|
|
|
|
|
|
-static void __init early_print(const char *str, ...)
|
|
|
+void __init early_print(const char *str, ...)
|
|
|
{
|
|
|
extern void printascii(const char *);
|
|
|
char buf[256];
|
|
@@ -439,25 +441,12 @@ void cpu_init(void)
|
|
|
: "r14");
|
|
|
}
|
|
|
|
|
|
-static struct machine_desc * __init setup_machine(unsigned int nr)
|
|
|
+void __init dump_machine_table(void)
|
|
|
{
|
|
|
- extern struct machine_desc __arch_info_begin[], __arch_info_end[];
|
|
|
struct machine_desc *p;
|
|
|
|
|
|
- /*
|
|
|
- * locate machine in the list of supported machines.
|
|
|
- */
|
|
|
- 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("Available machine support:\n\nID (hex)\tNAME\n");
|
|
|
+ for_each_machine_desc(p)
|
|
|
early_print("%08x\t%s\n", p->nr, p->name);
|
|
|
|
|
|
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)
|
|
|
/* 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)
|
|
|
+int __init arm_add_memory(phys_addr_t start, unsigned long size)
|
|
|
{
|
|
|
struct membank *bank = &meminfo.bank[meminfo.nr_banks];
|
|
|
|
|
@@ -801,23 +790,29 @@ static void __init squash_mem_tags(struct tag *tag)
|
|
|
tag->hdr.tag = ATAG_NONE;
|
|
|
}
|
|
|
|
|
|
-void __init setup_arch(char **cmdline_p)
|
|
|
+static struct machine_desc * __init setup_machine_tags(unsigned int nr)
|
|
|
{
|
|
|
struct tag *tags = (struct tag *)&init_tags;
|
|
|
- struct machine_desc *mdesc;
|
|
|
+ struct machine_desc *mdesc = NULL, *p;
|
|
|
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;
|
|
|
+ /*
|
|
|
+ * locate machine in the list of supported machines.
|
|
|
+ */
|
|
|
+ for_each_machine_desc(p)
|
|
|
+ if (nr == p->nr) {
|
|
|
+ printk("Machine: %s\n", p->name);
|
|
|
+ mdesc = p;
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- if (mdesc->soft_reboot)
|
|
|
- reboot_setup("s");
|
|
|
+ if (!mdesc) {
|
|
|
+ early_print("\nError: unrecognized/unsupported machine ID"
|
|
|
+ " (r1 = 0x%08x).\n\n", nr);
|
|
|
+ dump_machine_table(); /* does not return */
|
|
|
+ }
|
|
|
|
|
|
if (__atags_pointer)
|
|
|
tags = phys_to_virt(__atags_pointer);
|
|
@@ -849,8 +844,17 @@ void __init setup_arch(char **cmdline_p)
|
|
|
if (tags->hdr.tag != ATAG_CORE)
|
|
|
convert_to_tag_list(tags);
|
|
|
#endif
|
|
|
- if (tags->hdr.tag != ATAG_CORE)
|
|
|
+
|
|
|
+ if (tags->hdr.tag != ATAG_CORE) {
|
|
|
+#if defined(CONFIG_OF)
|
|
|
+ /*
|
|
|
+ * If CONFIG_OF is set, then assume this is a reasonably
|
|
|
+ * modern system that should pass boot parameters
|
|
|
+ */
|
|
|
+ early_print("Warning: Neither atags nor dtb found\n");
|
|
|
+#endif
|
|
|
tags = (struct tag *)&init_tags;
|
|
|
+ }
|
|
|
|
|
|
if (mdesc->fixup)
|
|
|
mdesc->fixup(mdesc, tags, &from, &meminfo);
|
|
@@ -862,14 +866,34 @@ void __init setup_arch(char **cmdline_p)
|
|
|
parse_tags(tags);
|
|
|
}
|
|
|
|
|
|
+ /* parse_early_param needs a boot_command_line */
|
|
|
+ strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
|
|
|
+
|
|
|
+ return mdesc;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void __init setup_arch(char **cmdline_p)
|
|
|
+{
|
|
|
+ struct machine_desc *mdesc;
|
|
|
+
|
|
|
+ unwind_init();
|
|
|
+
|
|
|
+ setup_processor();
|
|
|
+ mdesc = setup_machine_fdt(__atags_pointer);
|
|
|
+ if (!mdesc)
|
|
|
+ mdesc = setup_machine_tags(machine_arch_type);
|
|
|
+ machine_desc = mdesc;
|
|
|
+ machine_name = mdesc->name;
|
|
|
+
|
|
|
+ if (mdesc->soft_reboot)
|
|
|
+ reboot_setup("s");
|
|
|
+
|
|
|
init_mm.start_code = (unsigned long) _text;
|
|
|
init_mm.end_code = (unsigned long) _etext;
|
|
|
init_mm.end_data = (unsigned long) _edata;
|
|
|
init_mm.brk = (unsigned long) _end;
|
|
|
|
|
|
- /* parse_early_param needs a boot_command_line */
|
|
|
- strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
|
|
|
-
|
|
|
/* populate cmd_line too for later use, preserving boot_command_line */
|
|
|
strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
|
|
|
*cmdline_p = cmd_line;
|
|
@@ -881,6 +905,8 @@ void __init setup_arch(char **cmdline_p)
|
|
|
paging_init(mdesc);
|
|
|
request_standard_resources(mdesc);
|
|
|
|
|
|
+ unflatten_device_tree();
|
|
|
+
|
|
|
#ifdef CONFIG_SMP
|
|
|
if (is_smp())
|
|
|
smp_init_cpus();
|