crt0.S 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * crt0 - C-runtime startup Code for ARM U-Boot
  3. *
  4. * Copyright (c) 2012 Albert ARIBAUD <albert.u.boot@aribaud.net>
  5. *
  6. * See file CREDITS for list of people who contributed to this
  7. * project.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation; either version 2 of
  12. * the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22. * MA 02111-1307 USA
  23. */
  24. #include <config.h>
  25. #include <asm-offsets.h>
  26. /*
  27. * This file handles the target-independent stages of the U-Boot
  28. * start-up where a C runtime environment is needed. Its entry point
  29. * is _main and is branched into from the target's start.S file.
  30. *
  31. * _main execution sequence is:
  32. *
  33. * 1. Set up initial environment for calling board_init_f().
  34. * This environment only provides a stack and a place to store
  35. * the GD ('global data') structure, both located in some readily
  36. * available RAM (SRAM, locked cache...). In this context, VARIABLE
  37. * global data, initialized or not (BSS), are UNAVAILABLE; only
  38. * CONSTANT initialized data are available.
  39. *
  40. * 2. Call board_init_f(). This function prepares the hardware for
  41. * execution from system RAM (DRAM, DDR...) As system RAM may not
  42. * be available yet, , board_init_f() must use the current GD to
  43. * store any data which must be passed on to later stages. These
  44. * data include the relocation destination, the future stack, and
  45. * the future GD location.
  46. *
  47. * (the following applies only to non-SPL builds)
  48. *
  49. * 3. Set up intermediate environment where the stack and GD are the
  50. * ones allocated by board_init_f() in system RAM, but BSS and
  51. * initialized non-const data are still not available.
  52. *
  53. * 4. Call relocate_code(). This function relocates U-Boot from its
  54. * current location into the relocation destination computed by
  55. * board_init_f().
  56. *
  57. * 5. Set up final environment for calling board_init_r(). This
  58. * environment has BSS (initialized to 0), initialized non-const
  59. * data (initialized to their intended value), and stack in system
  60. * RAM. GD has retained values set by board_init_f(). Some CPUs
  61. * have some work left to do at this point regarding memory, so
  62. * call c_runtime_cpu_setup.
  63. *
  64. * 6. Branch to either nand_boot() or board_init_r().
  65. */
  66. /*
  67. * declare nand_boot() or board_init_r() to jump to at end of crt0
  68. */
  69. #if defined(CONFIG_NAND_SPL)
  70. .globl nand_boot
  71. #elif ! defined(CONFIG_SPL_BUILD)
  72. .globl board_init_r
  73. #endif
  74. /*
  75. * start and end of BSS
  76. */
  77. .globl __bss_start
  78. .globl __bss_end__
  79. /*
  80. * entry point of crt0 sequence
  81. */
  82. .global _main
  83. _main:
  84. /*
  85. * Set up initial C runtime environment and call board_init_f(0).
  86. */
  87. #if defined(CONFIG_NAND_SPL)
  88. /* deprecated, use instead CONFIG_SPL_BUILD */
  89. ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
  90. #elif defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
  91. ldr sp, =(CONFIG_SPL_STACK)
  92. #else
  93. ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
  94. #endif
  95. bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
  96. sub sp, #GD_SIZE /* allocate one GD above SP */
  97. bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
  98. mov r8, sp /* GD is above SP */
  99. mov r0, #0
  100. bl board_init_f
  101. #if ! defined(CONFIG_SPL_BUILD)
  102. /*
  103. * Set up intermediate environment (new sp and gd) and call
  104. * relocate_code(addr_sp, gd, addr_moni). Trick here is that
  105. * we'll return 'here' but relocated.
  106. */
  107. ldr sp, [r8, #GD_START_ADDR_SP] /* r8 = gd->start_addr_sp */
  108. bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
  109. ldr r8, [r8, #GD_BD] /* r8 = gd->bd */
  110. sub r8, r8, #GD_SIZE /* new GD is below bd */
  111. adr lr, here
  112. ldr r0, [r8, #GD_RELOC_OFF] /* lr = gd->start_addr_sp */
  113. add lr, lr, r0
  114. ldr r0, [r8, #GD_START_ADDR_SP] /* r0 = gd->start_addr_sp */
  115. mov r1, r8 /* r1 = gd */
  116. ldr r2, [r8, #GD_RELOCADDR] /* r2 = gd->relocaddr */
  117. b relocate_code
  118. here:
  119. /* Set up final (full) environment */
  120. bl c_runtime_cpu_setup /* we still call old routine here */
  121. ldr r0, =__bss_start /* this is auto-relocated! */
  122. ldr r1, =__bss_end__ /* this is auto-relocated! */
  123. mov r2, #0x00000000 /* prepare zero to clear BSS */
  124. clbss_l:cmp r0, r1 /* while not at end of BSS */
  125. strlo r2, [r0] /* clear 32-bit BSS word */
  126. addlo r0, r0, #4 /* move to next */
  127. blo clbss_l
  128. bl coloured_LED_init
  129. bl red_led_on
  130. #if defined(CONFIG_NAND_SPL)
  131. /* call _nand_boot() */
  132. ldr pc, =nand_boot
  133. #else
  134. /* call board_init_r(gd_t *id, ulong dest_addr) */
  135. mov r0, r8 /* gd_t */
  136. ldr r1, [r8, #GD_RELOCADDR] /* dest_addr */
  137. /* call board_init_r */
  138. ldr pc, =board_init_r /* this is auto-relocated! */
  139. #endif
  140. /* we should not return here. */
  141. #endif