head.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: SCCS/s.head.S 1.11 07/31/01 16:36:06 trini
  3.  */
  4. #include "../../kernel/ppc_defs.h"
  5. #include "../../kernel/ppc_asm.tmpl"
  6. #include <asm/processor.h>
  7. #include <asm/cache.h>
  8. .text
  9. /*
  10.  * Boot loader philosophy:
  11.  *      ROM loads us to some arbitrary location
  12.  *      Move the boot code to the link address (8M)
  13.  *      Call decompress_kernel()
  14.  *         Relocate the initrd, zimage and residual data to 8M
  15.  *         Decompress the kernel to 0
  16.  *      Jump to the kernel entry
  17.  *            -- Cort
  18.  */
  19. .globl start
  20. start:
  21. bl start_
  22. start_:
  23. mr r11,r3 /* Save pointer to residual/board data */
  24. mr      r25,r5          /* Save OFW pointer */
  25. li r3,MSR_IP /* Establish default MSR value */
  26. mtmsr r3
  27. /* check if we need to relocate ourselves to the link addr or were we
  28.    loaded there to begin with -- Cort */
  29. lis r4,start@h
  30. ori r4,r4,start@l
  31. mflr r3
  32. subi r3,r3,4 /* we get the nip, not the ip of the branch */
  33. mr r8,r3
  34. cmp 0,r3,r4
  35. bne 1010f
  36. /* compute size of whole image in words.  this should be moved to
  37.  * start_ldr() -- Cort
  38.  */
  39. lis r4,start@h
  40. ori r4,r4,start@l
  41. lis r5,end@h
  42. ori r5,r5,end@l
  43. addi r5,r5,3 /* round up */
  44. sub r5,r5,r4
  45. srwi r5,r5,2
  46. mr r7,r5
  47. b start_ldr
  48. 1010:
  49. /* 
  50.  * no matter where we're loaded, move ourselves to -Ttext address
  51.  */
  52. relocate:
  53. mflr r3 /* Compute code bias */
  54. subi r3,r3,4
  55. mr r8,r3
  56. lis r4,start@h
  57. ori r4,r4,start@l
  58. lis r5,end@h
  59. ori r5,r5,end@l
  60. addi r5,r5,3 /* Round up - just in case */
  61. sub r5,r5,r4 /* Compute # longwords to move */
  62. srwi r5,r5,2
  63. mtctr r5
  64. mr r7,r5
  65. li r6,0
  66. subi r3,r3,4 /* Set up for loop */
  67. subi r4,r4,4
  68. 00: lwzu r5,4(r3)
  69. stwu r5,4(r4)
  70. xor r6,r6,r5
  71. bdnz 00b
  72.    lis r3,start_ldr@h
  73. ori r3,r3,start_ldr@l
  74. mtlr r3 /* Easiest way to do an absolute jump */
  75. blr
  76. start_ldr:
  77. /* Clear all of BSS */
  78. lis r3,edata@h
  79. ori r3,r3,edata@l
  80. lis r4,end@h
  81. ori r4,r4,end@l
  82. subi r3,r3,4
  83. subi r4,r4,4
  84. li r0,0
  85. 50: stwu r0,4(r3)
  86. cmp 0,r3,r4
  87. bne 50b
  88. 90: mr r9,r1 /* Save old stack pointer (in case it matters) */
  89. lis r1,.stack@h
  90. ori r1,r1,.stack@l
  91. addi r1,r1,4096*2
  92. subi r1,r1,256
  93. li r2,0x000F /* Mask pointer to 16-byte boundary */
  94. andc r1,r1,r2
  95. /* Setup ISA_io */
  96. lis r3,ISA_io@h
  97. ori r3,r3,ISA_io@l
  98. lis r4,0x8000
  99. stw r4,0(r3)
  100. /* Run loader */
  101. mr r3,r8 /* Load point */
  102. mr r4,r7 /* Program length */
  103. mr r5,r6 /* Checksum */
  104. mr r6,r11 /* Residual data */
  105. mr      r7,r25                  /* OFW interfaces */
  106. bl decompress_kernel
  107. /* changed to use r3 (as firmware does) for kernel
  108.    as ptr to residual -- Cort*/
  109. lis r6,cmd_line@h
  110. ori r6,r6,cmd_line@l
  111. lwz r6, 0(r6)
  112. subi r7,r6,1
  113. 00: lbzu r2,1(r7)
  114. cmpi 0,r2,0
  115. bne 00b
  116. /* r4,r5 have initrd_start, size */
  117. lis r2,initrd_start@h
  118. ori r2,r2,initrd_start@l
  119. lwz r4,0(r2)
  120. lis r2,initrd_end@h
  121. ori r2,r2,initrd_end@l
  122. lwz r5,0(r2)
  123. /* tell kernel we're prep */
  124. /* 
  125.  * get start address of kernel code which is stored as a coff
  126.  * entry.  see boot/head.S -- Cort 
  127.  */
  128. li r9,0x4
  129. mtlr r9
  130. lis r10,0xdeadc0de@h
  131. ori r10,r10,0xdeadc0de@l
  132. li r9,0
  133. stw r10,0(r9)
  134. /*
  135.  * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2
  136.  * so disable BATs before setting this to avoid a clash
  137.  */
  138. li      r8,0
  139. mtspr   DBAT0U,r8
  140. mtspr   DBAT1U,r8
  141. mtspr   DBAT2U,r8
  142. mtspr   DBAT3U,r8
  143. mtspr   IBAT0U,r8
  144. mtspr   IBAT1U,r8
  145. mtspr   IBAT2U,r8
  146. mtspr   IBAT3U,r8
  147. blr
  148. hang:
  149. b hang
  150. /*
  151.  * Delay for a number of microseconds
  152.  * -- Use the BUS timer (assumes 66MHz)
  153.  */
  154. .globl udelay
  155. udelay:
  156. mfspr r4,PVR
  157. srwi r4,r4,16
  158. cmpi 0,r4,1 /* 601 ? */
  159. bne .udelay_not_601
  160. 00: li r0,86 /* Instructions / microsecond? */
  161. mtctr r0
  162. 10: addi r0,r0,0 /* NOP */
  163. bdnz 10b
  164. subic. r3,r3,1
  165. bne 00b
  166. blr
  167. .udelay_not_601:
  168. mulli r4,r3,1000 /* nanoseconds */
  169. addi r4,r4,59
  170. li r5,60
  171. divw r4,r4,r5 /* BUS ticks */
  172. 1: mftbu r5
  173. mftb r6
  174. mftbu r7
  175. cmp 0,r5,r7
  176. bne 1b /* Get [synced] base time */
  177. addc r9,r6,r4 /* Compute end time */
  178. addze r8,r5
  179. 2: mftbu r5
  180. cmp 0,r5,r8
  181. blt 2b
  182. bgt 3f
  183. mftb r6
  184. cmp 0,r6,r9
  185. blt 2b
  186. 3: blr
  187. .globl _get_HID0
  188. _get_HID0:
  189. mfspr r3,HID0
  190. blr
  191. .globl _put_HID0
  192. _put_HID0:
  193. mtspr HID0,r3
  194. blr
  195. .globl _get_MSR
  196. _get_MSR:
  197. mfmsr r3
  198. blr
  199. .globl _put_MSR
  200. _put_MSR:
  201. mtmsr r3
  202. blr
  203. /*
  204.  * Flush instruction cache
  205.  * *** I'm really paranoid here!
  206.  */
  207. _GLOBAL(flush_instruction_cache)
  208. mflr r5
  209. bl flush_data_cache
  210. mfspr r3,HID0 /* Caches are controlled by this register */
  211. li r4,0
  212. ori r4,r4,(HID0_ICE|HID0_ICFI)
  213. or r3,r3,r4 /* Need to enable+invalidate to clear */
  214. mtspr HID0,r3
  215. andc r3,r3,r4
  216. ori r3,r3,HID0_ICE /* Enable cache */
  217. mtspr HID0,r3
  218. mtlr r5
  219. blr
  220. #define NUM_CACHE_LINES 128*8
  221. #define CACHE_LINE_SIZE 32 
  222. #define cache_flush_buffer 0x1000
  223. /*
  224.  * Flush data cache
  225.  * *** I'm really paranoid here!
  226.  */
  227. _GLOBAL(flush_data_cache)
  228. lis r3,cache_flush_buffer@h
  229. ori r3,r3,cache_flush_buffer@l
  230. li r4,NUM_CACHE_LINES
  231. mtctr r4
  232. 00: lwz r4,0(r3)
  233. addi r3,r3,CACHE_LINE_SIZE /* Next line, please */
  234. bdnz 00b
  235. 10: blr
  236. .comm .stack,4096*2,4