1 /* 2 * (C) Copyright 2010 3 * Texas Instruments, <www.ti.com> 4 * 5 * Aneesh V <aneesh@ti.com> 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <dm.h> 12 #include <spl.h> 13 #include <asm/sections.h> 14 #include <asm/u-boot.h> 15 #include <nand.h> 16 #include <fat.h> 17 #include <version.h> 18 #include <image.h> 19 #include <malloc.h> 20 #include <mp_boot.h> 21 #include <dm/root.h> 22 #include <linux/compiler.h> 23 #include <fdt_support.h> 24 25 DECLARE_GLOBAL_DATA_PTR; 26 27 #ifndef CONFIG_SYS_UBOOT_START 28 #define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE 29 #endif 30 #ifndef CONFIG_SYS_MONITOR_LEN 31 /* Unknown U-Boot size, let's assume it will not be more than 200 KB */ 32 #define CONFIG_SYS_MONITOR_LEN (200 * 1024) 33 #endif 34 35 u32 *boot_params_ptr = NULL; 36 37 /* Define board data structure */ 38 static bd_t bdata __attribute__ ((section(".data"))); 39 40 /* 41 * Board-specific Platform code can reimplement show_boot_progress () if needed 42 */ 43 __weak void show_boot_progress(int val) {} 44 45 /* 46 * Default function to determine if u-boot or the OS should 47 * be started. This implementation always returns 1. 48 * 49 * Please implement your own board specific funcion to do this. 50 * 51 * RETURN 52 * 0 to not start u-boot 53 * positive if u-boot should start 54 */ 55 #ifdef CONFIG_SPL_OS_BOOT 56 __weak int spl_start_uboot(void) 57 { 58 puts("SPL: Please implement spl_start_uboot() for your board\n"); 59 puts("SPL: Direct Linux boot not active!\n"); 60 return 1; 61 } 62 63 /* weak default platform specific function to initialize 64 * dram banks 65 */ 66 __weak int dram_init_banksize(void) 67 { 68 return 0; 69 } 70 71 /* 72 * Weak default function for arch specific zImage check. Return zero 73 * and fill start and end address if image is recognized. 74 */ 75 int __weak bootz_setup(ulong image, ulong *start, ulong *end) 76 { 77 return 1; 78 } 79 #endif 80 81 /* Weak default function for arch/board-specific fixups to the spl_image_info */ 82 void __weak spl_perform_fixups(struct spl_image_info *spl_image) 83 { 84 } 85 86 /* Get the next stage process */ 87 __weak void spl_next_stage(struct spl_image_info *spl) 88 { 89 spl->next_stage = SPL_NEXT_STAGE_UBOOT; 90 } 91 92 /* Weak default function for arch/board-specific preppare before jumping */ 93 int __weak spl_board_prepare_for_jump(struct spl_image_info *spl_image) 94 { 95 return 0; 96 } 97 98 /* Fix storages, like iomux */ 99 __weak void spl_board_storages_fixup(struct spl_image_loader *loader) 100 { 101 /* Nothing to do! */ 102 } 103 104 void spl_fixup_fdt(void) 105 { 106 #if defined(CONFIG_SPL_OF_LIBFDT) && defined(CONFIG_SYS_SPL_ARGS_ADDR) 107 void *fdt_blob = (void *)CONFIG_SYS_SPL_ARGS_ADDR; 108 int err; 109 110 err = fdt_check_header(fdt_blob); 111 if (err < 0) { 112 printf("fdt_root: %s\n", fdt_strerror(err)); 113 return; 114 } 115 116 /* fixup the memory dt node */ 117 err = fdt_shrink_to_minimum(fdt_blob, 0); 118 if (err == 0) { 119 printf("spl: fdt_shrink_to_minimum err - %d\n", err); 120 return; 121 } 122 123 err = arch_fixup_fdt(fdt_blob); 124 if (err) { 125 printf("spl: arch_fixup_fdt err - %d\n", err); 126 return; 127 } 128 #endif 129 } 130 131 /* 132 * Weak default function for board specific cleanup/preparation before 133 * Linux boot. Some boards/platforms might not need it, so just provide 134 * an empty stub here. 135 */ 136 __weak void spl_board_prepare_for_linux(void) 137 { 138 /* Nothing to do! */ 139 } 140 141 __weak void spl_board_prepare_for_boot(void) 142 { 143 /* Nothing to do! */ 144 } 145 146 void spl_set_header_raw_uboot(struct spl_image_info *spl_image) 147 { 148 spl_image->size = CONFIG_SYS_MONITOR_LEN; 149 spl_image->entry_point = CONFIG_SYS_UBOOT_START; 150 spl_image->load_addr = CONFIG_SYS_TEXT_BASE; 151 spl_image->os = IH_OS_U_BOOT; 152 spl_image->name = "U-Boot"; 153 } 154 155 int spl_parse_image_header(struct spl_image_info *spl_image, 156 const struct image_header *header) 157 { 158 if (image_get_magic(header) == IH_MAGIC) { 159 #ifdef CONFIG_SPL_LEGACY_IMAGE_SUPPORT 160 u32 header_size = sizeof(struct image_header); 161 162 if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY) { 163 /* 164 * On some system (e.g. powerpc), the load-address and 165 * entry-point is located at address 0. We can't load 166 * to 0-0x40. So skip header in this case. 167 */ 168 spl_image->load_addr = image_get_load(header); 169 spl_image->entry_point = image_get_ep(header); 170 spl_image->size = image_get_data_size(header); 171 } else { 172 spl_image->entry_point = image_get_load(header); 173 /* Load including the header */ 174 spl_image->load_addr = spl_image->entry_point - 175 header_size; 176 spl_image->size = image_get_data_size(header) + 177 header_size; 178 } 179 spl_image->os = image_get_os(header); 180 spl_image->name = image_get_name(header); 181 debug("spl: payload image: %.*s load addr: 0x%lx size: %d\n", 182 IH_NMLEN, spl_image->name, 183 spl_image->load_addr, spl_image->size); 184 #else 185 /* LEGACY image not supported */ 186 debug("Legacy boot image support not enabled, proceeding to other boot methods\n"); 187 return -EINVAL; 188 #endif 189 } else { 190 #ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE 191 /* 192 * CONFIG_SPL_PANIC_ON_RAW_IMAGE is defined when the 193 * code which loads images in SPL cannot guarantee that 194 * absolutely all read errors will be reported. 195 * An example is the LPC32XX MLC NAND driver, which 196 * will consider that a completely unreadable NAND block 197 * is bad, and thus should be skipped silently. 198 */ 199 panic("** no mkimage signature but raw image not supported"); 200 #endif 201 202 #ifdef CONFIG_SPL_OS_BOOT 203 ulong start, end; 204 205 if (!bootz_setup((ulong)header, &start, &end)) { 206 spl_image->name = "Linux"; 207 spl_image->os = IH_OS_LINUX; 208 spl_image->load_addr = CONFIG_SYS_LOAD_ADDR; 209 spl_image->entry_point = CONFIG_SYS_LOAD_ADDR; 210 spl_image->size = end - start; 211 debug("spl: payload zImage, load addr: 0x%lx size: %d\n", 212 spl_image->load_addr, spl_image->size); 213 return 0; 214 } 215 #endif 216 217 #ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT 218 /* Signature not found - assume u-boot.bin */ 219 debug("mkimage signature not found - ih_magic = %x\n", 220 header->ih_magic); 221 spl_set_header_raw_uboot(spl_image); 222 #else 223 /* RAW image not supported, proceed to other boot methods. */ 224 debug("Raw boot image support not enabled, proceeding to other boot methods\n"); 225 return -EINVAL; 226 #endif 227 } 228 229 return 0; 230 } 231 232 __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) 233 { 234 typedef void __noreturn (*image_entry_noargs_t)(void); 235 236 image_entry_noargs_t image_entry = 237 (image_entry_noargs_t)spl_image->entry_point; 238 239 debug("image entry point: 0x%lX\n", spl_image->entry_point); 240 image_entry(); 241 } 242 243 /* 244 * 64-bit: No special operation. 245 * 246 * 32-bit: Initial gd->bd->bi_dram[] to active dcache attr of memory. 247 * Assuming 256MB is enough for SPL(MMU still maps 4GB size). 248 */ 249 #ifndef CONFIG_SPL_SYS_DCACHE_OFF 250 static int spl_dcache_enable(void) 251 { 252 bool free_bd = false; 253 254 #ifndef CONFIG_ARM64 255 if (!gd->bd) { 256 gd->bd = calloc(1, sizeof(bd_t)); 257 if (!gd->bd) { 258 debug("spl: no bd_t memory\n"); 259 return -ENOMEM; 260 } 261 gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; 262 gd->bd->bi_dram[0].size = SZ_256M; 263 free_bd = true; 264 } 265 #endif 266 /* TLB memory should be SZ_16K base align and 4KB end align */ 267 gd->arch.tlb_size = PGTABLE_SIZE; 268 gd->arch.tlb_addr = (ulong)memalign(SZ_16K, ALIGN(PGTABLE_SIZE, SZ_4K)); 269 if (!gd->arch.tlb_addr) { 270 debug("spl: no TLB memory\n"); 271 return -ENOMEM; 272 } 273 274 dcache_enable(); 275 if (free_bd) 276 free(gd->bd); 277 278 return 0; 279 } 280 #endif 281 282 static int spl_common_init(bool setup_malloc) 283 { 284 int ret; 285 286 debug("spl_early_init()\n"); 287 288 #if CONFIG_VAL(SYS_MALLOC_F_LEN) 289 if (setup_malloc) { 290 #ifdef CONFIG_MALLOC_F_ADDR 291 gd->malloc_base = CONFIG_MALLOC_F_ADDR; 292 #endif 293 gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN); 294 gd->malloc_ptr = 0; 295 } 296 #endif 297 298 /* 299 * setup D-cache as early as possible after malloc setup 300 * I-cache has been setup at early assembly code by default. 301 */ 302 #ifndef CONFIG_SPL_SYS_DCACHE_OFF 303 ret = spl_dcache_enable(); 304 if (ret) { 305 debug("spl_dcache_enable() return error %d\n", ret); 306 return ret; 307 } 308 #endif 309 ret = bootstage_init(true); 310 if (ret) { 311 debug("%s: Failed to set up bootstage: ret=%d\n", __func__, 312 ret); 313 return ret; 314 } 315 bootstage_mark_name(BOOTSTAGE_ID_START_SPL, "spl"); 316 if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { 317 ret = fdtdec_setup(); 318 if (ret) { 319 debug("fdtdec_setup() returned error %d\n", ret); 320 return ret; 321 } 322 } 323 if (CONFIG_IS_ENABLED(DM)) { 324 bootstage_start(BOOTSTATE_ID_ACCUM_DM_SPL, "dm_spl"); 325 /* With CONFIG_SPL_OF_PLATDATA, bring in all devices */ 326 ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA)); 327 bootstage_accum(BOOTSTATE_ID_ACCUM_DM_SPL); 328 if (ret) { 329 debug("dm_init_and_scan() returned error %d\n", ret); 330 return ret; 331 } 332 } 333 334 return 0; 335 } 336 337 #if !defined(CONFIG_SPL_SKIP_RELOCATE) && !defined(CONFIG_TPL_BUILD) 338 static void spl_setup_relocate(void) 339 { 340 gd->relocaddr = CONFIG_SPL_RELOC_TEXT_BASE; 341 gd->new_gd = (gd_t *)gd; 342 gd->start_addr_sp = gd->relocaddr; 343 gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32); 344 345 gd->start_addr_sp -= gd->fdt_size; 346 gd->new_fdt = (void *)gd->start_addr_sp; 347 memcpy(gd->new_fdt, gd->fdt_blob, gd->fdt_size); 348 gd->fdt_blob = gd->new_fdt; 349 350 gd->reloc_off = gd->relocaddr - (unsigned long)__image_copy_start; 351 } 352 #else 353 static void spl_setup_relocate(void) 354 { 355 356 } 357 #endif 358 359 void spl_set_bd(void) 360 { 361 if (!gd->bd) 362 gd->bd = &bdata; 363 } 364 365 int spl_early_init(void) 366 { 367 int ret; 368 369 ret = spl_common_init(true); 370 if (ret) 371 return ret; 372 gd->flags |= GD_FLG_SPL_EARLY_INIT; 373 374 spl_setup_relocate(); 375 376 return 0; 377 } 378 379 int spl_init(void) 380 { 381 int ret; 382 bool setup_malloc = !(IS_ENABLED(CONFIG_SPL_STACK_R) && 383 IS_ENABLED(CONFIG_SPL_SYS_MALLOC_SIMPLE)); 384 385 if (!(gd->flags & GD_FLG_SPL_EARLY_INIT)) { 386 ret = spl_common_init(setup_malloc); 387 if (ret) 388 return ret; 389 } 390 gd->flags |= GD_FLG_SPL_INIT; 391 392 return 0; 393 } 394 395 #ifndef BOOT_DEVICE_NONE 396 #define BOOT_DEVICE_NONE 0xdeadbeef 397 #endif 398 399 __weak void board_boot_order(u32 *spl_boot_list) 400 { 401 spl_boot_list[0] = spl_boot_device(); 402 } 403 404 static struct spl_image_loader *spl_ll_find_loader(uint boot_device) 405 { 406 struct spl_image_loader *drv = 407 ll_entry_start(struct spl_image_loader, spl_image_loader); 408 const int n_ents = 409 ll_entry_count(struct spl_image_loader, spl_image_loader); 410 struct spl_image_loader *entry; 411 412 for (entry = drv; entry != drv + n_ents; entry++) { 413 if (boot_device == entry->boot_device) 414 return entry; 415 } 416 417 /* Not found */ 418 return NULL; 419 } 420 421 static int spl_load_image(struct spl_image_info *spl_image, 422 struct spl_image_loader *loader) 423 { 424 struct spl_boot_device bootdev; 425 426 bootdev.boot_device = loader->boot_device; 427 bootdev.boot_device_name = NULL; 428 429 return loader->load_image(spl_image, &bootdev); 430 } 431 432 /** 433 * boot_from_devices() - Try loading an booting U-Boot from a list of devices 434 * 435 * @spl_image: Place to put the image details if successful 436 * @spl_boot_list: List of boot devices to try 437 * @count: Number of elements in spl_boot_list 438 * @return 0 if OK, -ve on error 439 */ 440 static int boot_from_devices(struct spl_image_info *spl_image, 441 u32 spl_boot_list[], int count) 442 { 443 int i; 444 445 for (i = 0; i < count && spl_boot_list[i] != BOOT_DEVICE_NONE; i++) { 446 struct spl_image_loader *loader; 447 448 loader = spl_ll_find_loader(spl_boot_list[i]); 449 #if defined(CONFIG_SPL_SERIAL_SUPPORT) && defined(CONFIG_SPL_LIBCOMMON_SUPPORT) 450 if (loader) 451 printf("Trying to boot from %s\n", loader->name); 452 else 453 puts("SPL: Unsupported Boot Device!\n"); 454 #endif 455 if (loader && !spl_load_image(spl_image, loader)) { 456 spl_image->boot_device = spl_boot_list[i]; 457 return 0; 458 } 459 460 spl_board_storages_fixup(loader); 461 } 462 463 return -ENODEV; 464 } 465 466 #if defined(CONFIG_DM) && !defined(CONFIG_SPL_SKIP_RELOCATE) && !defined(CONFIG_TPL_BUILD) 467 static int spl_initr_dm(void) 468 { 469 int ret; 470 471 /* Save the pre-reloc driver model and start a new one */ 472 gd->dm_root_f = gd->dm_root; 473 gd->dm_root = NULL; 474 bootstage_start(BOOTSTATE_ID_ACCUM_DM_R, "dm_r"); 475 ret = dm_init_and_scan(false); 476 bootstage_accum(BOOTSTATE_ID_ACCUM_DM_R); 477 if (ret) 478 return ret; 479 480 #if defined(CONFIG_TIMER) 481 gd->timer = NULL; 482 #endif 483 serial_init(); 484 485 return 0; 486 } 487 #else 488 static int spl_initr_dm(void) 489 { 490 return 0; 491 } 492 #endif 493 494 #if defined(CONFIG_SPL_KERNEL_BOOT) && !defined(CONFIG_ARM64) 495 static void boot_jump_linux(struct spl_image_info *spl_image) 496 { 497 void (*kernel_entry)(int zero, int arch, ulong params); 498 499 printf("Jumping to %s(0x%08lx)\n", "Kernel", 500 (ulong)spl_image->entry_point_os); 501 spl_cleanup_before_jump(spl_image); 502 kernel_entry = (void (*)(int, int, ulong))spl_image->entry_point_os; 503 kernel_entry(0, 0, (ulong)spl_image->fdt_addr); 504 } 505 #endif 506 507 void board_init_r(gd_t *dummy1, ulong dummy2) 508 { 509 u32 spl_boot_list[] = { 510 BOOT_DEVICE_NONE, 511 BOOT_DEVICE_NONE, 512 BOOT_DEVICE_NONE, 513 BOOT_DEVICE_NONE, 514 BOOT_DEVICE_NONE, 515 }; 516 struct spl_image_info spl_image; 517 518 debug(">>spl:board_init_r()\n"); 519 520 spl_initr_dm(); 521 522 spl_set_bd(); 523 524 #ifdef CONFIG_SPL_OS_BOOT 525 dram_init_banksize(); 526 #endif 527 528 #if defined(CONFIG_SYS_SPL_MALLOC_START) 529 mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, 530 CONFIG_SYS_SPL_MALLOC_SIZE); 531 gd->flags |= GD_FLG_FULL_MALLOC_INIT; 532 #endif 533 if (!(gd->flags & GD_FLG_SPL_INIT)) { 534 if (spl_init()) 535 hang(); 536 } 537 #if !defined(CONFIG_PPC) && !defined(CONFIG_ARCH_MX6) 538 /* 539 * timer_init() does not exist on PPC systems. The timer is initialized 540 * and enabled (decrementer) in interrupt_init() here. 541 */ 542 timer_init(); 543 #endif 544 545 #if CONFIG_IS_ENABLED(BOARD_INIT) 546 spl_board_init(); 547 #endif 548 549 memset(&spl_image, '\0', sizeof(spl_image)); 550 551 #ifdef CONFIG_MP_BOOT 552 mpb_init_x(0); 553 #endif 554 555 #if CONFIG_IS_ENABLED(ATF) 556 /* 557 * Bl32 ep is optional, initial it as an invalid value. 558 * BL33 ep is mandatory, but initial it as a default value is better. 559 */ 560 spl_image.entry_point_bl32 = -1; 561 spl_image.entry_point_bl33 = CONFIG_SYS_TEXT_BASE; 562 #endif 563 564 #if CONFIG_IS_ENABLED(OPTEE) 565 /* default address */ 566 spl_image.entry_point_os = CONFIG_SYS_TEXT_BASE; 567 #endif 568 569 #ifdef CONFIG_SYS_SPL_ARGS_ADDR 570 spl_image.arg = (void *)CONFIG_SYS_SPL_ARGS_ADDR; 571 #endif 572 spl_image.boot_device = BOOT_DEVICE_NONE; 573 board_boot_order(spl_boot_list); 574 spl_next_stage(&spl_image); 575 if (boot_from_devices(&spl_image, spl_boot_list, 576 ARRAY_SIZE(spl_boot_list))) { 577 puts("SPL: failed to boot from all boot devices\n"); 578 hang(); 579 } 580 581 spl_perform_fixups(&spl_image); 582 583 #ifdef CONFIG_MP_BOOT 584 mpb_init_x(2); 585 #endif 586 587 #ifdef CONFIG_CPU_V7M 588 spl_image.entry_point |= 0x1; 589 #endif 590 switch (spl_image.os) { 591 case IH_OS_U_BOOT: 592 debug("Jumping to U-Boot\n"); 593 spl_cleanup_before_jump(&spl_image); 594 break; 595 #if CONFIG_IS_ENABLED(ATF) 596 case IH_OS_ARM_TRUSTED_FIRMWARE: 597 printf("Jumping to %s(0x%08lx) via ARM Trusted Firmware(0x%08lx)\n", 598 spl_image.next_stage == SPL_NEXT_STAGE_UBOOT ? "U-Boot" : 599 (spl_image.next_stage == SPL_NEXT_STAGE_KERNEL ? "Kernel" : "Unknown"), 600 (ulong)spl_image.entry_point_bl33, 601 (ulong)spl_image.entry_point); 602 spl_invoke_atf(&spl_image); 603 break; 604 #endif 605 #if CONFIG_IS_ENABLED(OPTEE) 606 case IH_OS_OP_TEE: 607 printf("Jumping to %s(0x%08lx) via OP-TEE(0x%08lx)\n", 608 spl_image.next_stage == SPL_NEXT_STAGE_UBOOT ? "U-Boot" : 609 (spl_image.next_stage == SPL_NEXT_STAGE_KERNEL ? "Kernel" : "Unknown"), 610 (ulong)spl_image.entry_point_os, 611 (ulong)spl_image.entry_point); 612 spl_cleanup_before_jump(&spl_image); 613 spl_optee_entry(NULL, (void *)spl_image.entry_point_os, 614 (void *)spl_image.fdt_addr, 615 (void *)spl_image.entry_point); 616 break; 617 #endif 618 case IH_OS_LINUX: 619 #ifdef CONFIG_SPL_OS_BOOT 620 debug("Jumping to Linux\n"); 621 spl_fixup_fdt(); 622 spl_board_prepare_for_linux(); 623 jump_to_image_linux(&spl_image); 624 #elif defined(CONFIG_SPL_KERNEL_BOOT) && !defined(CONFIG_ARM64) 625 boot_jump_linux(&spl_image); 626 #endif 627 break; 628 default: 629 debug("Unsupported OS image.. Jumping nevertheless..\n"); 630 } 631 #if CONFIG_VAL(SYS_MALLOC_F_LEN) && !defined(CONFIG_SYS_SPL_MALLOC_SIZE) 632 debug("SPL malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr, 633 gd->malloc_ptr / 1024); 634 #endif 635 636 debug("loaded - jumping to U-Boot...\n"); 637 #ifdef CONFIG_BOOTSTAGE_STASH 638 int ret; 639 640 bootstage_mark_name(BOOTSTAGE_ID_END_SPL, "end_spl"); 641 ret = bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR, 642 CONFIG_BOOTSTAGE_STASH_SIZE); 643 if (ret) 644 debug("Failed to stash bootstage: err=%d\n", ret); 645 #endif 646 647 printf("Jumping to U-Boot(0x%08lx)\n", spl_image.entry_point); 648 spl_board_prepare_for_boot(); 649 jump_to_image_no_args(&spl_image); 650 } 651 652 /* 653 * This requires UART clocks to be enabled. In order for this to work the 654 * caller must ensure that the gd pointer is valid. 655 */ 656 void preloader_console_init(void) 657 { 658 gd->baudrate = CONFIG_BAUDRATE; 659 660 serial_init(); /* serial communications setup */ 661 662 gd->have_console = 1; 663 664 #ifdef BUILD_SPL_TAG 665 puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \ 666 U_BOOT_TIME "), fwver: "BUILD_SPL_TAG"\n"); 667 #else 668 puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \ 669 U_BOOT_TIME ")\n"); 670 #endif 671 #ifdef CONFIG_SPL_DISPLAY_PRINT 672 spl_display_print(); 673 #endif 674 } 675 676 /** 677 * spl_relocate_stack_gd() - Relocate stack ready for board_init_r() execution 678 * 679 * Sometimes board_init_f() runs with a stack in SRAM but we want to use SDRAM 680 * for the main board_init_r() execution. This is typically because we need 681 * more stack space for things like the MMC sub-system. 682 * 683 * This function calculates the stack position, copies the global_data into 684 * place, sets the new gd (except for ARM, for which setting GD within a C 685 * function may not always work) and returns the new stack position. The 686 * caller is responsible for setting up the sp register and, in the case 687 * of ARM, setting up gd. 688 * 689 * All of this is done using the same layout and alignments as done in 690 * board_init_f_init_reserve() / board_init_f_alloc_reserve(). 691 * 692 * @return new stack location, or 0 to use the same stack 693 */ 694 ulong spl_relocate_stack_gd(void) 695 { 696 #ifdef CONFIG_SPL_STACK_R 697 gd_t *new_gd; 698 ulong ptr = CONFIG_SPL_STACK_R_ADDR; 699 700 #if defined(CONFIG_SPL_SYS_MALLOC_SIMPLE) && CONFIG_VAL(SYS_MALLOC_F_LEN) 701 if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) { 702 ptr -= CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN; 703 gd->malloc_base = ptr; 704 gd->malloc_limit = CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN; 705 gd->malloc_ptr = 0; 706 } 707 #endif 708 /* Get stack position: use 8-byte alignment for ABI compliance */ 709 ptr = CONFIG_SPL_STACK_R_ADDR - roundup(sizeof(gd_t),16); 710 new_gd = (gd_t *)ptr; 711 memcpy(new_gd, (void *)gd, sizeof(gd_t)); 712 #if CONFIG_IS_ENABLED(DM) 713 dm_fixup_for_gd_move(new_gd); 714 #endif 715 #if !defined(CONFIG_ARM) 716 gd = new_gd; 717 #endif 718 return ptr; 719 #else 720 return 0; 721 #endif 722 } 723 724 /* cleanup before jump to next stage */ 725 void spl_cleanup_before_jump(struct spl_image_info *spl_image) 726 { 727 ulong us, tt_us; 728 729 spl_board_prepare_for_jump(spl_image); 730 731 disable_interrupts(); 732 733 #ifdef CONFIG_ARM64 734 disable_serror(); 735 #else 736 disable_async_abort(); 737 #endif 738 /* 739 * Turn off I-cache and invalidate it 740 */ 741 icache_disable(); 742 invalidate_icache_all(); 743 744 /* 745 * Turn off D-cache 746 * dcache_disable() in turn flushes the d-cache and disables MMU 747 */ 748 dcache_disable(); 749 invalidate_dcache_all(); 750 751 dsb(); 752 isb(); 753 754 us = (get_ticks() - gd->sys_start_tick) / 24UL; 755 tt_us = get_ticks() / (COUNTER_FREQUENCY / 1000000); 756 printf("Total: %ld.%ld/%ld.%ld ms\n\n", us / 1000, us % 1000, tt_us / 1000, tt_us % 1000); 757 } 758