Commit 6f6430d72b007128dd159e5200edb9f576a10bf9
Committed by
Tom Rini
1 parent
1938f4a5b6
Exists in
master
and in
53 other branches
Introduce generic post-relocation board_r.c
This file handles common post-relocation init for boards which use the generic framework. Signed-off-by: Simon Glass <sjg@chromium.org>
Showing 3 changed files with 425 additions and 1 deletions Side-by-side Diff
arch/powerpc/lib/board.c
common/Makefile
common/board_r.c
1 | +/* | |
2 | + * Copyright (c) 2011 The Chromium OS Authors. | |
3 | + * (C) Copyright 2002-2006 | |
4 | + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
5 | + * | |
6 | + * (C) Copyright 2002 | |
7 | + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> | |
8 | + * Marius Groeger <mgroeger@sysgo.de> | |
9 | + * | |
10 | + * See file CREDITS for list of people who contributed to this | |
11 | + * project. | |
12 | + * | |
13 | + * This program is free software; you can redistribute it and/or | |
14 | + * modify it under the terms of the GNU General Public License as | |
15 | + * published by the Free Software Foundation; either version 2 of | |
16 | + * the License, or (at your option) any later version. | |
17 | + * | |
18 | + * This program is distributed in the hope that it will be useful, | |
19 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 | + * GNU General Public License for more details. | |
22 | + * | |
23 | + * You should have received a copy of the GNU General Public License | |
24 | + * along with this program; if not, write to the Free Software | |
25 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
26 | + * MA 02111-1307 USA | |
27 | + */ | |
28 | + | |
29 | +#include <common.h> | |
30 | +#ifdef CONFIG_HAS_DATAFLASH | |
31 | +#include <dataflash.h> | |
32 | +#endif | |
33 | +#include <environment.h> | |
34 | +#include <fdtdec.h> | |
35 | +#include <initcall.h> | |
36 | +#include <logbuff.h> | |
37 | +#include <malloc.h> | |
38 | +#include <mmc.h> | |
39 | +#include <nand.h> | |
40 | +#include <onenand_uboot.h> | |
41 | +#include <serial.h> | |
42 | +#include <stdio_dev.h> | |
43 | +#include <asm/sections.h> | |
44 | + | |
45 | +DECLARE_GLOBAL_DATA_PTR; | |
46 | + | |
47 | +ulong monitor_flash_len; | |
48 | + | |
49 | + | |
50 | +static int initr_reloc(void) | |
51 | +{ | |
52 | + gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ | |
53 | + bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r"); | |
54 | + | |
55 | + return 0; | |
56 | +} | |
57 | + | |
58 | +#ifdef CONFIG_ARM | |
59 | +/* | |
60 | + * Some of these functions are needed purely because the functions they | |
61 | + * call return void. If we change them to return 0, these stubs can go away. | |
62 | + */ | |
63 | +static int initr_caches(void) | |
64 | +{ | |
65 | + /* Enable caches */ | |
66 | + enable_caches(); | |
67 | + return 0; | |
68 | +} | |
69 | +#endif | |
70 | + | |
71 | +static int initr_reloc_global_data(void) | |
72 | +{ | |
73 | +#ifdef CONFIG_SYS_SYM_OFFSETS | |
74 | + monitor_flash_len = _end_ofs; | |
75 | +#else | |
76 | + monitor_flash_len = (ulong)&__init_end - gd->dest_addr; | |
77 | +#endif | |
78 | +} | |
79 | + | |
80 | +static int initr_serial(void) | |
81 | +{ | |
82 | + serial_initialize(); | |
83 | + return 0; | |
84 | +} | |
85 | + | |
86 | +#ifdef CONFIG_LOGBUFFER | |
87 | +unsigned long logbuffer_base(void) | |
88 | +{ | |
89 | + return gd->ram_top - LOGBUFF_LEN; | |
90 | +} | |
91 | + | |
92 | +static int initr_logbuffer(void) | |
93 | +{ | |
94 | + logbuff_init_ptrs(); | |
95 | + return 0; | |
96 | +} | |
97 | +#endif | |
98 | + | |
99 | +#ifdef CONFIG_POST | |
100 | +static int initr_post_backlog(void) | |
101 | +{ | |
102 | + post_output_backlog(); | |
103 | + return 0; | |
104 | +} | |
105 | +#endif | |
106 | + | |
107 | +static int initr_malloc(void) | |
108 | +{ | |
109 | + ulong malloc_start; | |
110 | + | |
111 | + /* The malloc area is immediately below the monitor copy in DRAM */ | |
112 | + malloc_start = gd->dest_addr - TOTAL_MALLOC_LEN; | |
113 | + mem_malloc_init(malloc_start, TOTAL_MALLOC_LEN); | |
114 | + return 0; | |
115 | +} | |
116 | + | |
117 | +__weak int power_init_board(void) | |
118 | +{ | |
119 | + return 0; | |
120 | +} | |
121 | + | |
122 | +static int initr_announce(void) | |
123 | +{ | |
124 | + debug("Now running in RAM - U-Boot at: %08lx\n", gd->dest_addr); | |
125 | + return 0; | |
126 | +} | |
127 | + | |
128 | +#if !defined(CONFIG_SYS_NO_FLASH) | |
129 | +static int initr_flash(void) | |
130 | +{ | |
131 | + ulong flash_size; | |
132 | + | |
133 | + puts("Flash: "); | |
134 | + | |
135 | + flash_size = flash_init(); | |
136 | + if (flash_size <= 0) { | |
137 | + puts("*** failed ***\n"); | |
138 | + return -1; | |
139 | + } | |
140 | + print_size(flash_size, ""); | |
141 | +#ifdef CONFIG_SYS_FLASH_CHECKSUM | |
142 | + /* | |
143 | + * Compute and print flash CRC if flashchecksum is set to 'y' | |
144 | + * | |
145 | + * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX | |
146 | + */ | |
147 | + if (getenv_yesno("flashchecksum") == 1) { | |
148 | + printf(" CRC: %08X", crc32(0, | |
149 | + (const unsigned char *) CONFIG_SYS_FLASH_BASE, | |
150 | + flash_size)); | |
151 | + } | |
152 | +#endif /* CONFIG_SYS_FLASH_CHECKSUM */ | |
153 | + putc('\n'); | |
154 | + | |
155 | + return 0; | |
156 | +} | |
157 | +#endif | |
158 | + | |
159 | +#ifdef CONFIG_CMD_NAND | |
160 | +/* go init the NAND */ | |
161 | +int initr_nand(void) | |
162 | +{ | |
163 | + puts("NAND: "); | |
164 | + nand_init(); | |
165 | + return 0; | |
166 | +} | |
167 | +#endif | |
168 | + | |
169 | +#if defined(CONFIG_CMD_ONENAND) | |
170 | +/* go init the NAND */ | |
171 | +int initr_onenand(void) | |
172 | +{ | |
173 | + puts("NAND: "); | |
174 | + onenand_init(); | |
175 | + return 0; | |
176 | +} | |
177 | +#endif | |
178 | + | |
179 | +#ifdef CONFIG_GENERIC_MMC | |
180 | +int initr_mmc(void) | |
181 | +{ | |
182 | + puts("MMC: "); | |
183 | + mmc_initialize(gd->bd); | |
184 | + return 0; | |
185 | +} | |
186 | +#endif | |
187 | + | |
188 | +#ifdef CONFIG_HAS_DATAFLASH | |
189 | +int initr_dataflash(void) | |
190 | +{ | |
191 | + AT91F_DataflashInit(); | |
192 | + dataflash_print_info(); | |
193 | + return 0; | |
194 | +} | |
195 | +#endif | |
196 | + | |
197 | +/* | |
198 | + * Tell if it's OK to load the environment early in boot. | |
199 | + * | |
200 | + * If CONFIG_OF_CONFIG is defined, we'll check with the FDT to see | |
201 | + * if this is OK (defaulting to saying it's OK). | |
202 | + * | |
203 | + * NOTE: Loading the environment early can be a bad idea if security is | |
204 | + * important, since no verification is done on the environment. | |
205 | + * | |
206 | + * @return 0 if environment should not be loaded, !=0 if it is ok to load | |
207 | + */ | |
208 | +static int should_load_env(void) | |
209 | +{ | |
210 | +#ifdef CONFIG_OF_CONTROL | |
211 | + return fdtdec_get_config_int(gd->fdt_blob, "load-environment", 1); | |
212 | +#elif defined CONFIG_DELAY_ENVIRONMENT | |
213 | + return 0; | |
214 | +#else | |
215 | + return 1; | |
216 | +#endif | |
217 | +} | |
218 | + | |
219 | +static int initr_env(void) | |
220 | +{ | |
221 | + /* initialize environment */ | |
222 | + if (should_load_env()) | |
223 | + env_relocate(); | |
224 | + else | |
225 | + set_default_env(NULL); | |
226 | + | |
227 | + /* Initialize from environment */ | |
228 | + load_addr = getenv_ulong("loadaddr", 16, load_addr); | |
229 | + return 0; | |
230 | +} | |
231 | + | |
232 | +static int initr_jumptable(void) | |
233 | +{ | |
234 | + jumptable_init(); | |
235 | + return 0; | |
236 | +} | |
237 | + | |
238 | +#if defined(CONFIG_API) | |
239 | +static int initr_api(void) | |
240 | +{ | |
241 | + /* Initialize API */ | |
242 | + api_init(); | |
243 | + return 0; | |
244 | +} | |
245 | +#endif | |
246 | + | |
247 | +#ifdef CONFIG_DISPLAY_BOARDINFO_LATE | |
248 | +static int show_model_r(void) | |
249 | +{ | |
250 | + /* Put this here so it appears on the LCD, now it is ready */ | |
251 | +# ifdef CONFIG_OF_CONTROL | |
252 | + const char *model; | |
253 | + | |
254 | + model = (char *)fdt_getprop(gd->fdt_blob, 0, "model", NULL); | |
255 | + printf("Model: %s\n", model ? model : "<unknown>"); | |
256 | +# else | |
257 | + checkboard(); | |
258 | +# endif | |
259 | +} | |
260 | +#endif | |
261 | + | |
262 | +/* enable exceptions */ | |
263 | +static int initr_enable_interrupts(void) | |
264 | +{ | |
265 | + enable_interrupts(); | |
266 | + return 0; | |
267 | +} | |
268 | + | |
269 | +#ifdef CONFIG_CMD_NET | |
270 | +static int initr_ethaddr(void) | |
271 | +{ | |
272 | + | |
273 | + return 0; | |
274 | +} | |
275 | +#endif /* CONFIG_CMD_NET */ | |
276 | + | |
277 | +#ifdef CONFIG_BITBANGMII | |
278 | +static int initr_bbmii(void) | |
279 | +{ | |
280 | + bb_miiphy_init(); | |
281 | + return 0; | |
282 | +} | |
283 | +#endif | |
284 | + | |
285 | +#ifdef CONFIG_CMD_NET | |
286 | +static int initr_net(void) | |
287 | +{ | |
288 | + puts("Net: "); | |
289 | + eth_initialize(gd->bd); | |
290 | +#if defined(CONFIG_RESET_PHY_R) | |
291 | + debug("Reset Ethernet PHY\n"); | |
292 | + reset_phy(); | |
293 | +#endif | |
294 | + return 0; | |
295 | +} | |
296 | +#endif | |
297 | + | |
298 | +#ifdef CONFIG_POST | |
299 | +static int initr_post(void) | |
300 | +{ | |
301 | + post_run(NULL, POST_RAM | post_bootmode_get(0)); | |
302 | + return 0; | |
303 | +} | |
304 | +#endif | |
305 | + | |
306 | +#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER) | |
307 | +/* | |
308 | + * Export available size of memory for Linux, taking into account the | |
309 | + * protected RAM at top of memory | |
310 | + */ | |
311 | +int initr_mem(void) | |
312 | +{ | |
313 | + ulong pram = 0; | |
314 | + char memsz[32]; | |
315 | + | |
316 | +# ifdef CONFIG_PRAM | |
317 | + pram = getenv_ulong("pram", 10, CONFIG_PRAM); | |
318 | +# endif | |
319 | +# if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR) | |
320 | + /* Also take the logbuffer into account (pram is in kB) */ | |
321 | + pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024; | |
322 | +# endif | |
323 | + sprintf(memsz, "%ldk", (gd->ram_size / 1024) - pram); | |
324 | + setenv("mem", memsz); | |
325 | +} | |
326 | +#endif | |
327 | + | |
328 | +static int run_main_loop(void) | |
329 | +{ | |
330 | + /* main_loop() can return to retry autoboot, if so just run it again */ | |
331 | + for (;;) | |
332 | + main_loop(); | |
333 | + return 0; | |
334 | +} | |
335 | + | |
336 | +/* | |
337 | + * Over time we hope to remove these functions with code fragments and | |
338 | + * stub funtcions, and instead call the relevant function directly. | |
339 | + * | |
340 | + * We also hope to remove most of the driver-related init and do it if/when | |
341 | + * the driver is later used. | |
342 | + */ | |
343 | +init_fnc_t init_sequence_r[] = { | |
344 | + initr_reloc, | |
345 | +#ifdef CONFIG_ARM | |
346 | + initr_caches, | |
347 | + board_init, /* Setup chipselects */ | |
348 | +#endif | |
349 | + initr_reloc_global_data, | |
350 | + initr_serial, | |
351 | + initr_announce, | |
352 | +#ifdef CONFIG_LOGBUFFER | |
353 | + initr_logbuffer, | |
354 | +#endif | |
355 | +#ifdef CONFIG_POST | |
356 | + initr_post_backlog, | |
357 | +#endif | |
358 | + initr_malloc, | |
359 | +#ifdef CONFIG_ARCH_EARLY_INIT_R | |
360 | + arch_early_init_r, | |
361 | +#endif | |
362 | + power_init_board, | |
363 | +#ifndef CONFIG_SYS_NO_FLASH | |
364 | + initr_flash, | |
365 | +#endif | |
366 | +#ifdef CONFIG_CMD_NAND | |
367 | + initr_nand, | |
368 | +#endif | |
369 | +#ifdef CONFIG_CMD_ONENAND | |
370 | + initr_onenand, | |
371 | +#endif | |
372 | +#ifdef CONFIG_GENERIC_MMC | |
373 | + initr_mmc, | |
374 | +#endif | |
375 | +#ifdef CONFIG_HAS_DATAFLASH | |
376 | + initr_dataflash, | |
377 | +#endif | |
378 | + initr_env, | |
379 | + stdio_init, | |
380 | + initr_jumptable, | |
381 | +#ifdef CONFIG_API | |
382 | + initr_api, | |
383 | +#endif | |
384 | + console_init_r, /* fully init console as a device */ | |
385 | +#ifdef CONFIG_DISPLAY_BOARDINFO_LATE | |
386 | + show_model_r, | |
387 | +#endif | |
388 | +#ifdef CONFIG_ARCH_MISC_INIT | |
389 | + arch_misc_init, /* miscellaneous arch-dependent init */ | |
390 | +#endif | |
391 | +#ifdef CONFIG_MISC_INIT_R | |
392 | + misc_init_r, /* miscellaneous platform-dependent init */ | |
393 | +#endif | |
394 | + interrupt_init, | |
395 | + initr_enable_interrupts, | |
396 | +#ifdef CONFIG_CMD_NET | |
397 | + initr_ethaddr, | |
398 | +#endif | |
399 | +#ifdef CONFIG_BOARD_LATE_INIT | |
400 | + board_late_init, | |
401 | +#endif | |
402 | +#ifdef CONFIG_BITBANGMII | |
403 | + initr_bbmii, | |
404 | +#endif | |
405 | +#ifdef CONFIG_CMD_NET | |
406 | + initr_net, | |
407 | +#endif | |
408 | +#ifdef CONFIG_POST | |
409 | + initr_post, | |
410 | +#endif | |
411 | + run_main_loop, | |
412 | +}; | |
413 | + | |
414 | +void board_init_r(gd_t *new_gd, ulong dest_addr) | |
415 | +{ | |
416 | + gd = new_gd; | |
417 | + if (initcall_run_list(init_sequence_r)) | |
418 | + hang(); | |
419 | + | |
420 | + /* NOTREACHED - run_main_loop() does not return */ | |
421 | + hang(); | |
422 | +} |