From 4c2896e88d976d0e5b2213c64cde885f5677fa2b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 28 Apr 2011 14:27:20 -0600 Subject: arm/dt: Make __vet_atags also accept a dtb image The dtb is passed to the kernel via register r2, which is the same method that is used to pass an atags pointer. This patch modifies __vet_atags to not clear r2 when it encounters a dtb image. v2: fixed bugs pointed out by Nicolas Pitre Tested-by: Tony Lindgren Signed-off-by: Grant Likely --- arch/arm/kernel/head-common.S | 24 ++++++++++++++++++------ arch/arm/kernel/head.S | 8 ++++---- 2 files changed, 22 insertions(+), 10 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index c84b57d27d0..854bd22380d 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -15,6 +15,12 @@ #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2) #define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2) +#ifdef CONFIG_CPU_BIG_ENDIAN +#define OF_DT_MAGIC 0xd00dfeed +#else +#define OF_DT_MAGIC 0xedfe0dd0 /* 0xd00dfeed in big-endian */ +#endif + /* * Exception handling. Something went wrong and we can't proceed. We * ought to tell the user, but since we don't have any guarantee that @@ -28,20 +34,26 @@ /* Determine validity of the r2 atags pointer. The heuristic requires * that the pointer be aligned, in the first 16k of physical RAM and - * that the ATAG_CORE marker is first and present. Future revisions + * that the ATAG_CORE marker is first and present. If CONFIG_OF_FLATTREE + * is selected, then it will also accept a dtb pointer. Future revisions * of this function may be more lenient with the physical address and * may also be able to move the ATAGS block if necessary. * * Returns: - * r2 either valid atags pointer, or zero + * r2 either valid atags pointer, valid dtb pointer, or zero * r5, r6 corrupted */ __vet_atags: tst r2, #0x3 @ aligned? bne 1f - ldr r5, [r2, #0] @ is first tag ATAG_CORE? - cmp r5, #ATAG_CORE_SIZE + ldr r5, [r2, #0] +#ifdef CONFIG_OF_FLATTREE + ldr r6, =OF_DT_MAGIC @ is it a DTB? + cmp r5, r6 + beq 2f +#endif + cmp r5, #ATAG_CORE_SIZE @ is first tag ATAG_CORE? cmpne r5, #ATAG_CORE_SIZE_EMPTY bne 1f ldr r5, [r2, #4] @@ -49,7 +61,7 @@ __vet_atags: cmp r5, r6 bne 1f - mov pc, lr @ atag pointer is ok +2: mov pc, lr @ atag/dtb pointer is ok 1: mov r2, #0 mov pc, lr @@ -61,7 +73,7 @@ ENDPROC(__vet_atags) * * r0 = cp#15 control register * r1 = machine ID - * r2 = atags pointer + * r2 = atags/dtb pointer * r9 = processor ID */ __INIT diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index c9173cfbbc7..a5e5c5b9b48 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -59,7 +59,7 @@ * * This is normally called from the decompressor code. The requirements * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, - * r1 = machine nr, r2 = atags pointer. + * r1 = machine nr, r2 = atags or dtb pointer. * * This code is mostly position independent, so if you link the kernel at * 0xc0008000, you call this at __pa(0xc0008000). @@ -91,7 +91,7 @@ ENTRY(stext) #endif /* - * r1 = machine no, r2 = atags, + * r1 = machine no, r2 = atags or dtb, * r8 = phys_offset, r9 = cpuid, r10 = procinfo */ bl __vet_atags @@ -339,7 +339,7 @@ __secondary_data: * * r0 = cp#15 control register * r1 = machine ID - * r2 = atags pointer + * r2 = atags or dtb pointer * r4 = page table pointer * r9 = processor ID * r13 = *virtual* address to jump to upon completion @@ -376,7 +376,7 @@ ENDPROC(__enable_mmu) * * r0 = cp#15 control register * r1 = machine ID - * r2 = atags pointer + * r2 = atags or dtb pointer * r9 = processor ID * r13 = *virtual* address to jump to upon completion * -- cgit v1.2.3-18-g5258 From 9eb8f6743b076b67f00776cda4330c802e157b41 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 28 Apr 2011 14:27:20 -0600 Subject: arm/dt: Allow CONFIG_OF on ARM Add some basic empty infrastructure for DT support on ARM. v5: - Fix off-by-one error in size calculation of initrd - Stop mucking with cmd_line, and load command line from dt into boot_command_line instead which matches the behaviour of ATAGS booting v3: - moved cmd_line export and initrd setup to this patch to make the series bisectable. - switched to alloc_bootmem_align() for allocation when unflattening the device tree. memblock_alloc() was not the right interface. Signed-off-by: Jeremy Kerr Tested-by: Tony Lindgren Acked-by: Nicolas Pitre Acked-by: Russell King Signed-off-by: Grant Likely --- arch/arm/Kconfig | 7 +++++++ arch/arm/include/asm/prom.h | 25 +++++++++++++++++++++++ arch/arm/include/asm/setup.h | 2 ++ arch/arm/kernel/Makefile | 1 + arch/arm/kernel/devtree.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/setup.c | 2 +- arch/arm/mm/init.c | 9 +++++++++ 7 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/prom.h create mode 100644 arch/arm/kernel/devtree.c (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 377a7a595b0..efc7f3c87f1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1687,6 +1687,13 @@ endmenu menu "Boot options" +config USE_OF + bool "Flattened Device Tree support" + select OF + select OF_EARLY_FLATTREE + help + Include support for flattened device tree machine descriptions. + # Compressed boot loader in ROM. Yes, we really want to ask about # TEXT and BSS so we preserve their values in the config files. config ZBOOT_ROM_TEXT diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h new file mode 100644 index 00000000000..8f1037fdc08 --- /dev/null +++ b/arch/arm/include/asm/prom.h @@ -0,0 +1,25 @@ +/* + * arch/arm/include/asm/prom.h + * + * Copyright (C) 2009 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#ifndef __ASMARM_PROM_H +#define __ASMARM_PROM_H + +#ifdef CONFIG_OF + +#include +#include + +static inline void irq_dispose_mapping(unsigned int virq) +{ + return; +} + +#endif /* CONFIG_OF */ +#endif /* ASMARM_PROM_H */ diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index 95176af3df8..93b4702ffa0 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h @@ -217,6 +217,8 @@ extern struct meminfo meminfo; #define bank_phys_end(bank) ((bank)->start + (bank)->size) #define bank_phys_size(bank) (bank)->size +extern int arm_add_memory(phys_addr_t start, unsigned long size); + #endif /* __KERNEL__ */ #endif diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 8d95446150a..908c78cb1d1 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_ARM_THUMBEE) += thumbee.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_ARM_UNWIND) += unwind.o obj-$(CONFIG_HAVE_TCM) += tcm.o +obj-$(CONFIG_OF) += devtree.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o CFLAGS_swp_emulate.o := -Wa,-march=armv7-a diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c new file mode 100644 index 00000000000..75e3df85b88 --- /dev/null +++ b/arch/arm/kernel/devtree.c @@ -0,0 +1,47 @@ +/* + * linux/arch/arm/kernel/devtree.c + * + * Copyright (C) 2009 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +void __init early_init_dt_add_memory_arch(u64 base, u64 size) +{ + arm_add_memory(base, size); +} + +void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) +{ + return alloc_bootmem_align(size, align); +} + +/** + * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq# + * + * Currently the mapping mechanism is trivial; simple flat hwirq numbers are + * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not + * supported. + */ +unsigned int irq_create_of_mapping(struct device_node *controller, + const u32 *intspec, unsigned int intsize) +{ + return intspec[0]; +} +EXPORT_SYMBOL_GPL(irq_create_of_mapping); diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 006c1e884ea..109997e3fe4 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -466,7 +466,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]; diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index e5f6fc42834..26c405421f4 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +72,14 @@ static int __init parse_tag_initrd2(const struct tag *tag) __tagtable(ATAG_INITRD2, parse_tag_initrd2); +#ifdef CONFIG_OF_FLATTREE +void __init early_init_dt_setup_initrd_arch(unsigned long start, unsigned long end) +{ + phys_initrd_start = start; + phys_initrd_size = end - start; +} +#endif /* CONFIG_OF_FLATTREE */ + /* * This keeps memory configuration data used by a couple memory * initialization functions, as well as show_mem() for the skipping -- cgit v1.2.3-18-g5258 From 6291319d4864848efc7b5d81389e2404fb478cb9 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 28 Apr 2011 14:27:21 -0600 Subject: arm/dt: consolidate atags setup into setup_machine_atags In preparation for adding device tree support, this patch consolidates all of the atag-specific setup into a single function. v5: - drop double printk("Machine; %s\n", ...); call. - leave copying boot_command_line in setup_arch() since it isn't atags specific. v4: - adapt to the removal of lookup_machine_type() - break out dump of machine_desc table into dump_machine_table() because the device tree probe code will use it. - Add for_each_machine_desc() macro Tested-by: Tony Lindgren Acked-by: Nicolas Pitre Acked-by: Russell King Signed-off-by: Grant Likely --- arch/arm/include/asm/mach/arch.h | 7 ++++ arch/arm/kernel/setup.c | 69 +++++++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 29 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index bf13b814c1b..4764e67fb93 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -47,6 +47,13 @@ struct machine_desc { */ extern struct machine_desc *machine_desc; +/* + * Machine type table - also only accessible during boot + */ +extern struct machine_desc __arch_info_begin[], __arch_info_end[]; +#define for_each_machine_desc(p) \ + for (p = __arch_info_begin; p < __arch_info_end; p++) + /* * Set of macros to define architecture features. This is built into * a table by the linker. diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 109997e3fe4..42c2f0cedf1 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -439,25 +439,12 @@ void cpu_init(void) : "r14"); } -static struct machine_desc * __init setup_machine(unsigned int nr) +static 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"); @@ -796,23 +783,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); @@ -857,14 +850,32 @@ 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_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; -- cgit v1.2.3-18-g5258 From 93c02ab40ae6e06cb24d14845d9f008fdd24f43d Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 28 Apr 2011 14:27:21 -0600 Subject: arm/dt: probe for platforms via the device tree If a dtb is passed to the kernel then the kernel needs to iterate through compiled-in mdescs looking for one that matches and move the dtb data to a safe location before it gets accidentally overwritten by the kernel. This patch creates a new function, setup_machine_fdt() which is analogous to the setup_machine_atags() created in the previous patch. It does all the early setup needed to use a device tree machine description. v5: - Print warning with neither dtb nor atags are passed to the kernel - Fix bug in setting of __machine_arch_type to the selected machine, not just the last machine in the list. Reported-by: Tixy - Copy command line directly into boot_command_line instead of cmd_line v4: - Dump some output when a matching machine_desc cannot be found v3: - Added processing of reserved list. - Backed out the v2 change that copied instead of reserved the dtb. dtb is reserved again and the real problem was fixed by using alloc_bootmem_align() for early allocation of RAM for unflattening the tree. - Moved cmd_line and initrd changes to earlier patch to make series bisectable. v2: Changed to save the dtb by copying into an allocated buffer. - Since the dtb will very likely be passed in the first 16k of ram where the interrupt vectors live, memblock_reserve() is insufficient to protect the dtb data. [based on work originally written by Jeremy Kerr ] Tested-by: Tony Lindgren Acked-by: Nicolas Pitre Acked-by: Russell King Signed-off-by: Grant Likely --- arch/arm/include/asm/mach/arch.h | 2 + arch/arm/include/asm/prom.h | 12 +++++ arch/arm/include/asm/setup.h | 2 + arch/arm/kernel/devtree.c | 98 ++++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/setup.c | 23 ++++++++-- arch/arm/mm/init.c | 2 + 6 files changed, 135 insertions(+), 4 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index 4764e67fb93..946f4d778f7 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -18,6 +18,8 @@ struct machine_desc { unsigned int nr; /* architecture number */ const char *name; /* architecture name */ unsigned long boot_params; /* tagged list */ + const char **dt_compat; /* array of device tree + * 'compatible' strings */ unsigned int nr_irqs; /* number of IRQs */ diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h index 8f1037fdc08..11b8708fc4d 100644 --- a/arch/arm/include/asm/prom.h +++ b/arch/arm/include/asm/prom.h @@ -21,5 +21,17 @@ static inline void irq_dispose_mapping(unsigned int virq) return; } +extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys); +extern void arm_dt_memblock_reserve(void); + +#else /* CONFIG_OF */ + +static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys) +{ + return NULL; +} + +static inline void arm_dt_memblock_reserve(void) { } + #endif /* CONFIG_OF */ #endif /* ASMARM_PROM_H */ diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index 93b4702ffa0..ee2ad8ae07a 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h @@ -218,6 +218,8 @@ extern struct meminfo meminfo; #define bank_phys_size(bank) (bank)->size extern int arm_add_memory(phys_addr_t start, unsigned long size); +extern void early_print(const char *str, ...); +extern void dump_machine_table(void); #endif /* __KERNEL__ */ diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index 75e3df85b88..a701e4226a6 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -21,6 +21,8 @@ #include #include +#include +#include void __init early_init_dt_add_memory_arch(u64 base, u64 size) { @@ -32,6 +34,102 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) return alloc_bootmem_align(size, align); } +void __init arm_dt_memblock_reserve(void) +{ + u64 *reserve_map, base, size; + + if (!initial_boot_params) + return; + + /* Reserve the dtb region */ + memblock_reserve(virt_to_phys(initial_boot_params), + be32_to_cpu(initial_boot_params->totalsize)); + + /* + * Process the reserve map. This will probably overlap the initrd + * and dtb locations which are already reserved, but overlaping + * doesn't hurt anything + */ + reserve_map = ((void*)initial_boot_params) + + be32_to_cpu(initial_boot_params->off_mem_rsvmap); + while (1) { + base = be64_to_cpup(reserve_map++); + size = be64_to_cpup(reserve_map++); + if (!size) + break; + memblock_reserve(base, size); + } +} + +/** + * setup_machine_fdt - Machine setup when an dtb was passed to the kernel + * @dt_phys: physical address of dt blob + * + * If a dtb was passed to the kernel in r2, then use it to choose the + * correct machine_desc and to setup the system. + */ +struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) +{ + struct boot_param_header *devtree; + struct machine_desc *mdesc, *mdesc_best = NULL; + unsigned int score, mdesc_score = ~1; + unsigned long dt_root; + const char *model; + + devtree = phys_to_virt(dt_phys); + + /* check device tree validity */ + if (be32_to_cpu(devtree->magic) != OF_DT_HEADER) + return NULL; + + /* Search the mdescs for the 'best' compatible value match */ + initial_boot_params = devtree; + dt_root = of_get_flat_dt_root(); + for_each_machine_desc(mdesc) { + score = of_flat_dt_match(dt_root, mdesc->dt_compat); + if (score > 0 && score < mdesc_score) { + mdesc_best = mdesc; + mdesc_score = score; + } + } + if (!mdesc_best) { + const char *prop; + long size; + + early_print("\nError: unrecognized/unsupported " + "device tree compatible list:\n[ "); + + prop = of_get_flat_dt_prop(dt_root, "compatible", &size); + while (size > 0) { + early_print("'%s' ", prop); + size -= strlen(prop) + 1; + prop += strlen(prop) + 1; + } + early_print("]\n\n"); + + dump_machine_table(); /* does not return */ + } + + model = of_get_flat_dt_prop(dt_root, "model", NULL); + if (!model) + model = of_get_flat_dt_prop(dt_root, "compatible", NULL); + if (!model) + model = ""; + pr_info("Machine: %s, model: %s\n", mdesc_best->name, model); + + /* Retrieve various information from the /chosen node */ + of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); + /* Initialize {size,address}-cells info */ + of_scan_flat_dt(early_init_dt_scan_root, NULL); + /* Setup memory, calling early_init_dt_add_memory_arch */ + of_scan_flat_dt(early_init_dt_scan_memory, NULL); + + /* Change machine number to match the mdesc we're using */ + __machine_arch_type = mdesc_best->nr; + + return mdesc_best; +} + /** * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq# * diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 42c2f0cedf1..05db25ef3dd 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,7 @@ #include #include +#include #include #include #include @@ -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,7 +441,7 @@ void cpu_init(void) : "r14"); } -static void __init dump_machine_table(void) +void __init dump_machine_table(void) { struct machine_desc *p; @@ -837,8 +839,17 @@ static struct machine_desc * __init setup_machine_tags(unsigned int nr) 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); @@ -864,7 +875,9 @@ void __init setup_arch(char **cmdline_p) unwind_init(); setup_processor(); - mdesc = setup_machine_tags(machine_arch_type); + mdesc = setup_machine_fdt(__atags_pointer); + if (!mdesc) + mdesc = setup_machine_tags(machine_arch_type); machine_desc = mdesc; machine_name = mdesc->name; @@ -887,6 +900,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(); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 26c405421f4..b26597552eb 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -322,6 +323,7 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc) #endif arm_mm_memblock_reserve(); + arm_dt_memblock_reserve(); /* reserve any platform specific memblock areas */ if (mdesc->reserve) -- cgit v1.2.3-18-g5258