bootstrap.S 4.5 KB

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