lowlevel_init.S 3.9 KB

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