2 * linux/arch/arm/kernel/devtree.c
4 * Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/init.h>
12 #include <linux/module.h>
13 #include <linux/errno.h>
14 #include <linux/types.h>
15 #include <linux/bootmem.h>
16 #include <linux/memblock.h>
18 #include <linux/of_fdt.h>
19 #include <linux/of_irq.h>
20 #include <linux/of_platform.h>
22 #include <asm/setup.h>
24 #include <asm/mach/arch.h>
25 #include <asm/mach-types.h>
27 void __init
early_init_dt_add_memory_arch(u64 base
, u64 size
)
29 arm_add_memory(base
, size
);
32 void * __init
early_init_dt_alloc_memory_arch(u64 size
, u64 align
)
34 return alloc_bootmem_align(size
, align
);
37 void __init
arm_dt_memblock_reserve(void)
39 u64
*reserve_map
, base
, size
;
41 if (!initial_boot_params
)
44 /* Reserve the dtb region */
45 memblock_reserve(virt_to_phys(initial_boot_params
),
46 be32_to_cpu(initial_boot_params
->totalsize
));
49 * Process the reserve map. This will probably overlap the initrd
50 * and dtb locations which are already reserved, but overlaping
51 * doesn't hurt anything
53 reserve_map
= ((void*)initial_boot_params
) +
54 be32_to_cpu(initial_boot_params
->off_mem_rsvmap
);
56 base
= be64_to_cpup(reserve_map
++);
57 size
= be64_to_cpup(reserve_map
++);
60 memblock_reserve(base
, size
);
65 * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
66 * @dt_phys: physical address of dt blob
68 * If a dtb was passed to the kernel in r2, then use it to choose the
69 * correct machine_desc and to setup the system.
71 struct machine_desc
* __init
setup_machine_fdt(unsigned int dt_phys
)
73 struct boot_param_header
*devtree
;
74 struct machine_desc
*mdesc
, *mdesc_best
= NULL
;
75 unsigned int score
, mdesc_score
= ~1;
76 unsigned long dt_root
;
82 devtree
= phys_to_virt(dt_phys
);
84 /* check device tree validity */
85 if (be32_to_cpu(devtree
->magic
) != OF_DT_HEADER
)
88 /* Search the mdescs for the 'best' compatible value match */
89 initial_boot_params
= devtree
;
90 dt_root
= of_get_flat_dt_root();
91 for_each_machine_desc(mdesc
) {
92 score
= of_flat_dt_match(dt_root
, mdesc
->dt_compat
);
93 if (score
> 0 && score
< mdesc_score
) {
102 early_print("\nError: unrecognized/unsupported "
103 "device tree compatible list:\n[ ");
105 prop
= of_get_flat_dt_prop(dt_root
, "compatible", &size
);
107 early_print("'%s' ", prop
);
108 size
-= strlen(prop
) + 1;
109 prop
+= strlen(prop
) + 1;
111 early_print("]\n\n");
113 dump_machine_table(); /* does not return */
116 model
= of_get_flat_dt_prop(dt_root
, "model", NULL
);
118 model
= of_get_flat_dt_prop(dt_root
, "compatible", NULL
);
121 pr_info("Machine: %s, model: %s\n", mdesc_best
->name
, model
);
123 /* Retrieve various information from the /chosen node */
124 of_scan_flat_dt(early_init_dt_scan_chosen
, boot_command_line
);
125 /* Initialize {size,address}-cells info */
126 of_scan_flat_dt(early_init_dt_scan_root
, NULL
);
127 /* Setup memory, calling early_init_dt_add_memory_arch */
128 of_scan_flat_dt(early_init_dt_scan_memory
, NULL
);
130 /* Change machine number to match the mdesc we're using */
131 __machine_arch_type
= mdesc_best
->nr
;