bootstrap.S 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #include <asm/core.h>
  3. #include <asm/regs.h>
  4. #include <asm/asmmacro.h>
  5. #include <asm/cacheasm.h>
  6. #include <asm/processor.h>
  7. /*
  8. * RB-Data: RedBoot data/bss
  9. * P: Boot-Parameters
  10. * L: Kernel-Loader
  11. *
  12. * The Linux-Kernel image including the loader must be loaded
  13. * to a position so that the kernel and the boot parameters
  14. * can fit in the space before the load address.
  15. * ______________________________________________________
  16. * |_RB-Data_|_P_|__________|_L_|___Linux-Kernel___|______|
  17. * ^
  18. * ^ Load address
  19. * ______________________________________________________
  20. * |___Linux-Kernel___|_P_|_L_|___________________________|
  21. *
  22. * The loader copies the parameter to the position that will
  23. * be the end of the kernel and itself to the end of the
  24. * parameter list.
  25. */
  26. /* Make sure we have enough space for the 'uncompressor' */
  27. #define STACK_SIZE 32768
  28. #define HEAP_SIZE (131072*4)
  29. # a2: Parameter list
  30. # a3: Size of parameter list
  31. .section .start, "ax"
  32. .globl __start
  33. /* this must be the first byte of the loader! */
  34. __start:
  35. abi_entry(32) # we do not intend to return
  36. _call0 _start
  37. __start_a0:
  38. .align 4
  39. .section .text, "ax"
  40. .literal_position
  41. .begin literal_prefix .text
  42. /* put literals in here! */
  43. .globl _start
  44. _start:
  45. /* 'reset' window registers */
  46. movi a4, 1
  47. wsr a4, ps
  48. rsync
  49. #if XCHAL_HAVE_WINDOWED
  50. rsr a5, windowbase
  51. ssl a5
  52. sll a4, a4
  53. wsr a4, windowstart
  54. rsync
  55. #endif
  56. movi a4, KERNEL_PS_WOE_MASK
  57. wsr a4, ps
  58. rsync
  59. KABI_C0 mov abi_saved0, abi_arg0
  60. /* copy the loader to its address
  61. * Note: The loader itself is a very small piece, so we assume we
  62. * don't partially overlap. We also assume (even more important)
  63. * that the kernel image is out of the way. Usually, when the
  64. * load address of this image is not at an arbitrary address,
  65. * but aligned to some 10K's we shouldn't overlap.
  66. */
  67. /* Note: The assembler cannot relax "addi a0, a0, ..." to an
  68. l32r, so we load to a4 first. */
  69. # addi a4, a0, __start - __start_a0
  70. # mov a0, a4
  71. movi a4, __start
  72. movi a5, __start_a0
  73. add a4, a0, a4
  74. sub a0, a4, a5
  75. movi a4, __start
  76. movi a5, __reloc_end
  77. # a0: address where this code has been loaded
  78. # a4: compiled address of __start
  79. # a5: compiled end address
  80. mov.n a7, a0
  81. mov.n a8, a4
  82. 1:
  83. l32i a10, a7, 0
  84. l32i a11, a7, 4
  85. s32i a10, a8, 0
  86. s32i a11, a8, 4
  87. l32i a10, a7, 8
  88. l32i a11, a7, 12
  89. s32i a10, a8, 8
  90. s32i a11, a8, 12
  91. addi a8, a8, 16
  92. addi a7, a7, 16
  93. blt a8, a5, 1b
  94. /* We have to flush and invalidate the caches here before we jump. */
  95. #if XCHAL_DCACHE_IS_WRITEBACK
  96. ___flush_dcache_all a5 a6
  97. #endif
  98. ___invalidate_icache_all a5 a6
  99. isync
  100. movi a11, _reloc
  101. jx a11
  102. .globl _reloc
  103. _reloc:
  104. /* RedBoot is now at the end of the memory, so we don't have
  105. * to copy the parameter list. Keep the code around; in case
  106. * we need it again. */
  107. #if 0
  108. # a0: load address
  109. # a2: start address of parameter list
  110. # a3: length of parameter list
  111. # a4: __start
  112. /* copy the parameter list out of the way */
  113. movi a6, _param_start
  114. add a3, a2, a3
  115. 2:
  116. l32i a8, a2, 0
  117. s32i a8, a6, 0
  118. addi a2, a2, 4
  119. addi a6, a6, 4
  120. blt a2, a3, 2b
  121. #endif
  122. /* clear BSS section */
  123. movi a6, __bss_start
  124. movi a7, __bss_end
  125. movi.n a5, 0
  126. 3:
  127. s32i a5, a6, 0
  128. addi a6, a6, 4
  129. blt a6, a7, 3b
  130. movi a5, -16
  131. movi a1, _stack + STACK_SIZE
  132. and a1, a1, a5
  133. /* Uncompress the kernel */
  134. # a0: load address
  135. # a2: boot parameter
  136. # a4: __start
  137. movi a3, __image_load
  138. sub a4, a3, a4
  139. add abi_arg2, a0, a4
  140. # a1 Stack
  141. # a8(a4) Load address of the image
  142. movi abi_arg0, _image_start
  143. movi abi_arg4, _image_end
  144. movi abi_arg1, 0x1000000
  145. sub abi_tmp0, abi_arg4, abi_arg0
  146. movi abi_arg3, complen
  147. s32i abi_tmp0, abi_arg3, 0
  148. movi a0, 0
  149. # abi_arg0 destination
  150. # abi_arg1 maximum size of destination
  151. # abi_arg2 source
  152. # abi_arg3 ptr to length
  153. .extern gunzip
  154. movi abi_tmp0, gunzip
  155. beqz abi_tmp0, 1f
  156. abi_callx abi_tmp0
  157. j 2f
  158. # abi_arg0 destination start
  159. # abi_arg1 maximum size of destination
  160. # abi_arg2 source start
  161. # abi_arg3 ptr to length
  162. # abi_arg4 destination end
  163. 1:
  164. l32i abi_tmp0, abi_arg2, 0
  165. l32i abi_tmp1, abi_arg2, 4
  166. s32i abi_tmp0, abi_arg0, 0
  167. s32i abi_tmp1, abi_arg0, 4
  168. l32i abi_tmp0, abi_arg2, 8
  169. l32i abi_tmp1, abi_arg2, 12
  170. s32i abi_tmp0, abi_arg0, 8
  171. s32i abi_tmp1, abi_arg0, 12
  172. addi abi_arg0, abi_arg0, 16
  173. addi abi_arg2, abi_arg2, 16
  174. blt abi_arg0, abi_arg4, 1b
  175. /* jump to the kernel */
  176. 2:
  177. #if XCHAL_DCACHE_IS_WRITEBACK
  178. ___flush_dcache_all a5 a6
  179. #endif
  180. ___invalidate_icache_all a5 a6
  181. isync
  182. # a2 Boot parameter list
  183. KABI_C0 mov abi_arg0, abi_saved0
  184. movi a0, _image_start
  185. jx a0
  186. .align 16
  187. .data
  188. .globl avail_ram
  189. avail_ram:
  190. .long _heap
  191. .globl end_avail
  192. end_avail:
  193. .long _heap + HEAP_SIZE
  194. .comm _stack, STACK_SIZE
  195. .comm _heap, HEAP_SIZE
  196. .globl end_avail
  197. .comm complen, 4
  198. .end literal_prefix