lowlevel_init.S 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /* SPDX-License-Identifier: GPL-2.0+ */
  2. /*
  3. * (C) Copyright 2011-2012
  4. * Pali Rohár <pali@kernel.org>
  5. */
  6. #include <config.h>
  7. relocaddr: /* address of this relocaddr section after coping */
  8. .word . /* address of section (calculated at compile time) */
  9. startaddr: /* address of u-boot after copying */
  10. .word CONFIG_SYS_TEXT_BASE
  11. kernaddr: /* address of kernel after copying */
  12. .word KERNEL_ADDRESS
  13. kernsize: /* maximal size of kernel image */
  14. .word KERNEL_MAXSIZE
  15. kernoffs: /* offset of kernel image in loaded u-boot */
  16. .word KERNEL_OFFSET
  17. imagesize: /* maximal size of image */
  18. .word IMAGE_MAXSIZE
  19. ih_magic: /* IH_MAGIC in big endian from include/image.h */
  20. .word 0x56190527
  21. z_magic: /* LINUX_ARM_ZIMAGE_MAGIC */
  22. .word 0x016f2818
  23. /*
  24. * Routine: save_boot_params (called after reset from start.S)
  25. * Description: Copy attached kernel to address KERNEL_ADDRESS
  26. * Copy u-boot to address CONFIG_SYS_TEXT_BASE
  27. * Return to copied u-boot address
  28. */
  29. .global save_boot_params
  30. save_boot_params:
  31. /* Get return address */
  32. ldr lr, =save_boot_params_ret
  33. /* Copy valid attached kernel to address KERNEL_ADDRESS */
  34. copy_kernel_start:
  35. adr r0, relocaddr /* r0 - address of section relocaddr */
  36. ldr r1, relocaddr /* r1 - address of relocaddr after relocation */
  37. cmp r0, r1
  38. /* r4 - calculated offset */
  39. subhi r4, r0, r1
  40. sublo r4, r1, r0
  41. /* r0 - start of kernel before */
  42. ldr r0, startaddr
  43. addhi r0, r0, r4
  44. sublo r0, r0, r4
  45. ldr r1, kernoffs
  46. add r0, r0, r1
  47. /* r3 - start of kernel after */
  48. ldr r3, kernaddr
  49. /* r2 - end of kernel after */
  50. ldr r1, kernsize
  51. add r2, r3, r1
  52. /* r1 - end of kernel before */
  53. add r1, r0, r1
  54. /* remove header in target kernel */
  55. mov r5, #0
  56. str r5, [r3]
  57. /* check for valid kernel uImage */
  58. ldr r4, [r0] /* r4 - 4 bytes header of kernel */
  59. ldr r5, ih_magic /* r5 - IH_MAGIC */
  60. cmp r4, r5
  61. beq copy_kernel_loop
  62. /* check for valid kernel zImage */
  63. ldr r4, [r0, #36] /* r4 - 4 bytes header of kernel at offset 36 */
  64. ldr r5, z_magic /* r5 - LINUX_ARM_ZIMAGE_MAGIC */
  65. cmp r4, r5
  66. bne copy_kernel_end /* skip if invalid image */
  67. copy_kernel_loop:
  68. ldmdb r1!, {r3 - r10}
  69. stmdb r2!, {r3 - r10}
  70. cmp r1, r0
  71. bhi copy_kernel_loop
  72. copy_kernel_end:
  73. mov r5, #0
  74. str r5, [r0] /* remove 4 bytes header of kernel uImage */
  75. str r5, [r0, #36] /* remove 4 bytes header of kernel zImage */
  76. /* Fix u-boot code */
  77. fix_start:
  78. adr r0, relocaddr /* r0 - address of section relocaddr */
  79. ldr r1, relocaddr /* r1 - address of relocaddr after relocation */
  80. cmp r0, r1
  81. beq copy_uboot_end /* skip if u-boot is on correct address */
  82. /* r5 - calculated offset */
  83. subhi r5, r0, r1
  84. sublo r5, r1, r0
  85. /* r6 - maximal u-boot size */
  86. ldr r6, imagesize
  87. /* r1 - start of u-boot after */
  88. ldr r1, startaddr
  89. /* r0 - start of u-boot before */
  90. addhi r0, r1, r5
  91. sublo r0, r1, r5
  92. /* check if we need to move uboot copy code before calling it */
  93. cmp r5, r6
  94. bhi copy_uboot_start /* now coping u-boot code directly is safe */
  95. copy_code_start:
  96. /* r0 - start of u-boot before */
  97. /* r1 - start of u-boot after */
  98. /* r6 - maximal u-boot size */
  99. /* r7 - maximal kernel size */
  100. ldr r7, kernsize
  101. /* r4 - end of kernel before */
  102. add r4, r0, r6
  103. add r4, r4, r7
  104. /* r5 - end of u-boot after */
  105. ldr r5, startaddr
  106. add r5, r5, r6
  107. /* r2 - start of loop code after */
  108. cmp r4, r5 /* higher address (r4 or r5) */
  109. movhs r2, r4
  110. movlo r2, r5
  111. /* r3 - end of loop code before */
  112. adr r3, end
  113. /* r4 - end of loop code after */
  114. adr r4, copy_uboot_start
  115. sub r4, r3, r4
  116. add r4, r2, r4
  117. copy_code_loop:
  118. ldmdb r3!, {r7 - r10}
  119. stmdb r4!, {r7 - r10}
  120. cmp r4, r2
  121. bhi copy_code_loop
  122. copy_code_end:
  123. mov pc, r2
  124. /*
  125. * Copy u-boot to address CONFIG_SYS_TEXT_BASE
  126. *
  127. * Nokia X-Loader loading secondary image to address 0x80400000
  128. * NOLO loading boot image to random place, so it doesn't really
  129. * matter what is set in CONFIG_SYS_TEXT_BASE. We have to copy
  130. * u-boot to CONFIG_SYS_TEXT_BASE address.
  131. */
  132. copy_uboot_start:
  133. /* r0 - start of u-boot before */
  134. /* r1 - start of u-boot after */
  135. /* r6 - maximal u-boot size */
  136. /* r2 - end of u-boot after */
  137. add r2, r1, r6
  138. /* condition for copying from left to right */
  139. cmp r0, r1
  140. addlo r1, r0, r6 /* r1 - end of u-boot before */
  141. blo copy_uboot_loop_right
  142. copy_uboot_loop_left:
  143. ldmia r0!, {r3 - r10}
  144. stmia r1!, {r3 - r10}
  145. cmp r1, r2
  146. blo copy_uboot_loop_left
  147. b copy_uboot_end
  148. copy_uboot_loop_right:
  149. ldmdb r1!, {r3 - r10}
  150. stmdb r2!, {r3 - r10}
  151. cmp r1, r0
  152. bhi copy_uboot_loop_right
  153. copy_uboot_end:
  154. bx lr
  155. end: