relocate.S 4.7 KB

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