crt0.S 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. #include <linux/linkage.h>
  27. /*
  28. * This file handles the target-independent stages of the U-Boot
  29. * start-up where a C runtime environment is needed. Its entry point
  30. * is _main and is branched into from the target's start.S file.
  31. *
  32. * _main execution sequence is:
  33. *
  34. * 1. Set up initial environment for calling board_init_f().
  35. * This environment only provides a stack and a place to store
  36. * the GD ('global data') structure, both located in some readily
  37. * available RAM (SRAM, locked cache...). In this context, VARIABLE
  38. * global data, initialized or not (BSS), are UNAVAILABLE; only
  39. * CONSTANT initialized data are available.
  40. *
  41. * 2. Call board_init_f(). This function prepares the hardware for
  42. * execution from system RAM (DRAM, DDR...) As system RAM may not
  43. * be available yet, , board_init_f() must use the current GD to
  44. * store any data which must be passed on to later stages. These
  45. * data include the relocation destination, the future stack, and
  46. * the future GD location.
  47. *
  48. * (the following applies only to non-SPL builds)
  49. *
  50. * 3. Set up intermediate environment where the stack and GD are the
  51. * ones allocated by board_init_f() in system RAM, but BSS and
  52. * initialized non-const data are still not available.
  53. *
  54. * 4. Call relocate_code(). This function relocates U-Boot from its
  55. * current location into the relocation destination computed by
  56. * board_init_f().
  57. *
  58. * 5. Set up final environment for calling board_init_r(). This
  59. * environment has BSS (initialized to 0), initialized non-const
  60. * data (initialized to their intended value), and stack in system
  61. * RAM. GD has retained values set by board_init_f(). Some CPUs
  62. * have some work left to do at this point regarding memory, so
  63. * call c_runtime_cpu_setup.
  64. *
  65. * 6. Branch to board_init_r().
  66. */
  67. /*
  68. * entry point of crt0 sequence
  69. */
  70. ENTRY(_main)
  71. /*
  72. * Set up initial C runtime environment and call board_init_f(0).
  73. */
  74. #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
  75. ldr sp, =(CONFIG_SPL_STACK)
  76. #else
  77. ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
  78. #endif
  79. bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
  80. sub sp, #GD_SIZE /* allocate one GD above SP */
  81. bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
  82. mov r8, sp /* GD is above SP */
  83. mov r0, #0
  84. bl board_init_f
  85. #if ! defined(CONFIG_SPL_BUILD)
  86. /*
  87. * Set up intermediate environment (new sp and gd) and call
  88. * relocate_code(addr_moni). Trick here is that we'll return
  89. * 'here' but relocated.
  90. */
  91. ldr sp, [r8, #GD_START_ADDR_SP] /* r8 = gd->start_addr_sp */
  92. bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
  93. ldr r8, [r8, #GD_BD] /* r8 = gd->bd */
  94. sub r8, r8, #GD_SIZE /* new GD is below bd */
  95. adr lr, here
  96. ldr r0, [r8, #GD_RELOC_OFF] /* lr = gd->start_addr_sp */
  97. add lr, lr, r0
  98. ldr r0, [r8, #GD_RELOCADDR] /* r0 = gd->relocaddr */
  99. b relocate_code
  100. here:
  101. /* Set up final (full) environment */
  102. bl c_runtime_cpu_setup /* we still call old routine here */
  103. ldr r0, =__bss_start /* this is auto-relocated! */
  104. ldr r1, =__bss_end /* this is auto-relocated! */
  105. mov r2, #0x00000000 /* prepare zero to clear BSS */
  106. clbss_l:cmp r0, r1 /* while not at end of BSS */
  107. strlo r2, [r0] /* clear 32-bit BSS word */
  108. addlo r0, r0, #4 /* move to next */
  109. blo clbss_l
  110. bl coloured_LED_init
  111. bl red_led_on
  112. /* call board_init_r(gd_t *id, ulong dest_addr) */
  113. mov r0, r8 /* gd_t */
  114. ldr r1, [r8, #GD_RELOCADDR] /* dest_addr */
  115. /* call board_init_r */
  116. ldr pc, =board_init_r /* this is auto-relocated! */
  117. /* we should not return here. */
  118. #endif
  119. ENDPROC(_main)