relocate.S 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * This is the common part of the loader relocation and initialization
  3. * process. All of the board/processor specific initialization is
  4. * done before we get here.
  5. *
  6. * Author: Tom Rini
  7. * trini@mvista.com
  8. * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others).
  9. *
  10. * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
  11. * the terms of the GNU General Public License version 2. This program
  12. * is licensed "as is" without any warranty of any kind, whether express
  13. * or implied.
  14. */
  15. #include <asm/cache.h>
  16. #include <asm/ppc_asm.h>
  17. #define GETSYM(reg, sym) \
  18. lis reg, sym@h; ori reg, reg, sym@l
  19. .text
  20. /* We get called from the early initialization code.
  21. * Register 3 has the address where we were loaded,
  22. * Register 4 contains any residual data passed from the
  23. * boot rom.
  24. */
  25. .globl relocate
  26. relocate:
  27. /* Save r3, r4 for later.
  28. * The r8/r11 are legacy registers so I don't have to
  29. * rewrite the code below :-).
  30. */
  31. mr r8, r3
  32. mr r11, r4
  33. /* compute the size of the whole image in words. */
  34. GETSYM(r4,start)
  35. GETSYM(r5,end)
  36. addi r5,r5,3 /* round up */
  37. sub r5,r5,r4 /* end - start */
  38. srwi r5,r5,2
  39. mr r7,r5 /* Save for later use. */
  40. /*
  41. * Check if we need to relocate ourselves to the link addr or were
  42. * we loaded there to begin with.
  43. */
  44. cmpw cr0,r3,r4
  45. beq start_ldr /* If 0, we don't need to relocate */
  46. /* Move this code somewhere safe. This is max(load + size, end)
  47. * r8 == load address
  48. */
  49. GETSYM(r4, start)
  50. GETSYM(r5, end)
  51. sub r6,r5,r4
  52. add r6,r8,r6 /* r6 == phys(load + size) */
  53. cmpw r5,r6
  54. bgt 1f
  55. b 2f
  56. 1:
  57. mr r6, r5
  58. 2:
  59. /* dest is in r6 */
  60. /* Ensure alignment --- this code is precautionary */
  61. addi r6,r6,4
  62. li r5,0x0003
  63. andc r6,r6,r5
  64. /* Find physical address and size of do_relocate */
  65. GETSYM(r5, __relocate_start)
  66. GETSYM(r4, __relocate_end)
  67. GETSYM(r3, start)
  68. /* Size to copy */
  69. sub r4,r4,r5
  70. srwi r4,r4,2
  71. /* Src addr to copy (= __relocate_start - start + where_loaded) */
  72. sub r3,r5,r3
  73. add r5,r8,r3
  74. /* Save dest */
  75. mr r3, r6
  76. /* Do the copy */
  77. mtctr r4
  78. 3: lwz r4,0(r5)
  79. stw r4,0(r3)
  80. addi r3,r3,4
  81. addi r5,r5,4
  82. bdnz 3b
  83. GETSYM(r4, __relocate_start)
  84. GETSYM(r5, do_relocate)
  85. sub r4,r5,r4 /* Get entry point for do_relocate in */
  86. add r6,r6,r4 /* relocated section */
  87. /* This will return to the relocated do_relocate */
  88. mtlr r6
  89. b flush_instruction_cache
  90. .section ".relocate_code","xa"
  91. do_relocate:
  92. /* We have 2 cases --- start < load, or start > load
  93. * This determines whether we copy from the end, or the start.
  94. * Its easier to have 2 loops than to have paramaterised
  95. * loops. Sigh.
  96. */
  97. li r6,0 /* Clear checksum */
  98. mtctr r7 /* Setup for a loop */
  99. GETSYM(r4, start)
  100. mr r3,r8 /* Get the load addr */
  101. cmpw cr0,r4,r3 /* If we need to copy from the end, do so */
  102. bgt do_relocate_from_end
  103. do_relocate_from_start:
  104. 1: lwz r5,0(r3) /* Load and decrement */
  105. stw r5,0(r4) /* Store and decrement */
  106. addi r3,r3,4
  107. addi r4,r4,4
  108. xor r6,r6,r5 /* Update checksum */
  109. bdnz 1b /* Are we done? */
  110. b do_relocate_out /* Finished */
  111. do_relocate_from_end:
  112. GETSYM(r3, end)
  113. slwi r4,r7,2
  114. add r4,r8,r4 /* Get the physical end */
  115. 1: lwzu r5,-4(r4)
  116. stwu r5, -4(r3)
  117. xor r6,r6,r5
  118. bdnz 1b
  119. do_relocate_out:
  120. GETSYM(r3,start_ldr)
  121. mtlr r3 /* Easiest way to do an absolute jump */
  122. /* Some boards don't boot up with the I-cache enabled. Do that
  123. * now because the decompress runs much faster that way.
  124. * As a side effect, we have to ensure the data cache is not enabled
  125. * so we can access the serial I/O without trouble.
  126. */
  127. b flush_instruction_cache
  128. .previous
  129. start_ldr:
  130. /* Clear all of BSS and set up stack for C calls */
  131. lis r3,edata@h
  132. ori r3,r3,edata@l
  133. lis r4,end@h
  134. ori r4,r4,end@l
  135. subi r3,r3,4
  136. subi r4,r4,4
  137. li r0,0
  138. 50: stwu r0,4(r3)
  139. cmpw cr0,r3,r4
  140. bne 50b
  141. 90: mr r9,r1 /* Save old stack pointer (in case it matters) */
  142. lis r1,.stack@h
  143. ori r1,r1,.stack@l
  144. addi r1,r1,4096*2
  145. subi r1,r1,256
  146. li r2,0x000F /* Mask pointer to 16-byte boundary */
  147. andc r1,r1,r2
  148. /*
  149. * Exec kernel loader
  150. */
  151. mr r3,r8 /* Load point */
  152. mr r4,r7 /* Program length */
  153. mr r5,r6 /* Checksum */
  154. mr r6,r11 /* Residual data */
  155. mr r7,r25 /* Validated OFW interface */
  156. bl load_kernel
  157. /*
  158. * Make sure the kernel knows we don't have things set in
  159. * registers. -- Tom
  160. */
  161. li r4,0
  162. li r5,0
  163. li r6,0
  164. /*
  165. * Start at the begining.
  166. */
  167. #ifdef CONFIG_PPC_PREP
  168. li r9,0xc
  169. mtlr r9
  170. /* tell kernel we're prep, by putting 0xdeadc0de at KERNELLOAD,
  171. * and tell the kernel to start on the 4th instruction since we
  172. * overwrite the first 3 sometimes (which are 'nop').
  173. */
  174. lis r10,0xdeadc0de@h
  175. ori r10,r10,0xdeadc0de@l
  176. li r9,0
  177. stw r10,0(r9)
  178. #else
  179. li r9,0
  180. mtlr r9
  181. #endif
  182. blr
  183. .comm .stack,4096*2,4