startup.S 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /* startup.S - Startup code for the MIPS. */
  2. /*
  3. * GRUB -- GRand Unified Bootloader
  4. * Copyright (C) 2009 Free Software Foundation, Inc.
  5. *
  6. * GRUB is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * GRUB is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <grub/symbol.h>
  20. #include <grub/cpu/kernel.h>
  21. #include <grub/machine/memory.h>
  22. #define BASE_ADDR 8
  23. .extern __bss_start
  24. .extern _end
  25. .globl __start, _start, start
  26. __start:
  27. _start:
  28. start:
  29. bal codestart
  30. base:
  31. . = _start + GRUB_KERNEL_CPU_COMPRESSED_SIZE
  32. compressed_size:
  33. .long 0
  34. . = _start + GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE
  35. total_module_size:
  36. .long 0
  37. . = _start + GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE
  38. kernel_image_size:
  39. .long 0
  40. codestart:
  41. /* Save our base. */
  42. move $s0, $ra
  43. /* Parse arguments. Has to be done before relocation.
  44. So need to do it in asm. */
  45. #ifdef GRUB_MACHINE_MIPS_YEELOONG
  46. /* $a2 has the environment. */
  47. move $t0, $a2
  48. argcont:
  49. lw $t1, 0($t0)
  50. beq $t1, $zero, argdone
  51. #define DO_PARSE(str, reg) \
  52. addiu $t2, $s0, (str-base);\
  53. bal parsestr;\
  54. beq $v0, $zero, 1f;\
  55. move reg, $v0;\
  56. b 2f;\
  57. 1:
  58. DO_PARSE (busclockstr, $s2)
  59. DO_PARSE (cpuclockstr, $s3)
  60. DO_PARSE (memsizestr, $s4)
  61. DO_PARSE (highmemsizestr, $s5)
  62. 2:
  63. addiu $t0, $t0, 4
  64. b argcont
  65. parsestr:
  66. move $v0, $zero
  67. move $t3, $t1
  68. 3:
  69. lb $t4, 0($t2)
  70. lb $t5, 0($t3)
  71. addiu $t2, $t2, 1
  72. addiu $t3, $t3, 1
  73. beq $t5, $zero, 1f
  74. beq $t5, $t4, 3b
  75. bne $t4, $zero, 1f
  76. addiu $t3, $t3, 0xffff
  77. digcont:
  78. lb $t5, 0($t3)
  79. /* Substract '0' from digit. */
  80. addiu $t5, $t5, 0xffd0
  81. bltz $t5, 1f
  82. addiu $t4, $t5, 0xfff7
  83. bgtz $t4, 1f
  84. /* Multiply $v0 by 10 with bitshifts. */
  85. sll $v0, $v0, 1
  86. sll $t4, $v0, 2
  87. addu $v0, $v0, $t4
  88. addu $v0, $v0, $t5
  89. addiu $t3, $t3, 1
  90. b digcont
  91. 1:
  92. jr $ra
  93. busclockstr: .asciiz "busclock="
  94. cpuclockstr: .asciiz "cpuclock="
  95. memsizestr: .asciiz "memsize="
  96. highmemsizestr: .asciiz "highmemsize="
  97. .p2align 2
  98. argdone:
  99. #endif
  100. /* Decompress the payload. */
  101. addiu $a0, $s0, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR
  102. lui $a1, %hi(compressed)
  103. addiu $a1, %lo(compressed)
  104. lw $a2, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($s0)
  105. move $s1, $a1
  106. /* $a0 contains source compressed address, $a1 is destination,
  107. $a2 is compressed size. FIXME: put LZMA here. Don't clober $s0,
  108. $s1, $s2, $s3, $s4 and $s5.
  109. On return $v0 contains uncompressed size.
  110. */
  111. move $v0, $a2
  112. reloccont:
  113. lb $t4, 0($a0)
  114. sb $t4, 0($a1)
  115. addiu $a1,$a1,1
  116. addiu $a0,$a0,1
  117. addiu $a2, 0xffff
  118. bne $a2, $0, reloccont
  119. move $a0, $s1
  120. move $a1, $v0
  121. #include "cache_flush.S"
  122. lui $t1, %hi(cont)
  123. addiu $t1, %lo(cont)
  124. jr $t1
  125. . = _start + GRUB_KERNEL_CPU_RAW_SIZE
  126. compressed:
  127. . = _start + GRUB_KERNEL_CPU_PREFIX
  128. VARIABLE(grub_prefix)
  129. /* to be filled by grub-mkelfimage */
  130. /*
  131. * Leave some breathing room for the prefix.
  132. */
  133. . = _start + GRUB_KERNEL_CPU_DATA_END
  134. #ifdef GRUB_MACHINE_MIPS_YEELOONG
  135. VARIABLE (grub_arch_busclock)
  136. .long 0
  137. VARIABLE (grub_arch_cpuclock)
  138. .long 0
  139. VARIABLE (grub_arch_memsize)
  140. .long 0
  141. VARIABLE (grub_arch_highmemsize)
  142. .long 0
  143. #endif
  144. cont:
  145. #ifdef GRUB_MACHINE_MIPS_YEELOONG
  146. lui $t1, %hi(grub_arch_busclock)
  147. addiu $t1, %lo(grub_arch_busclock)
  148. sw $s2, 0($t1)
  149. sw $s3, 4($t1)
  150. sw $s4, 8($t1)
  151. sw $s5, 12($t1)
  152. #endif
  153. /* Move the modules out of BSS. */
  154. lui $t1, %hi(_start)
  155. addiu $t1, %lo(_start)
  156. lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0)
  157. addu $t2, $t1, $t2
  158. lui $t1, %hi(_end)
  159. addiu $t1, %lo(_end)
  160. addiu $t1, (GRUB_MOD_ALIGN-1)
  161. li $t3, (GRUB_MOD_ALIGN-1)
  162. nor $t3, $t3, $0
  163. and $t1, $t1, $t3
  164. lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($s0)
  165. /* Backward copy. */
  166. add $t1, $t1, $t3
  167. add $t2, $t2, $t3
  168. addiu $t1, $t1, 0xffff
  169. addiu $t2, $t2, 0xffff
  170. /* $t2 is source. $t1 is destination. $t3 is size. */
  171. modulesmovcont:
  172. lb $t4, 0($t2)
  173. sb $t4, 0($t1)
  174. addiu $t1,$t1,0xffff
  175. addiu $t2,$t2,0xffff
  176. addiu $t3, 0xffff
  177. bne $t3, $0, modulesmovcont
  178. /* Clean BSS. */
  179. lui $t1, %hi(__bss_start)
  180. addiu $t1, %lo(__bss_start)
  181. lui $t2, %hi(_end)
  182. addiu $t2, %lo(_end)
  183. bsscont:
  184. sb $0,0($t1)
  185. addiu $t1,$t1,1
  186. sltu $t3,$t1,$t2
  187. bne $t3, $0, bsscont
  188. li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH
  189. lui $t1, %hi(grub_main)
  190. addiu $t1, %lo(grub_main)
  191. jr $t1