crt0_64.S 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * crt0 - C-runtime startup Code for AArch64 U-Boot
  3. *
  4. * (C) Copyright 2013
  5. * David Feng <fenghua@phytium.com.cn>
  6. *
  7. * (C) Copyright 2012
  8. * Albert ARIBAUD <albert.u.boot@aribaud.net>
  9. *
  10. * SPDX-License-Identifier: GPL-2.0+
  11. */
  12. #include <config.h>
  13. #include <asm-offsets.h>
  14. #include <asm/macro.h>
  15. #include <linux/linkage.h>
  16. /*
  17. * This file handles the target-independent stages of the U-Boot
  18. * start-up where a C runtime environment is needed. Its entry point
  19. * is _main and is branched into from the target's start.S file.
  20. *
  21. * _main execution sequence is:
  22. *
  23. * 1. Set up initial environment for calling board_init_f().
  24. * This environment only provides a stack and a place to store
  25. * the GD ('global data') structure, both located in some readily
  26. * available RAM (SRAM, locked cache...). In this context, VARIABLE
  27. * global data, initialized or not (BSS), are UNAVAILABLE; only
  28. * CONSTANT initialized data are available. GD should be zeroed
  29. * before board_init_f() is called.
  30. *
  31. * 2. Call board_init_f(). This function prepares the hardware for
  32. * execution from system RAM (DRAM, DDR...) As system RAM may not
  33. * be available yet, , board_init_f() must use the current GD to
  34. * store any data which must be passed on to later stages. These
  35. * data include the relocation destination, the future stack, and
  36. * the future GD location.
  37. *
  38. * 3. Set up intermediate environment where the stack and GD are the
  39. * ones allocated by board_init_f() in system RAM, but BSS and
  40. * initialized non-const data are still not available.
  41. *
  42. * 4a.For U-Boot proper (not SPL), call relocate_code(). This function
  43. * relocates U-Boot from its current location into the relocation
  44. * destination computed by board_init_f().
  45. *
  46. * 4b.For SPL, board_init_f() just returns (to crt0). There is no
  47. * code relocation in SPL.
  48. *
  49. * 5. Set up final environment for calling board_init_r(). This
  50. * environment has BSS (initialized to 0), initialized non-const
  51. * data (initialized to their intended value), and stack in system
  52. * RAM (for SPL moving the stack and GD into RAM is optional - see
  53. * CONFIG_SPL_STACK_R). GD has retained values set by board_init_f().
  54. *
  55. * TODO: For SPL, implement stack relocation on AArch64.
  56. *
  57. * 6. For U-Boot proper (not SPL), some CPUs have some work left to do
  58. * at this point regarding memory, so call c_runtime_cpu_setup.
  59. *
  60. * 7. Branch to board_init_r().
  61. *
  62. * For more information see 'Board Initialisation Flow in README.
  63. */
  64. ENTRY(_main)
  65. /*
  66. * Set up initial C runtime environment and call board_init_f(0).
  67. */
  68. #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
  69. ldr x0, =(CONFIG_SPL_STACK)
  70. #else
  71. ldr x0, =(CONFIG_SYS_INIT_SP_ADDR)
  72. #endif
  73. bic sp, x0, #0xf /* 16-byte alignment for ABI compliance */
  74. mov x0, sp
  75. bl board_init_f_alloc_reserve
  76. mov sp, x0
  77. /* set up gd here, outside any C code */
  78. mov x18, x0
  79. bl board_init_f_init_reserve
  80. mov x0, #0
  81. bl board_init_f
  82. #if !defined(CONFIG_SPL_BUILD)
  83. /*
  84. * Set up intermediate environment (new sp and gd) and call
  85. * relocate_code(addr_moni). Trick here is that we'll return
  86. * 'here' but relocated.
  87. */
  88. ldr x0, [x18, #GD_START_ADDR_SP] /* x0 <- gd->start_addr_sp */
  89. bic sp, x0, #0xf /* 16-byte alignment for ABI compliance */
  90. ldr x18, [x18, #GD_BD] /* x18 <- gd->bd */
  91. sub x18, x18, #GD_SIZE /* new GD is below bd */
  92. adr lr, relocation_return
  93. ldr x9, [x18, #GD_RELOC_OFF] /* x9 <- gd->reloc_off */
  94. add lr, lr, x9 /* new return address after relocation */
  95. ldr x0, [x18, #GD_RELOCADDR] /* x0 <- gd->relocaddr */
  96. b relocate_code
  97. relocation_return:
  98. /*
  99. * Set up final (full) environment
  100. */
  101. bl c_runtime_cpu_setup /* still call old routine */
  102. #endif /* !CONFIG_SPL_BUILD */
  103. /* TODO: For SPL, call spl_relocate_stack_gd() to alloc stack relocation */
  104. /*
  105. * Clear BSS section
  106. */
  107. ldr x0, =__bss_start /* this is auto-relocated! */
  108. ldr x1, =__bss_end /* this is auto-relocated! */
  109. clear_loop:
  110. str xzr, [x0], #8
  111. cmp x0, x1
  112. b.lo clear_loop
  113. /* call board_init_r(gd_t *id, ulong dest_addr) */
  114. mov x0, x18 /* gd_t */
  115. ldr x1, [x18, #GD_RELOCADDR] /* dest_addr */
  116. b board_init_r /* PC relative jump */
  117. /* NOTREACHED - board_init_r() does not return */
  118. ENDPROC(_main)