1
2
3
4
5
6
7
8
9#include <common.h>
10#include <dm.h>
11#include <spl.h>
12#include <asm/u-boot.h>
13#include <nand.h>
14#include <fat.h>
15#include <version.h>
16#include <image.h>
17#include <malloc.h>
18#include <dm/root.h>
19#include <linux/compiler.h>
20
21DECLARE_GLOBAL_DATA_PTR;
22
23#ifndef CONFIG_SYS_UBOOT_START
24#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
25#endif
26#ifndef CONFIG_SYS_MONITOR_LEN
27
28#define CONFIG_SYS_MONITOR_LEN (200 * 1024)
29#endif
30
31u32 *boot_params_ptr = NULL;
32
33
34static bd_t bdata __attribute__ ((section(".data")));
35
36
37
38
39__weak void show_boot_progress(int val) {}
40
41
42
43
44
45
46
47
48
49
50
51#ifdef CONFIG_SPL_OS_BOOT
52__weak int spl_start_uboot(void)
53{
54 puts("SPL: Please implement spl_start_uboot() for your board\n");
55 puts("SPL: Direct Linux boot not active!\n");
56 return 1;
57}
58
59
60
61
62
63int __weak bootz_setup(ulong image, ulong *start, ulong *end)
64{
65 return 1;
66}
67#endif
68
69
70
71
72
73
74__weak void spl_board_prepare_for_linux(void)
75{
76
77}
78
79__weak void spl_board_prepare_for_boot(void)
80{
81
82}
83
84void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
85{
86 spl_image->size = CONFIG_SYS_MONITOR_LEN;
87 spl_image->entry_point = CONFIG_SYS_UBOOT_START;
88 spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
89 spl_image->os = IH_OS_U_BOOT;
90 spl_image->name = "U-Boot";
91}
92
93int spl_parse_image_header(struct spl_image_info *spl_image,
94 const struct image_header *header)
95{
96 u32 header_size = sizeof(struct image_header);
97
98 if (image_get_magic(header) == IH_MAGIC) {
99 if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY) {
100
101
102
103
104
105 spl_image->load_addr = image_get_load(header);
106 spl_image->entry_point = image_get_ep(header);
107 spl_image->size = image_get_data_size(header);
108 } else {
109 spl_image->entry_point = image_get_load(header);
110
111 spl_image->load_addr = spl_image->entry_point -
112 header_size;
113 spl_image->size = image_get_data_size(header) +
114 header_size;
115 }
116 spl_image->os = image_get_os(header);
117 spl_image->name = image_get_name(header);
118 debug("spl: payload image: %.*s load addr: 0x%x size: %d\n",
119 (int)sizeof(spl_image->name), spl_image->name,
120 spl_image->load_addr, spl_image->size);
121 } else {
122#ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE
123
124
125
126
127
128
129
130
131 panic("** no mkimage signature but raw image not supported");
132#endif
133
134#ifdef CONFIG_SPL_OS_BOOT
135 ulong start, end;
136
137 if (!bootz_setup((ulong)header, &start, &end)) {
138 spl_image->name = "Linux";
139 spl_image->os = IH_OS_LINUX;
140 spl_image->load_addr = CONFIG_SYS_LOAD_ADDR;
141 spl_image->entry_point = CONFIG_SYS_LOAD_ADDR;
142 spl_image->size = end - start;
143 debug("spl: payload zImage, load addr: 0x%x size: %d\n",
144 spl_image->load_addr, spl_image->size);
145 return 0;
146 }
147#endif
148
149#ifdef CONFIG_SPL_ABORT_ON_RAW_IMAGE
150
151 return -EINVAL;
152#else
153
154 debug("mkimage signature not found - ih_magic = %x\n",
155 header->ih_magic);
156 spl_set_header_raw_uboot(spl_image);
157#endif
158 }
159 return 0;
160}
161
162__weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
163{
164 typedef void __noreturn (*image_entry_noargs_t)(void);
165
166 image_entry_noargs_t image_entry =
167 (image_entry_noargs_t)(unsigned long)spl_image->entry_point;
168
169 debug("image entry point: 0x%X\n", spl_image->entry_point);
170 image_entry();
171}
172
173#ifndef CONFIG_SPL_LOAD_FIT_ADDRESS
174# define CONFIG_SPL_LOAD_FIT_ADDRESS 0
175#endif
176
177#if defined(CONFIG_SPL_RAM_DEVICE) || defined(CONFIG_SPL_DFU_SUPPORT)
178static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector,
179 ulong count, void *buf)
180{
181 debug("%s: sector %lx, count %lx, buf %lx\n",
182 __func__, sector, count, (ulong)buf);
183 memcpy(buf, (void *)(CONFIG_SPL_LOAD_FIT_ADDRESS + sector), count);
184 return count;
185}
186
187static int spl_ram_load_image(struct spl_image_info *spl_image,
188 struct spl_boot_device *bootdev)
189{
190 struct image_header *header;
191
192 header = (struct image_header *)CONFIG_SPL_LOAD_FIT_ADDRESS;
193
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
199 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
200 image_get_magic(header) == FDT_MAGIC) {
201 struct spl_load_info load;
202
203 debug("Found FIT\n");
204 load.bl_len = 1;
205 load.read = spl_ram_load_read;
206 spl_load_simple_fit(spl_image, &load, 0, header);
207 } else {
208 debug("Legacy image\n");
209
210
211
212
213
214
215 header = (struct image_header *)
216 (CONFIG_SYS_TEXT_BASE - sizeof(struct image_header));
217
218 spl_parse_image_header(spl_image, header);
219 }
220
221 return 0;
222}
223#if defined(CONFIG_SPL_RAM_DEVICE)
224SPL_LOAD_IMAGE_METHOD("RAM", 0, BOOT_DEVICE_RAM, spl_ram_load_image);
225#endif
226#if defined(CONFIG_SPL_DFU_SUPPORT)
227SPL_LOAD_IMAGE_METHOD("USB DFU", 0, BOOT_DEVICE_DFU, spl_ram_load_image);
228#endif
229#endif
230
231int spl_init(void)
232{
233 int ret;
234
235 debug("spl_init()\n");
236#if defined(CONFIG_SYS_MALLOC_F_LEN)
237#ifdef CONFIG_MALLOC_F_ADDR
238 gd->malloc_base = CONFIG_MALLOC_F_ADDR;
239#endif
240 gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN;
241 gd->malloc_ptr = 0;
242#endif
243 if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
244 ret = fdtdec_setup();
245 if (ret) {
246 debug("fdtdec_setup() returned error %d\n", ret);
247 return ret;
248 }
249 }
250 if (IS_ENABLED(CONFIG_SPL_DM)) {
251
252 ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA));
253 if (ret) {
254 debug("dm_init_and_scan() returned error %d\n", ret);
255 return ret;
256 }
257 }
258 gd->flags |= GD_FLG_SPL_INIT;
259
260 return 0;
261}
262
263#ifndef BOOT_DEVICE_NONE
264#define BOOT_DEVICE_NONE 0xdeadbeef
265#endif
266
267__weak void board_boot_order(u32 *spl_boot_list)
268{
269 spl_boot_list[0] = spl_boot_device();
270}
271
272static struct spl_image_loader *spl_ll_find_loader(uint boot_device)
273{
274 struct spl_image_loader *drv =
275 ll_entry_start(struct spl_image_loader, spl_image_loader);
276 const int n_ents =
277 ll_entry_count(struct spl_image_loader, spl_image_loader);
278 struct spl_image_loader *entry;
279
280 for (entry = drv; entry != drv + n_ents; entry++) {
281 if (boot_device == entry->boot_device)
282 return entry;
283 }
284
285
286 return NULL;
287}
288
289static int spl_load_image(struct spl_image_info *spl_image,
290 struct spl_image_loader *loader)
291{
292 struct spl_boot_device bootdev;
293
294 bootdev.boot_device = loader->boot_device;
295 bootdev.boot_device_name = NULL;
296
297 return loader->load_image(spl_image, &bootdev);
298}
299
300
301
302
303
304
305
306
307
308static int boot_from_devices(struct spl_image_info *spl_image,
309 u32 spl_boot_list[], int count)
310{
311 int i;
312
313 for (i = 0; i < count && spl_boot_list[i] != BOOT_DEVICE_NONE; i++) {
314 struct spl_image_loader *loader;
315
316 loader = spl_ll_find_loader(spl_boot_list[i]);
317#if defined(CONFIG_SPL_SERIAL_SUPPORT) && defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
318 if (loader)
319 printf("Trying to boot from %s\n", loader->name);
320 else
321 puts("SPL: Unsupported Boot Device!\n");
322#endif
323 if (loader && !spl_load_image(spl_image, loader))
324 return 0;
325 }
326
327 return -ENODEV;
328}
329
330void board_init_r(gd_t *dummy1, ulong dummy2)
331{
332 u32 spl_boot_list[] = {
333 BOOT_DEVICE_NONE,
334 BOOT_DEVICE_NONE,
335 BOOT_DEVICE_NONE,
336 BOOT_DEVICE_NONE,
337 BOOT_DEVICE_NONE,
338 };
339 struct spl_image_info spl_image;
340
341 debug(">>spl:board_init_r()\n");
342
343#if defined(CONFIG_SYS_SPL_MALLOC_START)
344 mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START,
345 CONFIG_SYS_SPL_MALLOC_SIZE);
346 gd->flags |= GD_FLG_FULL_MALLOC_INIT;
347#endif
348 if (!(gd->flags & GD_FLG_SPL_INIT)) {
349 if (spl_init())
350 hang();
351 }
352#ifndef CONFIG_PPC
353
354
355
356
357 timer_init();
358#endif
359
360#ifdef CONFIG_SPL_BOARD_INIT
361 spl_board_init();
362#endif
363
364 memset(&spl_image, '\0', sizeof(spl_image));
365 board_boot_order(spl_boot_list);
366
367 if (boot_from_devices(&spl_image, spl_boot_list,
368 ARRAY_SIZE(spl_boot_list))) {
369 puts("SPL: failed to boot from all boot devices\n");
370 hang();
371 }
372
373 switch (spl_image.os) {
374 case IH_OS_U_BOOT:
375 debug("Jumping to U-Boot\n");
376 break;
377#ifdef CONFIG_SPL_OS_BOOT
378 case IH_OS_LINUX:
379 debug("Jumping to Linux\n");
380 spl_board_prepare_for_linux();
381 jump_to_image_linux(&spl_image,
382 (void *)CONFIG_SYS_SPL_ARGS_ADDR);
383#endif
384 default:
385 debug("Unsupported OS image.. Jumping nevertheless..\n");
386 }
387#if defined(CONFIG_SYS_MALLOC_F_LEN) && !defined(CONFIG_SYS_SPL_MALLOC_SIZE)
388 debug("SPL malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr,
389 gd->malloc_ptr / 1024);
390#endif
391
392 debug("loaded - jumping to U-Boot...");
393 spl_board_prepare_for_boot();
394 jump_to_image_no_args(&spl_image);
395}
396
397
398
399
400
401void preloader_console_init(void)
402{
403 gd->bd = &bdata;
404 gd->baudrate = CONFIG_BAUDRATE;
405
406 serial_init();
407
408 gd->have_console = 1;
409
410 puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
411 U_BOOT_TIME ")\n");
412#ifdef CONFIG_SPL_DISPLAY_PRINT
413 spl_display_print();
414#endif
415}
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435ulong spl_relocate_stack_gd(void)
436{
437#ifdef CONFIG_SPL_STACK_R
438 gd_t *new_gd;
439 ulong ptr = CONFIG_SPL_STACK_R_ADDR;
440
441#ifdef CONFIG_SPL_SYS_MALLOC_SIMPLE
442 if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) {
443 ptr -= CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN;
444 gd->malloc_base = ptr;
445 gd->malloc_limit = CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN;
446 gd->malloc_ptr = 0;
447 }
448#endif
449
450 ptr = CONFIG_SPL_STACK_R_ADDR - roundup(sizeof(gd_t),16);
451 new_gd = (gd_t *)ptr;
452 memcpy(new_gd, (void *)gd, sizeof(gd_t));
453#if CONFIG_IS_ENABLED(DM)
454 dm_fixup_for_gd_move(new_gd);
455#endif
456#if !defined(CONFIG_ARM)
457 gd = new_gd;
458#endif
459 return ptr;
460#else
461 return 0;
462#endif
463}
464