head.S 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * linux/arch/unicore32/boot/compressed/head.S
  3. *
  4. * Code specific to PKUnity SoC and UniCore ISA
  5. *
  6. * Copyright (C) 2001-2010 GUAN Xue-tao
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/linkage.h>
  13. #include <mach/memory.h>
  14. #define csub cmpsub
  15. #define cand cmpand
  16. #define nop8 nop; nop; nop; nop; nop; nop; nop; nop
  17. .section ".start", #alloc, #execinstr
  18. .text
  19. start:
  20. .type start,#function
  21. /* Initialize ASR, PRIV mode and INTR off */
  22. mov r0, #0xD3
  23. mov.a asr, r0
  24. adr r0, LC0
  25. ldm (r1, r2, r3, r5, r6, r7, r8), [r0]+
  26. ldw sp, [r0+], #28
  27. sub.a r0, r0, r1 @ calculate the delta offset
  28. /*
  29. * if delta is zero, we are running at the address
  30. * we were linked at.
  31. */
  32. beq not_relocated
  33. /*
  34. * We're running at a different address. We need to fix
  35. * up various pointers:
  36. * r5 - zImage base address (_start)
  37. * r7 - GOT start
  38. * r8 - GOT end
  39. */
  40. add r5, r5, r0
  41. add r7, r7, r0
  42. add r8, r8, r0
  43. /*
  44. * we need to fix up pointers into the BSS region.
  45. * r2 - BSS start
  46. * r3 - BSS end
  47. * sp - stack pointer
  48. */
  49. add r2, r2, r0
  50. add r3, r3, r0
  51. add sp, sp, r0
  52. /*
  53. * Relocate all entries in the GOT table.
  54. * This fixes up the C references.
  55. * r7 - GOT start
  56. * r8 - GOT end
  57. */
  58. 1001: ldw r1, [r7+], #0
  59. add r1, r1, r0
  60. stw.w r1, [r7]+, #4
  61. csub.a r7, r8
  62. bub 1001b
  63. not_relocated:
  64. /*
  65. * Clear BSS region.
  66. * r2 - BSS start
  67. * r3 - BSS end
  68. */
  69. mov r0, #0
  70. 1002: stw.w r0, [r2]+, #4
  71. csub.a r2, r3
  72. bub 1002b
  73. /*
  74. * Turn on the cache.
  75. */
  76. mov r0, #0
  77. movc p0.c5, r0, #28 @ cache invalidate all
  78. nop8
  79. movc p0.c6, r0, #6 @ tlb invalidate all
  80. nop8
  81. mov r0, #0x1c @ en icache and wb dcache
  82. movc p0.c1, r0, #0
  83. nop8
  84. /*
  85. * Set up some pointers, for starting decompressing.
  86. */
  87. mov r1, sp @ malloc space above stack
  88. add r2, sp, #0x10000 @ 64k max
  89. /*
  90. * Check to see if we will overwrite ourselves.
  91. * r4 = final kernel address
  92. * r5 = start of this image
  93. * r6 = size of decompressed image
  94. * r2 = end of malloc space (and therefore this image)
  95. * We basically want:
  96. * r4 >= r2 -> OK
  97. * r4 + image length <= r5 -> OK
  98. */
  99. ldw r4, =KERNEL_IMAGE_START
  100. csub.a r4, r2
  101. bea wont_overwrite
  102. add r0, r4, r6
  103. csub.a r0, r5
  104. beb wont_overwrite
  105. /*
  106. * If overwrite, just print error message
  107. */
  108. b __error_overwrite
  109. /*
  110. * We're not in danger of overwriting ourselves.
  111. * Do this the simple way.
  112. */
  113. wont_overwrite:
  114. /*
  115. * decompress_kernel:
  116. * r0: output_start
  117. * r1: free_mem_ptr_p
  118. * r2: free_mem_ptr_end_p
  119. */
  120. mov r0, r4
  121. b.l decompress_kernel @ C functions
  122. /*
  123. * Clean and flush the cache to maintain consistency.
  124. */
  125. mov r0, #0
  126. movc p0.c5, r0, #14 @ flush dcache
  127. nop8
  128. movc p0.c5, r0, #20 @ icache invalidate all
  129. nop8
  130. /*
  131. * Turn off the Cache and MMU.
  132. */
  133. mov r0, #0 @ disable i/d cache and MMU
  134. movc p0.c1, r0, #0
  135. nop8
  136. mov r0, #0 @ must be zero
  137. ldw r4, =KERNEL_IMAGE_START
  138. mov pc, r4 @ call kernel
  139. .align 2
  140. .type LC0, #object
  141. LC0: .word LC0 @ r1
  142. .word __bss_start @ r2
  143. .word _end @ r3
  144. .word _start @ r5
  145. .word _image_size @ r6
  146. .word _got_start @ r7
  147. .word _got_end @ r8
  148. .word decompress_stack_end @ sp
  149. .size LC0, . - LC0
  150. print_string:
  151. #ifdef CONFIG_DEBUG_OCD
  152. 2001: ldb.w r1, [r0]+, #1
  153. csub.a r1, #0
  154. bne 2002f
  155. mov pc, lr
  156. 2002:
  157. movc r2, p1.c0, #0
  158. cand.a r2, #2
  159. bne 2002b
  160. movc p1.c1, r1, #1
  161. csub.a r1, #'\n'
  162. cmoveq r1, #'\r'
  163. beq 2002b
  164. b 2001b
  165. #else
  166. mov pc, lr
  167. #endif
  168. __error_overwrite:
  169. adr r0, str_error
  170. b.l print_string
  171. 2001: nop8
  172. b 2001b
  173. str_error: .asciz "\nError: Kernel address OVERWRITE\n"
  174. .align
  175. .ltorg
  176. .align 4
  177. .section ".stack", "aw", %nobits
  178. decompress_stack: .space 4096
  179. decompress_stack_end: