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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/arm/boot/compressed/head.S
  3.  *
  4.  *  Copyright (C) 1996-2002 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. /*
  53.  * "The ARM peripheral bus does not support byte or half-word operations.
  54.  * All reads and writes of the UART by the CPU should be wordwide."
  55.  *   - SA-1100 Developer's Manual, August 1999
  56.  */
  57. str rb, [r3, #0x14] @ UTDR
  58. .endm
  59. #else
  60. #error no serial architecture defined
  61. #endif
  62. #endif
  63. .macro kputc,val
  64. mov r0, val
  65. bl putc
  66. .endm
  67. .macro kphex,val,len
  68. mov r0, val
  69. mov r1, #len
  70. bl phex
  71. .endm
  72. .macro debug_reloc_start
  73. #ifdef DEBUG
  74. kputc #'n'
  75. kphex r6, 8 /* processor id */
  76. kputc #':'
  77. kphex r7, 8 /* architecture id */
  78. kputc #':'
  79. mrc p15, 0, r0, c1, c0
  80. kphex r0, 8 /* control reg */
  81. kputc #'n'
  82. kphex r5, 8 /* decompressed kernel start */
  83. kputc #'-'
  84. kphex r8, 8 /* decompressed kernel end  */
  85. kputc #'>'
  86. kphex r4, 8 /* kernel execution address */
  87. kputc #'n'
  88. #endif
  89. .endm
  90. .macro debug_reloc_end
  91. #ifdef DEBUG
  92. kphex r5, 8 /* end of kernel */
  93. kputc #'n'
  94. mov r0, r4
  95. bl memdump /* dump 256 bytes at start of kernel */
  96. #endif
  97. .endm
  98. .section ".start", #alloc, #execinstr
  99. /*
  100.  * sort out different calling conventions
  101.  */
  102. .align
  103. start:
  104. .type start,#function
  105. .rept 8
  106. mov r0, r0
  107. .endr
  108. b 1f
  109. .word 0x016f2818 @ Magic numbers to help the loader
  110. .word start @ absolute load/run zImage address
  111. .word _edata @ zImage end address
  112. 1: mov r7, r1 @ save architecture ID
  113. mov r8, #0 @ save r0
  114. #ifndef __ARM_ARCH_2__
  115. /*
  116.  * Booting from Angel - need to enter SVC mode and disable
  117.  * FIQs/IRQs (numeric definitions from angel arm.h source).
  118.  * We only do this if we were in user mode on entry.
  119.  */
  120. mrs r2, cpsr @ get current mode
  121. tst r2, #3 @ not user?
  122. bne not_angel
  123. mov r0, #0x17 @ angel_SWIreason_EnterSVC
  124. swi 0x123456 @ angel_SWI_ARM
  125. not_angel:
  126. mrs r2, cpsr @ turn off interrupts to
  127. orr r2, r2, #0xc0 @ prevent angel from running
  128. msr cpsr_c, r2
  129. #else
  130. teqp pc, #0x0c000003 @ turn off interrupts
  131. #endif
  132. /*
  133.  * Note that some cache flushing and other stuff may
  134.  * be needed here - is there an Angel SWI call for this?
  135.  */
  136. /*
  137.  * some architecture specific code can be inserted
  138.  * by the linker here, but it should preserve r7 and r8.
  139.  */
  140. .text
  141. adr r0, LC0
  142. ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp}
  143. subs r0, r0, r1 @ calculate the delta offset
  144. teq r0, #0 @ if delta is zero, we're
  145. beq not_relocated @ running at the address we
  146. @ were linked at.
  147. /*
  148.  * We're running at a different address.  We need to fix
  149.  * up various pointers:
  150.  *   r5 - zImage base address
  151.  *   r6 - GOT start
  152.  *   ip - GOT end
  153.  */
  154. add r5, r5, r0
  155. add r6, r6, r0
  156. add ip, ip, r0
  157. #ifndef CONFIG_ZBOOT_ROM
  158. /*
  159.  * If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
  160.  * we need to fix up pointers into the BSS region.
  161.  *   r2 - BSS start
  162.  *   r3 - BSS end
  163.  *   sp - stack pointer
  164.  */
  165. add r2, r2, r0
  166. add r3, r3, r0
  167. add sp, sp, r0
  168. /*
  169.  * Relocate all entries in the GOT table.
  170.  */
  171. 1: ldr r1, [r6, #0]
  172. add r1, r1, r0
  173. str r1, [r6], #4
  174. cmp r6, ip
  175. blo 1b
  176. #else
  177. /*
  178.  * Relocate entries in the GOT table.  We only relocate
  179.  * the entries that are outside the (relocated) BSS region.
  180.  */
  181. 1: ldr r1, [r6, #0]
  182. cmp r1, r2 @ entry < bss_start ||
  183. cmphs r3, r1 @ _end < entry
  184. addlo r1, r1, r0
  185. str r1, [r6], #4
  186. cmp r6, ip
  187. blo 1b
  188. #endif
  189. not_relocated: mov r0, #0
  190. 1: str r0, [r2], #4 @ clear bss
  191. str r0, [r2], #4
  192. str r0, [r2], #4
  193. str r0, [r2], #4
  194. cmp r2, r3
  195. blo 1b
  196. /*
  197.  * The C runtime environment should now be setup
  198.  * sufficiently.  Turn the cache on, set up some
  199.  * pointers, and start decompressing.
  200.  */
  201. bl cache_on
  202. mov r1, sp @ malloc space above stack
  203. add r2, sp, #0x10000 @ 64k max
  204. /*
  205.  * Check to see if we will overwrite ourselves.
  206.  *   r4 = final kernel address
  207.  *   r5 = start of this image
  208.  *   r2 = end of malloc space (and therefore this image)
  209.  * We basically want:
  210.  *   r4 >= r2 -> OK
  211.  *   r4 + image length <= r5 -> OK
  212.  */
  213. cmp r4, r2
  214. bhs wont_overwrite
  215. add r0, r4, #4096*1024 @ 4MB largest kernel size
  216. cmp r0, r5
  217. bls wont_overwrite
  218. mov r5, r2 @ decompress after malloc space
  219. mov r0, r5
  220. mov r3, r7
  221. bl decompress_kernel
  222. add r0, r0, #127
  223. bic r0, r0, #127 @ align the kernel length
  224. /*
  225.  * r0     = decompressed kernel length
  226.  * r1-r3  = unused
  227.  * r4     = kernel execution address
  228.  * r5     = decompressed kernel start
  229.  * r6     = processor ID
  230.  * r7     = architecture ID
  231.  * r8-r14 = unused
  232.  */
  233. add r1, r5, r0 @ end of decompressed kernel
  234. adr r2, reloc_start
  235. ldr r3, LC1
  236. add r3, r2, r3
  237. 1: ldmia r2!, {r8 - r13} @ copy relocation code
  238. stmia r1!, {r8 - r13}
  239. ldmia r2!, {r8 - r13}
  240. stmia r1!, {r8 - r13}
  241. cmp r2, r3
  242. blo 1b
  243. bl cache_clean_flush
  244. add pc, r5, r0 @ call relocation code
  245. /*
  246.  * We're not in danger of overwriting ourselves.  Do this the simple way.
  247.  *
  248.  * r4     = kernel execution address
  249.  * r7     = architecture ID
  250.  */
  251. wont_overwrite: mov r0, r4
  252. mov r3, r7
  253. bl decompress_kernel
  254. b call_kernel
  255. .type LC0, #object
  256. LC0: .word LC0 @ r1
  257. .word __bss_start @ r2
  258. .word _end @ r3
  259. .word _load_addr @ r4
  260. .word _start @ r5
  261. .word _got_start @ r6
  262. .word _got_end @ ip
  263. .word user_stack+4096 @ sp
  264. LC1: .word reloc_end - reloc_start
  265. .size LC0, . - LC0
  266. /*
  267.  * Turn on the cache.  We need to setup some page tables so that we
  268.  * can have both the I and D caches on.
  269.  *
  270.  * We place the page tables 16k down from the kernel execution address,
  271.  * and we hope that nothing else is using it.  If we're using it, we
  272.  * will go pop!
  273.  *
  274.  * On entry,
  275.  *  r4 = kernel execution address
  276.  *  r6 = processor ID
  277.  *  r7 = architecture number
  278.  *  r8 = run-time address of "start"
  279.  * On exit,
  280.  *  r1, r2, r3, r8, r9, r12 corrupted
  281.  * This routine must preserve:
  282.  *  r4, r5, r6, r7
  283.  */
  284. .align 5
  285. cache_on: mov r3, #8 @ cache_on function
  286. b call_cache_fn
  287. __setup_mmu:
  288. sub r3, r4, #16384 @ Page directory size
  289. bic r3, r3, #0xff @ Align the pointer
  290. bic r3, r3, #0x3f00
  291. /*
  292.  * Initialise the page tables, turning on the cacheable and bufferable
  293.  * bits for the RAM area only.
  294.  */
  295. mov r0, r3
  296. mov r8, r0, lsr #18
  297. mov r8, r8, lsl #18 @ start of RAM
  298. add r9, r8, #0x10000000 @ a reasonable RAM size
  299. mov r1, #0x12
  300. orr r1, r1, #3 << 10
  301. add r2, r3, #16384
  302. 1: cmp r1, r8 @ if virt > start of RAM
  303. #ifdef CONFIG_XSCALE_CACHE_ERRATA
  304. orrhs r1, r1, #0x08           @ set cacheable, not bufferable
  305. #else
  306. orrhs r1, r1, #0x0c @ set cacheable, bufferable
  307. #endif
  308. cmp r1, r9 @ if virt > end of RAM
  309. bichs r1, r1, #0x0c @ clear cacheable, bufferable
  310. str r1, [r0], #4 @ 1:1 mapping
  311. add r1, r1, #1048576
  312. teq r0, r2
  313. bne 1b
  314. /*
  315.  * If ever we are running from Flash, then we surely want the cache
  316.  * to be enabled also for our execution instance...  We map 2MB of it
  317.  * so there is no map overlap problem for up to 1 MB compressed kernel.
  318.  * If the execution is in RAM then we would only be duplicating the above.
  319.  */
  320. mov r1, #0x1e
  321. orr r1, r1, #3 << 10
  322. mov r2, pc, lsr #20
  323. orr r1, r1, r2, lsl #20
  324. add r0, r3, r2, lsl #2
  325. str r1, [r0], #4
  326. add r1, r1, #1048576
  327. str r1, [r0]
  328. mov pc, lr
  329. __armv4_cache_on:
  330. mov r12, lr
  331. bl __setup_mmu
  332. mov r0, #0
  333. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  334. mcr p15, 0, r0, c8, c7 @ flush I,D TLBs
  335. mcr p15, 0, r3, c2, c0 @ load page table pointer
  336. mov r0, #-1
  337. mcr p15, 0, r0, c3, c0 @ load domain access register
  338. mrc p15, 0, r0, c1, c0
  339. orr r0, r0, #0x1000 @ I-cache enable
  340. #ifndef DEBUG
  341. orr r0, r0, #0x003d @ Write buffer, mmu
  342. #endif
  343. mcr p15, 0, r0, c1, c0
  344. mov pc, r12
  345. __arm6_cache_on:
  346. mov r12, lr
  347. bl __setup_mmu
  348. mov r0, #0
  349. mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
  350. mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
  351. mcr p15, 0, r3, c2, c0 @ load page table pointer
  352. mov r0, #-1
  353. mcr p15, 0, r0, c3, c0
  354. mov r0, #0x3d
  355. mcr p15, 0, r0, c1, c0, 0
  356. mov pc, r12
  357. /*
  358.  * All code following this line is relocatable.  It is relocated by
  359.  * the above code to the end of the decompressed kernel image and
  360.  * executed there.  During this time, we have no stacks.
  361.  *
  362.  * r0     = decompressed kernel length
  363.  * r1-r3  = unused
  364.  * r4     = kernel execution address
  365.  * r5     = decompressed kernel start
  366.  * r6     = processor ID
  367.  * r7     = architecture ID
  368.  * r8-r14 = unused
  369.  */
  370. .align 5
  371. reloc_start: add r8, r5, r0
  372. debug_reloc_start
  373. mov r1, r4
  374. 1:
  375. .rept 4
  376. ldmia r5!, {r0, r2, r3, r9 - r13} @ relocate kernel
  377. stmia r1!, {r0, r2, r3, r9 - r13}
  378. .endr
  379. cmp r5, r8
  380. blo 1b
  381. debug_reloc_end
  382. call_kernel: bl cache_clean_flush
  383. bl cache_off
  384. mov r0, #0
  385. mov r1, r7 @ restore architecture number
  386. mov pc, r4 @ call kernel
  387. /*
  388.  * Here follow the relocatable cache support functions for the
  389.  * various processors.  This is a generic hook for locating an
  390.  * entry and jumping to an instruction at the specified offset
  391.  * from the start of the block.  Please note this is all position
  392.  * independent code.
  393.  *
  394.  *  r1  = corrupted
  395.  *  r2  = corrupted
  396.  *  r3  = block offset
  397.  *  r6  = corrupted
  398.  *  r12 = corrupted
  399.  */
  400. call_cache_fn: adr r12, proc_types
  401. mrc p15, 0, r6, c0, c0 @ get processor ID
  402. 1: ldr r1, [r12, #0] @ get value
  403. ldr r2, [r12, #4] @ get mask
  404. eor r1, r1, r6 @ (real ^ match)
  405. tst r1, r2 @       & mask
  406. addeq pc, r12, r3 @ call cache function
  407. add r12, r12, #4*5
  408. b 1b
  409. /*
  410.  * Table for cache operations.  This is basically:
  411.  *   - CPU ID match
  412.  *   - CPU ID mask
  413.  *   - 'cache on' method instruction
  414.  *   - 'cache off' method instruction
  415.  *   - 'cache flush' method instruction
  416.  *
  417.  * We match an entry using: ((real_id ^ match) & mask) == 0
  418.  *
  419.  * Writethrough caches generally only need 'on' and 'off'
  420.  * methods.  Writeback caches _must_ have the flush method
  421.  * defined.
  422.  */
  423. .type proc_types,#object
  424. proc_types:
  425. .word 0x41560600 @ ARM6/610
  426. .word 0xffffffe0
  427. b __arm6_cache_off @ works, but slow
  428. b __arm6_cache_off
  429. mov pc, lr
  430. @ b __arm6_cache_on @ untested
  431. @ b __arm6_cache_off
  432. @ b __armv3_cache_flush
  433. .word 0x41007000 @ ARM7/710
  434. .word 0xfff8fe00
  435. b __arm7_cache_off
  436. b __arm7_cache_off
  437. mov pc, lr
  438. .word 0x41807200 @ ARM720T (writethrough)
  439. .word 0xffffff00
  440. b __armv4_cache_on
  441. b __armv4_cache_off
  442. mov pc, lr
  443. .word 0x41129200 @ ARM920T
  444. .word 0xff00fff0
  445. b __armv4_cache_on
  446. b __armv4_cache_off
  447. b __armv4_cache_flush
  448. .word 0x4401a100 @ sa110 / sa1100
  449. .word 0xffffffe0
  450. b __armv4_cache_on
  451. b __armv4_cache_off
  452. b __armv4_cache_flush
  453. .word 0x6901b110 @ sa1110
  454. .word 0xfffffff0
  455. b __armv4_cache_on
  456. b __armv4_cache_off
  457. b __armv4_cache_flush
  458. .word 0x69050000 @ xscale
  459. .word 0xffff0000
  460. b __armv4_cache_on
  461. b __armv4_cache_off
  462. b __armv4_cache_flush
  463. .word 0 @ unrecognised type
  464. .word 0
  465. mov pc, lr
  466. mov pc, lr
  467. mov pc, lr
  468. .size proc_types, . - proc_types
  469. /*
  470.  * Turn off the Cache and MMU.  ARMv3 does not support
  471.  * reading the control register, but ARMv4 does.
  472.  *
  473.  * On entry,  r6 = processor ID
  474.  * On exit,   r0, r1, r2, r3, r12 corrupted
  475.  * This routine must preserve: r4, r6, r7
  476.  */
  477. .align 5
  478. cache_off: mov r3, #12 @ cache_off function
  479. b call_cache_fn
  480. __armv4_cache_off:
  481. mrc p15, 0, r0, c1, c0
  482. bic r0, r0, #0x000d
  483. mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
  484. mov r0, #0
  485. mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4
  486. mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4
  487. mov pc, lr
  488. __arm6_cache_off:
  489. mov r0, #0x00000030 @ ARM6 control reg.
  490. b __armv3_cache_off
  491. __arm7_cache_off:
  492. mov r0, #0x00000070 @ ARM7 control reg.
  493. b __armv3_cache_off
  494. __armv3_cache_off:
  495. mcr p15, 0, r0, c1, c0, 0 @ turn MMU and cache off
  496. mov r0, #0
  497. mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
  498. mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
  499. mov pc, lr
  500. /*
  501.  * Clean and flush the cache to maintain consistency.
  502.  *
  503.  * On entry,
  504.  *  r6 = processor ID
  505.  * On exit,
  506.  *  r1, r2, r3, r12 corrupted
  507.  * This routine must preserve:
  508.  *  r0, r4, r5, r6, r7
  509.  */
  510. .align 5
  511. cache_clean_flush:
  512. mov r3, #16
  513. b call_cache_fn
  514. __armv4_cache_flush:
  515. bic r1, pc, #31
  516. add r2, r1, #65536 @ 2x the largest dcache size
  517. 1: ldr r12, [r1], #32 @ s/w flush D cache
  518. teq r1, r2
  519. bne 1b
  520. mcr p15, 0, r1, c7, c7, 0 @ flush I cache
  521. mcr p15, 0, r1, c7, c10, 4 @ drain WB
  522. mov pc, lr
  523. __armv3_cache_flush:
  524. mov r1, #0
  525. mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
  526. mov pc, lr
  527. /*
  528.  * Various debugging routines for printing hex characters and
  529.  * memory, which again must be relocatable.
  530.  */
  531. #ifdef DEBUG
  532. .type phexbuf,#object
  533. phexbuf: .space 12
  534. .size phexbuf, . - phexbuf
  535. phex: adr r3, phexbuf
  536. mov r2, #0
  537. strb r2, [r3, r1]
  538. 1: subs r1, r1, #1
  539. movmi r0, r3
  540. bmi puts
  541. and r2, r0, #15
  542. mov r0, r0, lsr #4
  543. cmp r2, #10
  544. addge r2, r2, #7
  545. add r2, r2, #'0'
  546. strb r2, [r3, r1]
  547. b 1b
  548. puts: loadsp r3
  549. 1: ldrb r2, [r0], #1
  550. teq r2, #0
  551. moveq pc, lr
  552. 2: writeb r2
  553. mov r1, #0x00020000
  554. 3: subs r1, r1, #1
  555. bne 3b
  556. teq r2, #'n'
  557. moveq r2, #'r'
  558. beq 2b
  559. teq r0, #0
  560. bne 1b
  561. mov pc, lr
  562. putc:
  563. mov r2, r0
  564. mov r0, #0
  565. loadsp r3
  566. b 2b
  567. memdump: mov r12, r0
  568. mov r10, lr
  569. mov r11, #0
  570. 2: mov r0, r11, lsl #2
  571. add r0, r0, r12
  572. mov r1, #8
  573. bl phex
  574. mov r0, #':'
  575. bl putc
  576. 1: mov r0, #' '
  577. bl putc
  578. ldr r0, [r12, r11, lsl #2]
  579. mov r1, #8
  580. bl phex
  581. and r0, r11, #7
  582. teq r0, #3
  583. moveq r0, #' '
  584. bleq putc
  585. and r0, r11, #7
  586. add r11, r11, #1
  587. teq r0, #7
  588. bne 1b
  589. mov r0, #'n'
  590. bl putc
  591. cmp r11, #64
  592. blt 2b
  593. mov pc, r10
  594. #endif
  595. reloc_end:
  596. .align
  597. .section ".stack", "aw"
  598. user_stack: .space 4096