lowlevel_init.S 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * (C) Copyright 2011-2012
  3. * Pali Rohár <pali.rohar@gmail.com>
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <config.h>
  24. relocaddr: /* address of this relocaddr section after coping */
  25. .word . /* address of section (calculated at compile time) */
  26. startaddr: /* address of u-boot after copying */
  27. .word CONFIG_SYS_TEXT_BASE
  28. kernaddr: /* address of kernel after copying */
  29. .word KERNEL_ADDRESS
  30. kernsize: /* maximal size of kernel image */
  31. .word KERNEL_MAXSIZE
  32. kernoffs: /* offset of kernel image in loaded u-boot */
  33. .word KERNEL_OFFSET
  34. imagesize: /* maximal size of image */
  35. .word IMAGE_MAXSIZE
  36. ih_magic: /* IH_MAGIC in big endian from include/image.h */
  37. .word 0x56190527
  38. /*
  39. * Routine: save_boot_params (called after reset from start.S)
  40. * Description: Copy attached kernel to address KERNEL_ADDRESS
  41. * Copy u-boot to address CONFIG_SYS_TEXT_BASE
  42. * Return to copied u-boot address
  43. */
  44. .global save_boot_params
  45. save_boot_params:
  46. /* Copy valid attached kernel to address KERNEL_ADDRESS */
  47. copy_kernel_start:
  48. adr r0, relocaddr /* r0 - address of section relocaddr */
  49. ldr r1, relocaddr /* r1 - address of relocaddr after relocation */
  50. cmp r0, r1
  51. /* r4 - calculated offset */
  52. subhi r4, r0, r1
  53. sublo r4, r1, r0
  54. /* r0 - start of kernel before */
  55. ldr r0, startaddr
  56. addhi r0, r0, r4
  57. sublo r0, r0, r4
  58. ldr r1, kernoffs
  59. add r0, r0, r1
  60. /* r3 - start of kernel after */
  61. ldr r3, kernaddr
  62. /* r2 - end of kernel after */
  63. ldr r1, kernsize
  64. add r2, r3, r1
  65. /* r1 - end of kernel before */
  66. add r1, r0, r1
  67. /* remove header in target kernel */
  68. mov r5, #0
  69. str r5, [r3]
  70. /* check for valid kernel uImage */
  71. ldr r4, [r0] /* r4 - 4 bytes header of kernel */
  72. ldr r5, ih_magic /* r5 - IH_MAGIC */
  73. cmp r4, r5
  74. bne copy_kernel_end /* skip if invalid image */
  75. copy_kernel_loop:
  76. ldmdb r1!, {r3 - r10}
  77. stmdb r2!, {r3 - r10}
  78. cmp r1, r0
  79. bhi copy_kernel_loop
  80. copy_kernel_end:
  81. mov r5, #0
  82. str r5, [r0] /* remove 4 bytes header of kernel */
  83. /* Fix u-boot code */
  84. fix_start:
  85. adr r0, relocaddr /* r0 - address of section relocaddr */
  86. ldr r1, relocaddr /* r1 - address of relocaddr after relocation */
  87. cmp r0, r1
  88. beq copy_uboot_end /* skip if u-boot is on correct address */
  89. /* r5 - calculated offset */
  90. subhi r5, r0, r1
  91. sublo r5, r1, r0
  92. /* r6 - maximal u-boot size */
  93. ldr r6, imagesize
  94. /* fix return address */
  95. subhi lr, lr, r5
  96. addlo lr, lr, r5
  97. /* r1 - start of u-boot after */
  98. ldr r1, startaddr
  99. /* r0 - start of u-boot before */
  100. addhi r0, r1, r5
  101. sublo r0, r1, r5
  102. /* check if we need to move uboot copy code before calling it */
  103. cmp r5, r6
  104. bhi copy_uboot_start /* now coping u-boot code directly is safe */
  105. copy_code_start:
  106. /* r0 - start of u-boot before */
  107. /* r1 - start of u-boot after */
  108. /* r6 - maximal u-boot size */
  109. /* r7 - maximal kernel size */
  110. ldr r7, kernsize
  111. /* r4 - end of kernel before */
  112. add r4, r0, r6
  113. add r4, r4, r7
  114. /* r5 - end of u-boot after */
  115. ldr r5, startaddr
  116. add r5, r5, r6
  117. /* r2 - start of loop code after */
  118. cmp r4, r5 /* higher address (r4 or r5) */
  119. movhs r2, r4
  120. movlo r2, r5
  121. /* r3 - end of loop code before */
  122. adr r3, end
  123. /* r4 - end of loop code after */
  124. adr r4, copy_uboot_start
  125. sub r4, r3, r4
  126. add r4, r2, r4
  127. copy_code_loop:
  128. ldmdb r3!, {r7 - r10}
  129. stmdb r4!, {r7 - r10}
  130. cmp r4, r2
  131. bhi copy_code_loop
  132. copy_code_end:
  133. mov pc, r2
  134. /* Copy u-boot to address CONFIG_SYS_TEXT_BASE */
  135. copy_uboot_start:
  136. /* r0 - start of u-boot before */
  137. /* r1 - start of u-boot after */
  138. /* r6 - maximal u-boot size */
  139. /* r2 - end of u-boot after */
  140. add r2, r1, r6
  141. /* condition for copying from left to right */
  142. cmp r0, r1
  143. addlo r1, r0, r6 /* r1 - end of u-boot before */
  144. blo copy_uboot_loop_right
  145. copy_uboot_loop_left:
  146. ldmia r0!, {r3 - r10}
  147. stmia r1!, {r3 - r10}
  148. cmp r1, r2
  149. blo copy_uboot_loop_left
  150. b copy_uboot_end
  151. copy_uboot_loop_right:
  152. ldmdb r1!, {r3 - r10}
  153. stmdb r2!, {r3 - r10}
  154. cmp r1, r0
  155. bhi copy_uboot_loop_right
  156. copy_uboot_end:
  157. bx lr
  158. end: