head.S
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:10k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/arm/boot/compressed/head.S
  3.  *
  4.  *  Copyright (C) 1996-1999 Russell King
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License version 2 as
  8.  * published by the Free Software Foundation.
  9.  */
  10. #include <linux/config.h>
  11. #include <linux/linkage.h>
  12. /*
  13.  * Debugging stuff
  14.  *
  15.  * Note that these macros must not contain any code which is not
  16.  * 100% relocatable.  Any attempt to do so will result in a crash.
  17.  * Please select one of the following when turning on debugging.
  18.  */
  19. #ifdef DEBUG
  20. #if defined(CONFIG_DEBUG_DC21285_PORT)
  21. .macro loadsp, rb
  22. mov rb, #0x7c000000
  23. .endm
  24. .macro writeb, rb
  25. strb rb, [r3, #0x3f8]
  26. .endm
  27. #elif defined(CONFIG_ARCH_RPC)
  28. .macro loadsp, rb
  29. mov rb, #0x03000000
  30. orr rb, rb, #0x00010000
  31. .endm
  32. .macro writeb, rb
  33. strb rb, [r3, #0x3f8 << 2]
  34. .endm
  35. #elif defined(CONFIG_ARCH_INTEGRATOR)
  36. .macro loadsp, rb
  37. mov rb, #0x16000000
  38. .endm
  39. .macro writeb, rb
  40. strb rb, [r3, #0]
  41. .endm
  42. #elif defined(CONFIG_ARCH_SA1100)
  43. .macro loadsp, rb
  44. mov rb, #0x80000000 @ physical base address
  45. #  if defined(CONFIG_DEBUG_LL_SER3)
  46. add rb, rb, #0x00050000 @ Ser3
  47. #  else
  48. add rb, rb, #0x00010000 @ Ser1
  49. #  endif
  50. .endm
  51. .macro writeb, rb
  52. str rb, [r3, #0x14] @ UTDR
  53. .endm
  54. #else
  55. #error no serial architecture defined
  56. #endif
  57. #endif
  58. .macro kputc,val
  59. mov r0, val
  60. bl putc
  61. .endm
  62. .macro kphex,val,len
  63. mov r0, val
  64. mov r1, #len
  65. bl phex
  66. .endm
  67. .macro debug_reloc_start
  68. #ifdef DEBUG
  69. kputc #'n'
  70. kphex r6, 8 /* processor id */
  71. kputc #':'
  72. kphex r7, 8 /* architecture id */
  73. kputc #':'
  74. mrc p15, 0, r0, c1, c0
  75. kphex r0, 8 /* control reg */
  76. kputc #'n'
  77. kphex r5, 8 /* decompressed kernel start */
  78. kputc #'-'
  79. kphex r8, 8 /* decompressed kernel end  */
  80. kputc #'>'
  81. kphex r4, 8 /* kernel execution address */
  82. kputc #'n'
  83. #endif
  84. .endm
  85. .macro debug_reloc_end
  86. #ifdef DEBUG
  87. kphex r5, 8 /* end of kernel */
  88. kputc #'n'
  89. mov r0, r4
  90. bl memdump /* dump 256 bytes at start of kernel */
  91. #endif
  92. .endm
  93. .section ".start", #alloc, #execinstr
  94. /*
  95.  * sort out different calling conventions
  96.  */
  97. .align
  98. start:
  99. .type start,#function
  100. .rept 8
  101. mov r0, r0
  102. .endr
  103. b 1f
  104. .word 0x016f2818 @ Magic numbers to help the loader
  105. .word start @ absolute load/run zImage address
  106. .word _edata @ zImage end address
  107. 1: mov r7, r1 @ save architecture ID
  108. mov r8, #0 @ save r0
  109. #ifndef __ARM_ARCH_2__
  110. /*
  111.  * Booting from Angel - need to enter SVC mode and disable
  112.  * FIQs/IRQs (numeric definitions from angel arm.h source).
  113.  * We only do this if we were in user mode on entry.
  114.  */
  115. mrs r2, cpsr @ get current mode
  116. tst r2, #3 @ not user?
  117. bne not_angel
  118. mov r0, #0x17 @ angel_SWIreason_EnterSVC
  119. swi 0x123456 @ angel_SWI_ARM
  120. not_angel:
  121. mrs r2, cpsr @ turn off interrupts to
  122. orr r2, r2, #0xc0 @ prevent angel from running
  123. msr cpsr_c, r2
  124. #else
  125. teqp pc, #0x0c000003 @ turn off interrupts
  126. #endif
  127. /*
  128.  * Note that some cache flushing and other stuff may
  129.  * be needed here - is there an Angel SWI call for this?
  130.  */
  131. /*
  132.  * some architecture specific code can be inserted
  133.  * by the linker here, but it should preserve r7 and r8.
  134.  */
  135. .text
  136. 1: adr r2, LC0
  137. ldmia r2, {r2, r3, r4, r5, sp}
  138. mov r0, #0
  139. 1: str r0, [r2], #4 @ clear bss
  140. str r0, [r2], #4
  141. str r0, [r2], #4
  142. str r0, [r2], #4
  143. cmp r2, r3
  144. blt 1b
  145. mrc p15, 0, r6, c0, c0 @ get processor ID
  146. bl cache_on
  147. mov r1, sp @ malloc space above stack
  148. add r2, sp, #0x10000 @ 64k max
  149. teq r4, r5 @ will we overwrite ourselves?
  150. moveq r5, r2 @ decompress after image
  151. movne r5, r4 @ decompress to final location
  152. mov r0, r5
  153. mov r3, r7
  154. bl SYMBOL_NAME(decompress_kernel)
  155. teq r4, r5 @ do we need to relocate
  156. beq call_kernel @ the kernel?
  157. add r0, r0, #127
  158. bic r0, r0, #127 @ align the kernel length
  159. /*
  160.  * r0     = decompressed kernel length
  161.  * r1-r3  = unused
  162.  * r4     = kernel execution address
  163.  * r5     = decompressed kernel start
  164.  * r6     = processor ID
  165.  * r7     = architecture ID
  166.  * r8-r14 = unused
  167.  */
  168. add r1, r5, r0 @ end of decompressed kernel
  169. adr r2, reloc_start
  170. adr r3, reloc_end
  171. 1: ldmia r2!, {r8 - r13} @ copy relocation code
  172. stmia r1!, {r8 - r13}
  173. ldmia r2!, {r8 - r13}
  174. stmia r1!, {r8 - r13}
  175. cmp r2, r3
  176. blt 1b
  177. bl cache_clean_flush
  178. add pc, r5, r0 @ call relocation code
  179. .type LC0, #object
  180. LC0: .word __bss_start
  181. .word _end
  182. .word _load_addr
  183. .word _start
  184. .word user_stack+4096
  185. .size LC0, . - LC0
  186. /*
  187.  * Turn on the cache.  We need to setup some page tables so that we
  188.  * can have both the I and D caches on.
  189.  *
  190.  * We place the page tables 16k down from the kernel execution address,
  191.  * and we hope that nothing else is using it.  If we're using it, we
  192.  * will go pop!
  193.  *
  194.  * On entry,
  195.  *  r4 = kernel execution address
  196.  *  r6 = processor ID
  197.  *  r7 = architecture number
  198.  *  r8 = run-time address of "start"
  199.  * On exit,
  200.  *  r0, r1, r2, r3, r8, r9 corrupted
  201.  * This routine must preserve:
  202.  *  r4, r5, r6, r7
  203.  */
  204. .align 5
  205. cache_on: ldr r1, proc_sa110_type
  206. eor r1, r1, r6
  207. movs r1, r1, lsr #5 @ catch SA110 and SA1100
  208. beq 1f
  209. ldr     r1, proc_sa1110_type
  210. eor r1, r1, r6
  211. movs r1, r1, lsr #4
  212. @ movne pc, lr
  213. bne cache_off
  214. 1:
  215. sub r3, r4, #16384 @ Page directory size
  216. bic r3, r3, #0xff @ Align the pointer
  217. bic r3, r3, #0x3f00
  218. /*
  219.  * Initialise the page tables, turning on the cacheable and bufferable
  220.  * bits for the RAM area only.
  221.  */
  222. mov r0, r3
  223. mov r8, r0, lsr #18
  224. mov r8, r8, lsl #18 @ start of RAM
  225. add r9, r8, #0x10000000 @ a reasonable RAM size
  226. mov r1, #0x12
  227. orr r1, r1, #3 << 10
  228. add r2, r3, #16384
  229. 1: cmp r1, r8 @ if virt > start of RAM
  230. orrge r1, r1, #0x0c @ set cacheable, bufferable
  231. cmp r1, r9 @ if virt > end of RAM
  232. bicge r1, r1, #0x0c @ clear cacheable, bufferable
  233. str r1, [r0], #4 @ 1:1 mapping
  234. add r1, r1, #1048576
  235. teq r0, r2
  236. bne 1b
  237. /*
  238.  * If ever we are running from Flash, then we surely want the cache
  239.  * to be enabled also for our execution instance...  We map 2MB of it
  240.  * so there is no map overlap problem for up to 1 MB compressed kernel.
  241.  * If the execution is in RAM then we would only be duplicating the above.
  242.  */
  243. mov r1, #0x1e
  244. orr r1, r1, #3 << 10
  245. mov r2, pc, lsr #20
  246. orr r1, r1, r2, lsl #20
  247. add r0, r3, r2, lsl #2
  248. str r1, [r0], #4
  249. add r1, r1, #1048576
  250. str r1, [r0]
  251. mov r0, #0
  252. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  253. mcr p15, 0, r0, c8, c7 @ flush I,D TLBs
  254. mcr p15, 0, r3, c2, c0 @ load page table pointer
  255. mov r0, #-1
  256. mcr p15, 0, r0, c3, c0 @ load domain access register
  257. mrc p15, 0, r0, c1, c0
  258. orr r0, r0, #0x1000 @ I-cache enable
  259. #ifndef DEBUG
  260. orr r0, r0, #0x003d @ Write buffer, mmu
  261. #endif
  262. mcr p15, 0, r0, c1, c0
  263. mov pc, lr
  264. /*
  265.  * This code is relocatable.  It is relocated by the above code to the end
  266.  * of the kernel and executed there.  During this time, we have no stacks.
  267.  *
  268.  * r0     = decompressed kernel length
  269.  * r1-r3  = unused
  270.  * r4     = kernel execution address
  271.  * r5     = decompressed kernel start
  272.  * r6     = processor ID
  273.  * r7     = architecture ID
  274.  * r8-r14 = unused
  275.  */
  276. .align 5
  277. reloc_start: add r8, r5, r0
  278. debug_reloc_start
  279. mov r1, r4
  280. 1:
  281. .rept 4
  282. ldmia r5!, {r0, r2, r3, r9 - r13} @ relocate kernel
  283. stmia r1!, {r0, r2, r3, r9 - r13}
  284. .endr
  285. cmp r5, r8
  286. blt 1b
  287. debug_reloc_end
  288. call_kernel: bl cache_clean_flush
  289. bl cache_off
  290. mov r0, #0
  291. mov r1, r7 @ restore architecture number
  292. mov pc, r4 @ call kernel
  293. /*
  294.  * Here follow the relocatable cache support functions for
  295.  * the various processors.
  296.  */
  297. .type proc_sa110_type,#object
  298. proc_sa110_type:
  299. .word 0x4401a100
  300. .size proc_sa110_type, . - proc_sa110_type
  301. .type proc_sa1110_type,#object
  302. proc_sa1110_type:
  303. .word 0x6901b110
  304. .size proc_sa1110_type, . - proc_sa1110_type
  305. /*
  306.  * Turn off the Cache and MMU.  ARMv3 does not support
  307.  * reading the control register, but ARMv4 does.
  308.  *
  309.  * On entry,  r6 = processor ID
  310.  * On exit,   r0, r1 corrupted
  311.  * This routine must preserve: r4, r6, r7
  312.  */
  313. .align 5
  314. cache_off:
  315. #ifdef CONFIG_CPU_ARM610
  316. eor r1, r6, #0x41000000
  317. eor r1, r1, #0x00560000
  318. bic r1, r1, #0x0000001f
  319. teq r1, #0x00000600
  320. mov r0, #0x00000060 @ ARM6 control reg.
  321. beq __armv3_cache_off
  322. #endif
  323. #ifdef CONFIG_CPU_ARM710
  324. eor r1, r6, #0x41000000
  325. bic r1, r1, #0x00070000
  326. bic r1, r1, #0x000000ff
  327. teq r1, #0x00007000 @ ARM7
  328. teqne r1, #0x00007100 @ ARM710
  329. mov r0, #0x00000070 @ ARM7 control reg.
  330. beq __armv3_cache_off
  331. #endif
  332. mrc p15, 0, r0, c1, c0
  333. bic r0, r0, #0x000d
  334. mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
  335. mov r0, #0
  336. mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4
  337. mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4
  338. mov pc, lr
  339. __armv3_cache_off:
  340. mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
  341. mov r0, #0
  342. mcr p15, 0, r0, c7, c0 @ invalidate whole cache v3
  343. mcr p15, 0, r0, c5, c0 @ invalidate whole TLB v3
  344. mov pc, lr
  345. /*
  346.  * Clean and flush the cache to maintain consistency.
  347.  *
  348.  * On entry,
  349.  *  r6 = processor ID
  350.  * On exit,
  351.  *  r1, r2, r12 corrupted
  352.  * This routine must preserve:
  353.  *  r4, r6, r7
  354.  */
  355. .align 5
  356. cache_clean_flush:
  357. ldr r1, proc_sa110_type
  358. eor r1, r1, r6
  359. movs r1, r1, lsr #5 @ catch SA110 and SA1100
  360. beq 1f
  361. ldr r1, proc_sa1110_type
  362. eor r1, r1, r6
  363. movs r1, r1, lsr #4
  364. movne pc, lr
  365. 1:
  366. bic r1, pc, #31
  367. add r2, r1, #32768
  368. 1: ldr r12, [r1], #32 @ s/w flush D cache
  369. teq r1, r2
  370. bne 1b
  371. mcr p15, 0, r1, c7, c7, 0 @ flush I cache
  372. mcr p15, 0, r1, c7, c10, 4 @ drain WB
  373. mov pc, lr
  374. /*
  375.  * Various debugging routines for printing hex characters and
  376.  * memory, which again must be relocatable.
  377.  */
  378. #ifdef DEBUG
  379. .type phexbuf,#object
  380. phexbuf: .space 12
  381. .size phexbuf, . - phexbuf
  382. phex: adr r3, phexbuf
  383. mov r2, #0
  384. strb r2, [r3, r1]
  385. 1: subs r1, r1, #1
  386. movmi r0, r3
  387. bmi puts
  388. and r2, r0, #15
  389. mov r0, r0, lsr #4
  390. cmp r2, #10
  391. addge r2, r2, #7
  392. add r2, r2, #'0'
  393. strb r2, [r3, r1]
  394. b 1b
  395. puts: loadsp r3
  396. 1: ldrb r2, [r0], #1
  397. teq r2, #0
  398. moveq pc, lr
  399. 2: writeb r2
  400. mov r1, #0x00020000
  401. 3: subs r1, r1, #1
  402. bne 3b
  403. teq r2, #'n'
  404. moveq r2, #'r'
  405. beq 2b
  406. teq r0, #0
  407. bne 1b
  408. mov pc, lr
  409. putc:
  410. mov r2, r0
  411. mov r0, #0
  412. loadsp r3
  413. b 2b
  414. memdump: mov r12, r0
  415. mov r10, lr
  416. mov r11, #0
  417. 2: mov r0, r11, lsl #2
  418. add r0, r0, r12
  419. mov r1, #8
  420. bl phex
  421. mov r0, #':'
  422. bl putc
  423. 1: mov r0, #' '
  424. bl putc
  425. ldr r0, [r12, r11, lsl #2]
  426. mov r1, #8
  427. bl phex
  428. and r0, r11, #7
  429. teq r0, #3
  430. moveq r0, #' '
  431. bleq putc
  432. and r0, r11, #7
  433. add r11, r11, #1
  434. teq r0, #7
  435. bne 1b
  436. mov r0, #'n'
  437. bl putc
  438. cmp r11, #64
  439. blt 2b
  440. mov pc, r10
  441. #endif
  442. reloc_end:
  443. .align
  444. .section ".stack"
  445. user_stack: .space 4096