lowlevel_init.S 3.9 KB

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