2222#include <linux/bootmem.h>
2323#include <linux/kernel.h>
2424
25+ #ifdef CONFIG_OF
26+ #include <linux/of_fdt.h>
27+ #include <linux/of_platform.h>
28+ #endif
29+
2530#if defined(CONFIG_VGA_CONSOLE ) || defined(CONFIG_DUMMY_CONSOLE )
2631# include <linux/console.h>
2732#endif
@@ -65,6 +70,11 @@ int initrd_is_mapped = 0;
6570extern int initrd_below_start_ok ;
6671#endif
6772
73+ #ifdef CONFIG_OF
74+ extern u32 __dtb_start [];
75+ void * dtb_start = __dtb_start ;
76+ #endif
77+
6878unsigned char aux_device_present ;
6979extern unsigned long loops_per_jiffy ;
7080
@@ -84,6 +94,8 @@ extern void init_mmu(void);
8494static inline void init_mmu (void ) { }
8595#endif
8696
97+ extern int mem_reserve (unsigned long , unsigned long , int );
98+ extern void bootmem_init (void );
8799extern void zones_init (void );
88100
89101/*
@@ -105,28 +117,33 @@ typedef struct tagtable {
105117
106118/* parse current tag */
107119
108- static int __init parse_tag_mem (const bp_tag_t * tag )
120+ static int __init add_sysmem_bank (unsigned long type , unsigned long start ,
121+ unsigned long end )
109122{
110- meminfo_t * mi = (meminfo_t * )(tag -> data );
111-
112- if (mi -> type != MEMORY_TYPE_CONVENTIONAL )
113- return -1 ;
114-
115123 if (sysmem .nr_banks >= SYSMEM_BANKS_MAX ) {
116124 printk (KERN_WARNING
117- "Ignoring memory bank 0x%08lx size %ldKB\n" ,
118- (unsigned long )mi -> start ,
119- (unsigned long )mi -> end - (unsigned long )mi -> start );
125+ "Ignoring memory bank 0x%08lx size %ldKB\n" ,
126+ start , end - start );
120127 return - EINVAL ;
121128 }
122- sysmem .bank [sysmem .nr_banks ].type = mi -> type ;
123- sysmem .bank [sysmem .nr_banks ].start = PAGE_ALIGN (mi -> start );
124- sysmem .bank [sysmem .nr_banks ].end = mi -> end & PAGE_MASK ;
129+ sysmem .bank [sysmem .nr_banks ].type = type ;
130+ sysmem .bank [sysmem .nr_banks ].start = PAGE_ALIGN (start );
131+ sysmem .bank [sysmem .nr_banks ].end = end & PAGE_MASK ;
125132 sysmem .nr_banks ++ ;
126133
127134 return 0 ;
128135}
129136
137+ static int __init parse_tag_mem (const bp_tag_t * tag )
138+ {
139+ meminfo_t * mi = (meminfo_t * )(tag -> data );
140+
141+ if (mi -> type != MEMORY_TYPE_CONVENTIONAL )
142+ return -1 ;
143+
144+ return add_sysmem_bank (mi -> type , mi -> start , mi -> end );
145+ }
146+
130147__tagtable (BP_TAG_MEMORY , parse_tag_mem );
131148
132149#ifdef CONFIG_BLK_DEV_INITRD
@@ -143,12 +160,31 @@ static int __init parse_tag_initrd(const bp_tag_t* tag)
143160
144161__tagtable (BP_TAG_INITRD , parse_tag_initrd );
145162
163+ #ifdef CONFIG_OF
164+
165+ static int __init parse_tag_fdt (const bp_tag_t * tag )
166+ {
167+ dtb_start = (void * )(tag -> data [0 ]);
168+ return 0 ;
169+ }
170+
171+ __tagtable (BP_TAG_FDT , parse_tag_fdt );
172+
173+ void __init early_init_dt_setup_initrd_arch (unsigned long start ,
174+ unsigned long end )
175+ {
176+ initrd_start = (void * )__va (start );
177+ initrd_end = (void * )__va (end );
178+ initrd_below_start_ok = 1 ;
179+ }
180+
181+ #endif /* CONFIG_OF */
182+
146183#endif /* CONFIG_BLK_DEV_INITRD */
147184
148185static int __init parse_tag_cmdline (const bp_tag_t * tag )
149186{
150- strncpy (command_line , (char * )(tag -> data ), COMMAND_LINE_SIZE );
151- command_line [COMMAND_LINE_SIZE - 1 ] = '\0' ;
187+ strlcpy (command_line , (char * )(tag -> data ), COMMAND_LINE_SIZE );
152188 return 0 ;
153189}
154190
@@ -186,6 +222,58 @@ static int __init parse_bootparam(const bp_tag_t* tag)
186222 return 0 ;
187223}
188224
225+ #ifdef CONFIG_OF
226+
227+ void __init early_init_dt_add_memory_arch (u64 base , u64 size )
228+ {
229+ size &= PAGE_MASK ;
230+ add_sysmem_bank (MEMORY_TYPE_CONVENTIONAL , base , base + size );
231+ }
232+
233+ void * __init early_init_dt_alloc_memory_arch (u64 size , u64 align )
234+ {
235+ return __alloc_bootmem (size , align , 0 );
236+ }
237+
238+ void __init early_init_devtree (void * params )
239+ {
240+ /* Setup flat device-tree pointer */
241+ initial_boot_params = params ;
242+
243+ /* Retrieve various informations from the /chosen node of the
244+ * device-tree, including the platform type, initrd location and
245+ * size, TCE reserve, and more ...
246+ */
247+ if (!command_line [0 ])
248+ of_scan_flat_dt (early_init_dt_scan_chosen , command_line );
249+
250+ /* Scan memory nodes and rebuild MEMBLOCKs */
251+ of_scan_flat_dt (early_init_dt_scan_root , NULL );
252+ if (sysmem .nr_banks == 0 )
253+ of_scan_flat_dt (early_init_dt_scan_memory , NULL );
254+ }
255+
256+ static void __init copy_devtree (void )
257+ {
258+ void * alloc = early_init_dt_alloc_memory_arch (
259+ be32_to_cpu (initial_boot_params -> totalsize ), 0 );
260+ if (alloc ) {
261+ memcpy (alloc , initial_boot_params ,
262+ be32_to_cpu (initial_boot_params -> totalsize ));
263+ initial_boot_params = alloc ;
264+ }
265+ }
266+
267+ static int __init xtensa_device_probe (void )
268+ {
269+ of_platform_populate (NULL , NULL , NULL , NULL );
270+ return 0 ;
271+ }
272+
273+ device_initcall (xtensa_device_probe );
274+
275+ #endif /* CONFIG_OF */
276+
189277/*
190278 * Initialize architecture. (Early stage)
191279 */
@@ -194,14 +282,14 @@ void __init init_arch(bp_tag_t *bp_start)
194282{
195283 sysmem .nr_banks = 0 ;
196284
197- #ifdef CONFIG_CMDLINE_BOOL
198- strcpy (command_line , default_command_line );
199- #endif
200-
201285 /* Parse boot parameters */
202286
203287 if (bp_start )
204- parse_bootparam (bp_start );
288+ parse_bootparam (bp_start );
289+
290+ #ifdef CONFIG_OF
291+ early_init_devtree (dtb_start );
292+ #endif
205293
206294 if (sysmem .nr_banks == 0 ) {
207295 sysmem .nr_banks = 1 ;
@@ -210,6 +298,11 @@ void __init init_arch(bp_tag_t *bp_start)
210298 + PLATFORM_DEFAULT_MEM_SIZE ;
211299 }
212300
301+ #ifdef CONFIG_CMDLINE_BOOL
302+ if (!command_line [0 ])
303+ strlcpy (command_line , default_command_line , COMMAND_LINE_SIZE );
304+ #endif
305+
213306 /* Early hook for platforms */
214307
215308 platform_init (bp_start );
@@ -355,11 +448,7 @@ void __init check_s32c1i(void)
355448
356449void __init setup_arch (char * * cmdline_p )
357450{
358- extern int mem_reserve (unsigned long , unsigned long , int );
359- extern void bootmem_init (void );
360-
361- memcpy (boot_command_line , command_line , COMMAND_LINE_SIZE );
362- boot_command_line [COMMAND_LINE_SIZE - 1 ] = '\0' ;
451+ strlcpy (boot_command_line , command_line , COMMAND_LINE_SIZE );
363452 * cmdline_p = command_line ;
364453
365454 check_s32c1i ();
@@ -395,8 +484,12 @@ void __init setup_arch(char **cmdline_p)
395484
396485 bootmem_init ();
397486
398- platform_setup (cmdline_p );
487+ #ifdef CONFIG_OF
488+ copy_devtree ();
489+ unflatten_device_tree ();
490+ #endif
399491
492+ platform_setup (cmdline_p );
400493
401494 paging_init ();
402495 zones_init ();
0 commit comments