bootstrap.S 4.6 KB

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