]>
Commit | Line | Data |
---|---|---|
bcae7211 A |
1 | /* |
2 | * (C) Copyright 2010 | |
3 | * Texas Instruments, <www.ti.com> | |
4 | * | |
5 | * Aneesh V <aneesh@ti.com> | |
6 | * | |
1a459660 | 7 | * SPDX-License-Identifier: GPL-2.0+ |
bcae7211 A |
8 | */ |
9 | #include <common.h> | |
11516518 | 10 | #include <dm.h> |
47f7bcae | 11 | #include <spl.h> |
bcae7211 | 12 | #include <asm/u-boot.h> |
bb085b87 | 13 | #include <nand.h> |
8cf686e1 | 14 | #include <fat.h> |
efb2172e | 15 | #include <version.h> |
8cf686e1 | 16 | #include <image.h> |
2d01dd95 | 17 | #include <malloc.h> |
11516518 | 18 | #include <dm/root.h> |
761ca31e | 19 | #include <linux/compiler.h> |
bcae7211 A |
20 | |
21 | DECLARE_GLOBAL_DATA_PTR; | |
22 | ||
3c6f8a0d SR |
23 | #ifndef CONFIG_SYS_UBOOT_START |
24 | #define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE | |
25 | #endif | |
ae83d882 | 26 | #ifndef CONFIG_SYS_MONITOR_LEN |
e76caa62 | 27 | /* Unknown U-Boot size, let's assume it will not be more than 200 KB */ |
ae83d882 SB |
28 | #define CONFIG_SYS_MONITOR_LEN (200 * 1024) |
29 | #endif | |
30 | ||
47f7bcae | 31 | u32 *boot_params_ptr = NULL; |
9ea5c6ef SS |
32 | struct spl_image_info spl_image; |
33 | ||
6507f133 | 34 | /* Define board data structure */ |
bcae7211 A |
35 | static bd_t bdata __attribute__ ((section(".data"))); |
36 | ||
496c5483 HS |
37 | /* |
38 | * Board-specific Platform code can reimplement show_boot_progress () if needed | |
39 | */ | |
40 | __weak void show_boot_progress(int val) {} | |
41 | ||
379c19ab SS |
42 | /* |
43 | * Default function to determine if u-boot or the OS should | |
44 | * be started. This implementation always returns 1. | |
45 | * | |
46 | * Please implement your own board specific funcion to do this. | |
47 | * | |
48 | * RETURN | |
49 | * 0 to not start u-boot | |
50 | * positive if u-boot should start | |
51 | */ | |
52 | #ifdef CONFIG_SPL_OS_BOOT | |
53 | __weak int spl_start_uboot(void) | |
54 | { | |
026b2fe3 TR |
55 | puts("SPL: Please implement spl_start_uboot() for your board\n"); |
56 | puts("SPL: Direct Linux boot not active!\n"); | |
379c19ab SS |
57 | return 1; |
58 | } | |
431889d6 LM |
59 | |
60 | /* | |
61 | * Weak default function for arch specific zImage check. Return zero | |
62 | * and fill start and end address if image is recognized. | |
63 | */ | |
64 | int __weak bootz_setup(ulong image, ulong *start, ulong *end) | |
65 | { | |
66 | return 1; | |
67 | } | |
379c19ab SS |
68 | #endif |
69 | ||
ea8256f0 SR |
70 | /* |
71 | * Weak default function for board specific cleanup/preparation before | |
72 | * Linux boot. Some boards/platforms might not need it, so just provide | |
73 | * an empty stub here. | |
74 | */ | |
75 | __weak void spl_board_prepare_for_linux(void) | |
76 | { | |
77 | /* Nothing to do! */ | |
78 | } | |
79 | ||
3a3b9147 MS |
80 | __weak void spl_board_prepare_for_boot(void) |
81 | { | |
82 | /* Nothing to do! */ | |
83 | } | |
84 | ||
d95ceb97 | 85 | void spl_set_header_raw_uboot(struct spl_image_info *spl_image) |
0c3117b1 | 86 | { |
d95ceb97 SG |
87 | spl_image->size = CONFIG_SYS_MONITOR_LEN; |
88 | spl_image->entry_point = CONFIG_SYS_UBOOT_START; | |
89 | spl_image->load_addr = CONFIG_SYS_TEXT_BASE; | |
90 | spl_image->os = IH_OS_U_BOOT; | |
91 | spl_image->name = "U-Boot"; | |
0c3117b1 HS |
92 | } |
93 | ||
71316c1d SG |
94 | int spl_parse_image_header(struct spl_image_info *spl_image, |
95 | const struct image_header *header) | |
8cf686e1 A |
96 | { |
97 | u32 header_size = sizeof(struct image_header); | |
98 | ||
77552b06 | 99 | if (image_get_magic(header) == IH_MAGIC) { |
71316c1d | 100 | if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY) { |
022b4975 SR |
101 | /* |
102 | * On some system (e.g. powerpc), the load-address and | |
103 | * entry-point is located at address 0. We can't load | |
104 | * to 0-0x40. So skip header in this case. | |
105 | */ | |
71316c1d SG |
106 | spl_image->load_addr = image_get_load(header); |
107 | spl_image->entry_point = image_get_ep(header); | |
108 | spl_image->size = image_get_data_size(header); | |
022b4975 | 109 | } else { |
71316c1d | 110 | spl_image->entry_point = image_get_load(header); |
022b4975 | 111 | /* Load including the header */ |
71316c1d | 112 | spl_image->load_addr = spl_image->entry_point - |
022b4975 | 113 | header_size; |
71316c1d | 114 | spl_image->size = image_get_data_size(header) + |
022b4975 SR |
115 | header_size; |
116 | } | |
71316c1d SG |
117 | spl_image->os = image_get_os(header); |
118 | spl_image->name = image_get_name(header); | |
62cf11c0 | 119 | debug("spl: payload image: %.*s load addr: 0x%x size: %d\n", |
71316c1d SG |
120 | (int)sizeof(spl_image->name), spl_image->name, |
121 | spl_image->load_addr, spl_image->size); | |
8cf686e1 | 122 | } else { |
8c80eb3b AA |
123 | #ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE |
124 | /* | |
125 | * CONFIG_SPL_PANIC_ON_RAW_IMAGE is defined when the | |
126 | * code which loads images in SPL cannot guarantee that | |
127 | * absolutely all read errors will be reported. | |
128 | * An example is the LPC32XX MLC NAND driver, which | |
129 | * will consider that a completely unreadable NAND block | |
130 | * is bad, and thus should be skipped silently. | |
131 | */ | |
132 | panic("** no mkimage signature but raw image not supported"); | |
85a37729 PK |
133 | #endif |
134 | ||
431889d6 LM |
135 | #ifdef CONFIG_SPL_OS_BOOT |
136 | ulong start, end; | |
137 | ||
138 | if (!bootz_setup((ulong)header, &start, &end)) { | |
71316c1d SG |
139 | spl_image->name = "Linux"; |
140 | spl_image->os = IH_OS_LINUX; | |
141 | spl_image->load_addr = CONFIG_SYS_LOAD_ADDR; | |
142 | spl_image->entry_point = CONFIG_SYS_LOAD_ADDR; | |
143 | spl_image->size = end - start; | |
431889d6 | 144 | debug("spl: payload zImage, load addr: 0x%x size: %d\n", |
71316c1d | 145 | spl_image->load_addr, spl_image->size); |
431889d6 LM |
146 | return 0; |
147 | } | |
148 | #endif | |
85a37729 PK |
149 | |
150 | #ifdef CONFIG_SPL_ABORT_ON_RAW_IMAGE | |
151 | /* Signature not found, proceed to other boot methods. */ | |
152 | return -EINVAL; | |
153 | #else | |
8cf686e1 | 154 | /* Signature not found - assume u-boot.bin */ |
026b2fe3 | 155 | debug("mkimage signature not found - ih_magic = %x\n", |
8cf686e1 | 156 | header->ih_magic); |
71316c1d | 157 | spl_set_header_raw_uboot(spl_image); |
8c80eb3b | 158 | #endif |
8cf686e1 | 159 | } |
7e0f2267 | 160 | return 0; |
8cf686e1 A |
161 | } |
162 | ||
a759f1e0 | 163 | __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) |
8cf686e1 | 164 | { |
4a0eb757 S |
165 | typedef void __noreturn (*image_entry_noargs_t)(void); |
166 | ||
8cf686e1 | 167 | image_entry_noargs_t image_entry = |
b2d5ac59 | 168 | (image_entry_noargs_t)(unsigned long)spl_image->entry_point; |
8cf686e1 | 169 | |
a759f1e0 | 170 | debug("image entry point: 0x%X\n", spl_image->entry_point); |
4a0eb757 | 171 | image_entry(); |
8cf686e1 A |
172 | } |
173 | ||
8d16e1d5 MS |
174 | #ifndef CONFIG_SPL_LOAD_FIT_ADDRESS |
175 | # define CONFIG_SPL_LOAD_FIT_ADDRESS 0 | |
176 | #endif | |
177 | ||
6f8387f1 | 178 | #if defined(CONFIG_SPL_RAM_DEVICE) || defined(CONFIG_SPL_DFU_SUPPORT) |
8d16e1d5 MS |
179 | static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector, |
180 | ulong count, void *buf) | |
181 | { | |
182 | debug("%s: sector %lx, count %lx, buf %lx\n", | |
183 | __func__, sector, count, (ulong)buf); | |
184 | memcpy(buf, (void *)(CONFIG_SPL_LOAD_FIT_ADDRESS + sector), count); | |
185 | return count; | |
186 | } | |
187 | ||
ecdfd69a | 188 | static int spl_ram_load_image(struct spl_boot_device *bootdev) |
c57b953d | 189 | { |
8d16e1d5 MS |
190 | struct image_header *header; |
191 | ||
192 | header = (struct image_header *)CONFIG_SPL_LOAD_FIT_ADDRESS; | |
c57b953d | 193 | |
98136b2f SG |
194 | #if defined(CONFIG_SPL_DFU_SUPPORT) |
195 | if (bootdev->boot_device == BOOT_DEVICE_DFU) | |
196 | spl_dfu_cmd(0, "dfu_alt_info_ram", "ram", "0"); | |
197 | #endif | |
198 | ||
8d16e1d5 MS |
199 | if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && |
200 | image_get_magic(header) == FDT_MAGIC) { | |
201 | struct spl_load_info load; | |
c57b953d | 202 | |
8d16e1d5 MS |
203 | debug("Found FIT\n"); |
204 | load.bl_len = 1; | |
205 | load.read = spl_ram_load_read; | |
206 | spl_load_simple_fit(&load, 0, header); | |
207 | } else { | |
208 | debug("Legacy image\n"); | |
209 | /* | |
210 | * Get the header. It will point to an address defined by | |
211 | * handoff which will tell where the image located inside | |
212 | * the flash. For now, it will temporary fixed to address | |
213 | * pointed by U-Boot. | |
214 | */ | |
215 | header = (struct image_header *) | |
216 | (CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); | |
217 | ||
71316c1d | 218 | spl_parse_image_header(&spl_image, header); |
8d16e1d5 | 219 | } |
36afd451 NK |
220 | |
221 | return 0; | |
c57b953d | 222 | } |
98136b2f SG |
223 | SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_RAM, spl_ram_load_image); |
224 | #if defined(CONFIG_SPL_DFU_SUPPORT) | |
225 | SPL_LOAD_IMAGE_METHOD(0, BOOT_DEVICE_DFU, spl_ram_load_image); | |
226 | #endif | |
c57b953d PM |
227 | #endif |
228 | ||
070d00b8 | 229 | int spl_init(void) |
bcae7211 | 230 | { |
f3d46bd6 SG |
231 | int ret; |
232 | ||
070d00b8 SG |
233 | debug("spl_init()\n"); |
234 | #if defined(CONFIG_SYS_MALLOC_F_LEN) | |
94b9e22e MV |
235 | #ifdef CONFIG_MALLOC_F_ADDR |
236 | gd->malloc_base = CONFIG_MALLOC_F_ADDR; | |
237 | #endif | |
293f16b1 | 238 | gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN; |
fb4f5e7c | 239 | gd->malloc_ptr = 0; |
24dafad5 | 240 | #endif |
d223e0a8 | 241 | if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { |
f3d46bd6 SG |
242 | ret = fdtdec_setup(); |
243 | if (ret) { | |
244 | debug("fdtdec_setup() returned error %d\n", ret); | |
070d00b8 | 245 | return ret; |
f3d46bd6 SG |
246 | } |
247 | } | |
248 | if (IS_ENABLED(CONFIG_SPL_DM)) { | |
7d23b9cf SG |
249 | /* With CONFIG_OF_PLATDATA, bring in all devices */ |
250 | ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA)); | |
f3d46bd6 SG |
251 | if (ret) { |
252 | debug("dm_init_and_scan() returned error %d\n", ret); | |
070d00b8 | 253 | return ret; |
f3d46bd6 SG |
254 | } |
255 | } | |
070d00b8 | 256 | gd->flags |= GD_FLG_SPL_INIT; |
2d01dd95 | 257 | |
070d00b8 SG |
258 | return 0; |
259 | } | |
260 | ||
f101e4bd NK |
261 | #ifndef BOOT_DEVICE_NONE |
262 | #define BOOT_DEVICE_NONE 0xdeadbeef | |
263 | #endif | |
264 | ||
265 | static u32 spl_boot_list[] = { | |
266 | BOOT_DEVICE_NONE, | |
267 | BOOT_DEVICE_NONE, | |
268 | BOOT_DEVICE_NONE, | |
269 | BOOT_DEVICE_NONE, | |
270 | BOOT_DEVICE_NONE, | |
271 | }; | |
272 | ||
273 | __weak void board_boot_order(u32 *spl_boot_list) | |
274 | { | |
275 | spl_boot_list[0] = spl_boot_device(); | |
276 | } | |
277 | ||
310c8466 NK |
278 | #ifdef CONFIG_SPL_BOARD_LOAD_IMAGE |
279 | __weak void spl_board_announce_boot_device(void) { } | |
280 | #endif | |
281 | ||
282 | #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT | |
283 | struct boot_device_name { | |
284 | u32 boot_dev; | |
285 | const char *name; | |
286 | }; | |
287 | ||
288 | struct boot_device_name boot_name_table[] = { | |
289 | #ifdef CONFIG_SPL_RAM_DEVICE | |
290 | { BOOT_DEVICE_RAM, "RAM" }, | |
291 | #endif | |
292 | #ifdef CONFIG_SPL_MMC_SUPPORT | |
8f10b5c6 HG |
293 | { BOOT_DEVICE_MMC1, "MMC1" }, |
294 | { BOOT_DEVICE_MMC2, "MMC2" }, | |
295 | { BOOT_DEVICE_MMC2_2, "MMC2_2" }, | |
310c8466 NK |
296 | #endif |
297 | #ifdef CONFIG_SPL_NAND_SUPPORT | |
298 | { BOOT_DEVICE_NAND, "NAND" }, | |
299 | #endif | |
300 | #ifdef CONFIG_SPL_ONENAND_SUPPORT | |
301 | { BOOT_DEVICE_ONENAND, "OneNAND" }, | |
302 | #endif | |
303 | #ifdef CONFIG_SPL_NOR_SUPPORT | |
304 | { BOOT_DEVICE_NOR, "NOR" }, | |
305 | #endif | |
306 | #ifdef CONFIG_SPL_YMODEM_SUPPORT | |
307 | { BOOT_DEVICE_UART, "UART" }, | |
308 | #endif | |
19e99fb4 | 309 | #if defined(CONFIG_SPL_SPI_SUPPORT) || defined(CONFIG_SPL_SPI_FLASH_SUPPORT) |
310c8466 NK |
310 | { BOOT_DEVICE_SPI, "SPI" }, |
311 | #endif | |
312 | #ifdef CONFIG_SPL_ETH_SUPPORT | |
313 | #ifdef CONFIG_SPL_ETH_DEVICE | |
314 | { BOOT_DEVICE_CPGMAC, "eth device" }, | |
315 | #else | |
316 | { BOOT_DEVICE_CPGMAC, "net" }, | |
317 | #endif | |
318 | #endif | |
319 | #ifdef CONFIG_SPL_USBETH_SUPPORT | |
320 | { BOOT_DEVICE_USBETH, "USB eth" }, | |
321 | #endif | |
322 | #ifdef CONFIG_SPL_USB_SUPPORT | |
323 | { BOOT_DEVICE_USB, "USB" }, | |
324 | #endif | |
6f8387f1 R |
325 | #ifdef CONFIG_SPL_DFU_SUPPORT |
326 | { BOOT_DEVICE_DFU, "USB DFU" }, | |
327 | #endif | |
310c8466 NK |
328 | #ifdef CONFIG_SPL_SATA_SUPPORT |
329 | { BOOT_DEVICE_SATA, "SATA" }, | |
330 | #endif | |
331 | /* Keep this entry last */ | |
332 | { BOOT_DEVICE_NONE, "unknown boot device" }, | |
333 | }; | |
334 | ||
335 | static void announce_boot_device(u32 boot_device) | |
336 | { | |
337 | int i; | |
338 | ||
339 | puts("Trying to boot from "); | |
340 | ||
341 | #ifdef CONFIG_SPL_BOARD_LOAD_IMAGE | |
342 | if (boot_device == BOOT_DEVICE_BOARD) { | |
343 | spl_board_announce_boot_device(); | |
344 | puts("\n"); | |
345 | return; | |
346 | } | |
347 | #endif | |
348 | for (i = 0; i < ARRAY_SIZE(boot_name_table) - 1; i++) { | |
349 | if (boot_name_table[i].boot_dev == boot_device) | |
350 | break; | |
351 | } | |
352 | ||
353 | printf("%s\n", boot_name_table[i].name); | |
354 | } | |
355 | #else | |
356 | static inline void announce_boot_device(u32 boot_device) { } | |
357 | #endif | |
358 | ||
a0a80290 SG |
359 | static struct spl_image_loader *spl_ll_find_loader(uint boot_device) |
360 | { | |
361 | struct spl_image_loader *drv = | |
362 | ll_entry_start(struct spl_image_loader, spl_image_loader); | |
363 | const int n_ents = | |
364 | ll_entry_count(struct spl_image_loader, spl_image_loader); | |
365 | struct spl_image_loader *entry; | |
366 | ||
367 | for (entry = drv; entry != drv + n_ents; entry++) { | |
368 | if (boot_device == entry->boot_device) | |
369 | return entry; | |
370 | } | |
371 | ||
372 | /* Not found */ | |
373 | return NULL; | |
374 | } | |
375 | ||
5211b87e | 376 | static int spl_load_image(u32 boot_device) |
070d00b8 | 377 | { |
ecdfd69a | 378 | struct spl_boot_device bootdev; |
a0a80290 | 379 | struct spl_image_loader *loader = spl_ll_find_loader(boot_device); |
ecdfd69a SG |
380 | |
381 | bootdev.boot_device = boot_device; | |
382 | bootdev.boot_device_name = NULL; | |
a0a80290 SG |
383 | if (loader) |
384 | return loader->load_image(&bootdev); | |
ecdfd69a | 385 | |
8cf686e1 | 386 | switch (boot_device) { |
19e99fb4 | 387 | #if defined(CONFIG_SPL_SPI_SUPPORT) || defined(CONFIG_SPL_SPI_FLASH_SUPPORT) |
d4c4e0e1 | 388 | case BOOT_DEVICE_SPI: |
ecdfd69a | 389 | return spl_spi_load_image(&bootdev); |
7ac2fe2d IY |
390 | #endif |
391 | #ifdef CONFIG_SPL_ETH_SUPPORT | |
392 | case BOOT_DEVICE_CPGMAC: | |
393 | #ifdef CONFIG_SPL_ETH_DEVICE | |
ecdfd69a | 394 | bootdev.boot_device_name = CONFIG_SPL_ETH_DEVICE; |
7ac2fe2d | 395 | #endif |
ecdfd69a | 396 | return spl_net_load_image(&bootdev); |
62a81431 IY |
397 | #endif |
398 | #ifdef CONFIG_SPL_USBETH_SUPPORT | |
399 | case BOOT_DEVICE_USBETH: | |
ecdfd69a SG |
400 | bootdev.boot_device_name = "usb_ether"; |
401 | return spl_net_load_image(&bootdev); | |
8cffe5bd DM |
402 | #endif |
403 | #ifdef CONFIG_SPL_USB_SUPPORT | |
404 | case BOOT_DEVICE_USB: | |
ecdfd69a | 405 | return spl_usb_load_image(&bootdev); |
fff40a7e DM |
406 | #endif |
407 | #ifdef CONFIG_SPL_SATA_SUPPORT | |
408 | case BOOT_DEVICE_SATA: | |
ecdfd69a | 409 | return spl_sata_load_image(&bootdev); |
c01c71bc SG |
410 | #endif |
411 | #ifdef CONFIG_SPL_BOARD_LOAD_IMAGE | |
412 | case BOOT_DEVICE_BOARD: | |
ecdfd69a | 413 | return spl_board_load_image(&bootdev); |
bb085b87 | 414 | #endif |
8cf686e1 | 415 | default: |
18f26fdb | 416 | #if defined(CONFIG_SPL_SERIAL_SUPPORT) && defined(CONFIG_SPL_LIBCOMMON_SUPPORT) |
e860d012 | 417 | puts("SPL: Unsupported Boot Device!\n"); |
18f26fdb | 418 | #endif |
5211b87e | 419 | return -ENODEV; |
8cf686e1 A |
420 | } |
421 | ||
5211b87e NK |
422 | return -EINVAL; |
423 | } | |
424 | ||
425 | void board_init_r(gd_t *dummy1, ulong dummy2) | |
426 | { | |
f101e4bd | 427 | int i; |
5211b87e NK |
428 | |
429 | debug(">>spl:board_init_r()\n"); | |
430 | ||
431 | #if defined(CONFIG_SYS_SPL_MALLOC_START) | |
432 | mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, | |
433 | CONFIG_SYS_SPL_MALLOC_SIZE); | |
434 | gd->flags |= GD_FLG_FULL_MALLOC_INIT; | |
435 | #endif | |
436 | if (!(gd->flags & GD_FLG_SPL_INIT)) { | |
437 | if (spl_init()) | |
438 | hang(); | |
439 | } | |
440 | #ifndef CONFIG_PPC | |
441 | /* | |
442 | * timer_init() does not exist on PPC systems. The timer is initialized | |
443 | * and enabled (decrementer) in interrupt_init() here. | |
444 | */ | |
445 | timer_init(); | |
446 | #endif | |
447 | ||
448 | #ifdef CONFIG_SPL_BOARD_INIT | |
449 | spl_board_init(); | |
450 | #endif | |
451 | ||
f101e4bd NK |
452 | board_boot_order(spl_boot_list); |
453 | for (i = 0; i < ARRAY_SIZE(spl_boot_list) && | |
454 | spl_boot_list[i] != BOOT_DEVICE_NONE; i++) { | |
310c8466 | 455 | announce_boot_device(spl_boot_list[i]); |
f101e4bd NK |
456 | if (!spl_load_image(spl_boot_list[i])) |
457 | break; | |
458 | } | |
459 | ||
460 | if (i == ARRAY_SIZE(spl_boot_list) || | |
461 | spl_boot_list[i] == BOOT_DEVICE_NONE) { | |
462 | puts("SPL: failed to boot from all boot devices\n"); | |
5211b87e | 463 | hang(); |
f101e4bd | 464 | } |
5211b87e | 465 | |
9ea5c6ef | 466 | switch (spl_image.os) { |
8cf686e1 A |
467 | case IH_OS_U_BOOT: |
468 | debug("Jumping to U-Boot\n"); | |
8cf686e1 | 469 | break; |
379c19ab SS |
470 | #ifdef CONFIG_SPL_OS_BOOT |
471 | case IH_OS_LINUX: | |
472 | debug("Jumping to Linux\n"); | |
473 | spl_board_prepare_for_linux(); | |
ca12e65c SG |
474 | jump_to_image_linux(&spl_image, |
475 | (void *)CONFIG_SYS_SPL_ARGS_ADDR); | |
379c19ab | 476 | #endif |
8cf686e1 | 477 | default: |
42120981 | 478 | debug("Unsupported OS image.. Jumping nevertheless..\n"); |
8cf686e1 | 479 | } |
fb4f5e7c SG |
480 | #if defined(CONFIG_SYS_MALLOC_F_LEN) && !defined(CONFIG_SYS_SPL_MALLOC_SIZE) |
481 | debug("SPL malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr, | |
482 | gd->malloc_ptr / 1024); | |
483 | #endif | |
484 | ||
aea3d40d | 485 | debug("loaded - jumping to U-Boot..."); |
3a3b9147 | 486 | spl_board_prepare_for_boot(); |
a759f1e0 | 487 | jump_to_image_no_args(&spl_image); |
bcae7211 A |
488 | } |
489 | ||
6507f133 TR |
490 | /* |
491 | * This requires UART clocks to be enabled. In order for this to work the | |
492 | * caller must ensure that the gd pointer is valid. | |
493 | */ | |
bcae7211 A |
494 | void preloader_console_init(void) |
495 | { | |
bcae7211 | 496 | gd->bd = &bdata; |
bcae7211 A |
497 | gd->baudrate = CONFIG_BAUDRATE; |
498 | ||
bcae7211 A |
499 | serial_init(); /* serial communications setup */ |
500 | ||
b88befa5 IY |
501 | gd->have_console = 1; |
502 | ||
026b2fe3 TR |
503 | puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \ |
504 | U_BOOT_TIME ")\n"); | |
861a86f4 TR |
505 | #ifdef CONFIG_SPL_DISPLAY_PRINT |
506 | spl_display_print(); | |
507 | #endif | |
cc3f7058 | 508 | } |
db910353 SG |
509 | |
510 | /** | |
511 | * spl_relocate_stack_gd() - Relocate stack ready for board_init_r() execution | |
512 | * | |
513 | * Sometimes board_init_f() runs with a stack in SRAM but we want to use SDRAM | |
514 | * for the main board_init_r() execution. This is typically because we need | |
515 | * more stack space for things like the MMC sub-system. | |
516 | * | |
517 | * This function calculates the stack position, copies the global_data into | |
adc421e4 AA |
518 | * place, sets the new gd (except for ARM, for which setting GD within a C |
519 | * function may not always work) and returns the new stack position. The | |
520 | * caller is responsible for setting up the sp register and, in the case | |
521 | * of ARM, setting up gd. | |
522 | * | |
523 | * All of this is done using the same layout and alignments as done in | |
524 | * board_init_f_init_reserve() / board_init_f_alloc_reserve(). | |
db910353 SG |
525 | * |
526 | * @return new stack location, or 0 to use the same stack | |
527 | */ | |
528 | ulong spl_relocate_stack_gd(void) | |
529 | { | |
530 | #ifdef CONFIG_SPL_STACK_R | |
531 | gd_t *new_gd; | |
adc421e4 | 532 | ulong ptr = CONFIG_SPL_STACK_R_ADDR; |
db910353 | 533 | |
dcfcb8d4 HG |
534 | #ifdef CONFIG_SPL_SYS_MALLOC_SIMPLE |
535 | if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) { | |
dcfcb8d4 HG |
536 | ptr -= CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN; |
537 | gd->malloc_base = ptr; | |
538 | gd->malloc_limit = CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN; | |
539 | gd->malloc_ptr = 0; | |
540 | } | |
541 | #endif | |
adc421e4 AA |
542 | /* Get stack position: use 8-byte alignment for ABI compliance */ |
543 | ptr = CONFIG_SPL_STACK_R_ADDR - roundup(sizeof(gd_t),16); | |
544 | new_gd = (gd_t *)ptr; | |
545 | memcpy(new_gd, (void *)gd, sizeof(gd_t)); | |
546 | #if !defined(CONFIG_ARM) | |
547 | gd = new_gd; | |
548 | #endif | |
db910353 SG |
549 | return ptr; |
550 | #else | |
551 | return 0; | |
552 | #endif | |
553 | } |