head.S 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068
  1. /*
  2. * linux/arch/arm/boot/compressed/head.S
  3. *
  4. * Copyright (C) 1996-2002 Russell King
  5. * Copyright (C) 2004 Hyok S. Choi (MPU support)
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  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_ICEDCC)
  21. #ifdef CONFIG_CPU_V6
  22. .macro loadsp, rb
  23. .endm
  24. .macro writeb, ch, rb
  25. mcr p14, 0, \ch, c0, c5, 0
  26. .endm
  27. #elif defined(CONFIG_CPU_XSCALE)
  28. .macro loadsp, rb
  29. .endm
  30. .macro writeb, ch, rb
  31. mcr p14, 0, \ch, c8, c0, 0
  32. .endm
  33. #else
  34. .macro loadsp, rb
  35. .endm
  36. .macro writeb, ch, rb
  37. mcr p14, 0, \ch, c1, c0, 0
  38. .endm
  39. #endif
  40. #else
  41. #include <mach/debug-macro.S>
  42. .macro writeb, ch, rb
  43. senduart \ch, \rb
  44. .endm
  45. #if defined(CONFIG_ARCH_SA1100)
  46. .macro loadsp, rb
  47. mov \rb, #0x80000000 @ physical base address
  48. #ifdef CONFIG_DEBUG_LL_SER3
  49. add \rb, \rb, #0x00050000 @ Ser3
  50. #else
  51. add \rb, \rb, #0x00010000 @ Ser1
  52. #endif
  53. .endm
  54. #elif defined(CONFIG_ARCH_S3C2410)
  55. .macro loadsp, rb
  56. mov \rb, #0x50000000
  57. add \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
  58. .endm
  59. #else
  60. .macro loadsp, rb
  61. addruart \rb
  62. .endm
  63. #endif
  64. #endif
  65. #endif
  66. .macro kputc,val
  67. mov r0, \val
  68. bl putc
  69. .endm
  70. .macro kphex,val,len
  71. mov r0, \val
  72. mov r1, #\len
  73. bl phex
  74. .endm
  75. .macro debug_reloc_start
  76. #ifdef DEBUG
  77. kputc #'\n'
  78. kphex r6, 8 /* processor id */
  79. kputc #':'
  80. kphex r7, 8 /* architecture id */
  81. #ifdef CONFIG_CPU_CP15
  82. kputc #':'
  83. mrc p15, 0, r0, c1, c0
  84. kphex r0, 8 /* control reg */
  85. #endif
  86. kputc #'\n'
  87. kphex r5, 8 /* decompressed kernel start */
  88. kputc #'-'
  89. kphex r9, 8 /* decompressed kernel end */
  90. kputc #'>'
  91. kphex r4, 8 /* kernel execution address */
  92. kputc #'\n'
  93. #endif
  94. .endm
  95. .macro debug_reloc_end
  96. #ifdef DEBUG
  97. kphex r5, 8 /* end of kernel */
  98. kputc #'\n'
  99. mov r0, r4
  100. bl memdump /* dump 256 bytes at start of kernel */
  101. #endif
  102. .endm
  103. .section ".start", #alloc, #execinstr
  104. /*
  105. * sort out different calling conventions
  106. */
  107. .align
  108. start:
  109. .type start,#function
  110. .rept 8
  111. mov r0, r0
  112. .endr
  113. b 1f
  114. .word 0x016f2818 @ Magic numbers to help the loader
  115. .word start @ absolute load/run zImage address
  116. .word _edata @ zImage end address
  117. 1: mov r7, r1 @ save architecture ID
  118. mov r8, r2 @ save atags pointer
  119. #ifndef __ARM_ARCH_2__
  120. /*
  121. * Booting from Angel - need to enter SVC mode and disable
  122. * FIQs/IRQs (numeric definitions from angel arm.h source).
  123. * We only do this if we were in user mode on entry.
  124. */
  125. mrs r2, cpsr @ get current mode
  126. tst r2, #3 @ not user?
  127. bne not_angel
  128. mov r0, #0x17 @ angel_SWIreason_EnterSVC
  129. ARM( swi 0x123456 ) @ angel_SWI_ARM
  130. THUMB( svc 0xab ) @ angel_SWI_THUMB
  131. not_angel:
  132. mrs r2, cpsr @ turn off interrupts to
  133. orr r2, r2, #0xc0 @ prevent angel from running
  134. msr cpsr_c, r2
  135. #else
  136. teqp pc, #0x0c000003 @ turn off interrupts
  137. #endif
  138. /*
  139. * Note that some cache flushing and other stuff may
  140. * be needed here - is there an Angel SWI call for this?
  141. */
  142. /*
  143. * some architecture specific code can be inserted
  144. * by the linker here, but it should preserve r7, r8, and r9.
  145. */
  146. .text
  147. adr r0, LC0
  148. ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp} )
  149. THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, ip} )
  150. THUMB( ldr sp, [r0, #28] )
  151. subs r0, r0, r1 @ calculate the delta offset
  152. @ if delta is zero, we are
  153. beq not_relocated @ running at the address we
  154. @ were linked at.
  155. /*
  156. * We're running at a different address. We need to fix
  157. * up various pointers:
  158. * r5 - zImage base address
  159. * r6 - GOT start
  160. * ip - GOT end
  161. */
  162. add r5, r5, r0
  163. add r6, r6, r0
  164. add ip, ip, r0
  165. #ifndef CONFIG_ZBOOT_ROM
  166. /*
  167. * If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
  168. * we need to fix up pointers into the BSS region.
  169. * r2 - BSS start
  170. * r3 - BSS end
  171. * sp - stack pointer
  172. */
  173. add r2, r2, r0
  174. add r3, r3, r0
  175. add sp, sp, r0
  176. /*
  177. * Relocate all entries in the GOT table.
  178. */
  179. 1: ldr r1, [r6, #0] @ relocate entries in the GOT
  180. add r1, r1, r0 @ table. This fixes up the
  181. str r1, [r6], #4 @ C references.
  182. cmp r6, ip
  183. blo 1b
  184. #else
  185. /*
  186. * Relocate entries in the GOT table. We only relocate
  187. * the entries that are outside the (relocated) BSS region.
  188. */
  189. 1: ldr r1, [r6, #0] @ relocate entries in the GOT
  190. cmp r1, r2 @ entry < bss_start ||
  191. cmphs r3, r1 @ _end < entry
  192. addlo r1, r1, r0 @ table. This fixes up the
  193. str r1, [r6], #4 @ C references.
  194. cmp r6, ip
  195. blo 1b
  196. #endif
  197. not_relocated: mov r0, #0
  198. 1: str r0, [r2], #4 @ clear bss
  199. str r0, [r2], #4
  200. str r0, [r2], #4
  201. str r0, [r2], #4
  202. cmp r2, r3
  203. blo 1b
  204. /*
  205. * The C runtime environment should now be setup
  206. * sufficiently. Turn the cache on, set up some
  207. * pointers, and start decompressing.
  208. */
  209. bl cache_on
  210. mov r1, sp @ malloc space above stack
  211. add r2, sp, #0x10000 @ 64k max
  212. /*
  213. * Check to see if we will overwrite ourselves.
  214. * r4 = final kernel address
  215. * r5 = start of this image
  216. * r2 = end of malloc space (and therefore this image)
  217. * We basically want:
  218. * r4 >= r2 -> OK
  219. * r4 + image length <= r5 -> OK
  220. */
  221. cmp r4, r2
  222. bhs wont_overwrite
  223. sub r3, sp, r5 @ > compressed kernel size
  224. add r0, r4, r3, lsl #2 @ allow for 4x expansion
  225. cmp r0, r5
  226. bls wont_overwrite
  227. mov r5, r2 @ decompress after malloc space
  228. mov r0, r5
  229. mov r3, r7
  230. bl decompress_kernel
  231. add r0, r0, #127 + 128 @ alignment + stack
  232. bic r0, r0, #127 @ align the kernel length
  233. /*
  234. * r0 = decompressed kernel length
  235. * r1-r3 = unused
  236. * r4 = kernel execution address
  237. * r5 = decompressed kernel start
  238. * r6 = processor ID
  239. * r7 = architecture ID
  240. * r8 = atags pointer
  241. * r9-r12,r14 = corrupted
  242. */
  243. add r1, r5, r0 @ end of decompressed kernel
  244. adr r2, reloc_start
  245. ldr r3, LC1
  246. add r3, r2, r3
  247. 1: ldmia r2!, {r9 - r12, r14} @ copy relocation code
  248. stmia r1!, {r9 - r12, r14}
  249. ldmia r2!, {r9 - r12, r14}
  250. stmia r1!, {r9 - r12, r14}
  251. cmp r2, r3
  252. blo 1b
  253. mov sp, r1
  254. add sp, sp, #128 @ relocate the stack
  255. bl cache_clean_flush
  256. ARM( add pc, r5, r0 ) @ call relocation code
  257. THUMB( add r12, r5, r0 )
  258. THUMB( mov pc, r12 ) @ call relocation code
  259. /*
  260. * We're not in danger of overwriting ourselves. Do this the simple way.
  261. *
  262. * r4 = kernel execution address
  263. * r7 = architecture ID
  264. */
  265. wont_overwrite: mov r0, r4
  266. mov r3, r7
  267. bl decompress_kernel
  268. b call_kernel
  269. .align 2
  270. .type LC0, #object
  271. LC0: .word LC0 @ r1
  272. .word __bss_start @ r2
  273. .word _end @ r3
  274. .word zreladdr @ r4
  275. .word _start @ r5
  276. .word _got_start @ r6
  277. .word _got_end @ ip
  278. .word user_stack+4096 @ sp
  279. LC1: .word reloc_end - reloc_start
  280. .size LC0, . - LC0
  281. #ifdef CONFIG_ARCH_RPC
  282. .globl params
  283. params: ldr r0, =params_phys
  284. mov pc, lr
  285. .ltorg
  286. .align
  287. #endif
  288. /*
  289. * Turn on the cache. We need to setup some page tables so that we
  290. * can have both the I and D caches on.
  291. *
  292. * We place the page tables 16k down from the kernel execution address,
  293. * and we hope that nothing else is using it. If we're using it, we
  294. * will go pop!
  295. *
  296. * On entry,
  297. * r4 = kernel execution address
  298. * r6 = processor ID
  299. * r7 = architecture number
  300. * r8 = atags pointer
  301. * r9 = run-time address of "start" (???)
  302. * On exit,
  303. * r1, r2, r3, r9, r10, r12 corrupted
  304. * This routine must preserve:
  305. * r4, r5, r6, r7, r8
  306. */
  307. .align 5
  308. cache_on: mov r3, #8 @ cache_on function
  309. b call_cache_fn
  310. /*
  311. * Initialize the highest priority protection region, PR7
  312. * to cover all 32bit address and cacheable and bufferable.
  313. */
  314. __armv4_mpu_cache_on:
  315. mov r0, #0x3f @ 4G, the whole
  316. mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting
  317. mcr p15, 0, r0, c6, c7, 1
  318. mov r0, #0x80 @ PR7
  319. mcr p15, 0, r0, c2, c0, 0 @ D-cache on
  320. mcr p15, 0, r0, c2, c0, 1 @ I-cache on
  321. mcr p15, 0, r0, c3, c0, 0 @ write-buffer on
  322. mov r0, #0xc000
  323. mcr p15, 0, r0, c5, c0, 1 @ I-access permission
  324. mcr p15, 0, r0, c5, c0, 0 @ D-access permission
  325. mov r0, #0
  326. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  327. mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache
  328. mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache
  329. mrc p15, 0, r0, c1, c0, 0 @ read control reg
  330. @ ...I .... ..D. WC.M
  331. orr r0, r0, #0x002d @ .... .... ..1. 11.1
  332. orr r0, r0, #0x1000 @ ...1 .... .... ....
  333. mcr p15, 0, r0, c1, c0, 0 @ write control reg
  334. mov r0, #0
  335. mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache
  336. mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache
  337. mov pc, lr
  338. __armv3_mpu_cache_on:
  339. mov r0, #0x3f @ 4G, the whole
  340. mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting
  341. mov r0, #0x80 @ PR7
  342. mcr p15, 0, r0, c2, c0, 0 @ cache on
  343. mcr p15, 0, r0, c3, c0, 0 @ write-buffer on
  344. mov r0, #0xc000
  345. mcr p15, 0, r0, c5, c0, 0 @ access permission
  346. mov r0, #0
  347. mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
  348. mrc p15, 0, r0, c1, c0, 0 @ read control reg
  349. @ .... .... .... WC.M
  350. orr r0, r0, #0x000d @ .... .... .... 11.1
  351. mov r0, #0
  352. mcr p15, 0, r0, c1, c0, 0 @ write control reg
  353. mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
  354. mov pc, lr
  355. __setup_mmu: sub r3, r4, #16384 @ Page directory size
  356. bic r3, r3, #0xff @ Align the pointer
  357. bic r3, r3, #0x3f00
  358. /*
  359. * Initialise the page tables, turning on the cacheable and bufferable
  360. * bits for the RAM area only.
  361. */
  362. mov r0, r3
  363. mov r9, r0, lsr #18
  364. mov r9, r9, lsl #18 @ start of RAM
  365. add r10, r9, #0x10000000 @ a reasonable RAM size
  366. mov r1, #0x12
  367. orr r1, r1, #3 << 10
  368. add r2, r3, #16384
  369. 1: cmp r1, r9 @ if virt > start of RAM
  370. orrhs r1, r1, #0x0c @ set cacheable, bufferable
  371. cmp r1, r10 @ if virt > end of RAM
  372. bichs r1, r1, #0x0c @ clear cacheable, bufferable
  373. str r1, [r0], #4 @ 1:1 mapping
  374. add r1, r1, #1048576
  375. teq r0, r2
  376. bne 1b
  377. /*
  378. * If ever we are running from Flash, then we surely want the cache
  379. * to be enabled also for our execution instance... We map 2MB of it
  380. * so there is no map overlap problem for up to 1 MB compressed kernel.
  381. * If the execution is in RAM then we would only be duplicating the above.
  382. */
  383. mov r1, #0x1e
  384. orr r1, r1, #3 << 10
  385. mov r2, pc, lsr #20
  386. orr r1, r1, r2, lsl #20
  387. add r0, r3, r2, lsl #2
  388. str r1, [r0], #4
  389. add r1, r1, #1048576
  390. str r1, [r0]
  391. mov pc, lr
  392. ENDPROC(__setup_mmu)
  393. __armv4_mmu_cache_on:
  394. mov r12, lr
  395. #ifdef CONFIG_MMU
  396. bl __setup_mmu
  397. mov r0, #0
  398. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  399. mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
  400. mrc p15, 0, r0, c1, c0, 0 @ read control reg
  401. orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
  402. orr r0, r0, #0x0030
  403. #ifdef CONFIG_CPU_ENDIAN_BE8
  404. orr r0, r0, #1 << 25 @ big-endian page tables
  405. #endif
  406. bl __common_mmu_cache_on
  407. mov r0, #0
  408. mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
  409. #endif
  410. mov pc, r12
  411. __armv7_mmu_cache_on:
  412. mov r12, lr
  413. #ifdef CONFIG_MMU
  414. mrc p15, 0, r11, c0, c1, 4 @ read ID_MMFR0
  415. tst r11, #0xf @ VMSA
  416. blne __setup_mmu
  417. mov r0, #0
  418. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  419. tst r11, #0xf @ VMSA
  420. mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
  421. #endif
  422. mrc p15, 0, r0, c1, c0, 0 @ read control reg
  423. orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
  424. orr r0, r0, #0x003c @ write buffer
  425. #ifdef CONFIG_MMU
  426. #ifdef CONFIG_CPU_ENDIAN_BE8
  427. orr r0, r0, #1 << 25 @ big-endian page tables
  428. #endif
  429. orrne r0, r0, #1 @ MMU enabled
  430. movne r1, #-1
  431. mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer
  432. mcrne p15, 0, r1, c3, c0, 0 @ load domain access control
  433. #endif
  434. mcr p15, 0, r0, c1, c0, 0 @ load control register
  435. mrc p15, 0, r0, c1, c0, 0 @ and read it back
  436. mov r0, #0
  437. mcr p15, 0, r0, c7, c5, 4 @ ISB
  438. mov pc, r12
  439. __fa526_cache_on:
  440. mov r12, lr
  441. bl __setup_mmu
  442. mov r0, #0
  443. mcr p15, 0, r0, c7, c7, 0 @ Invalidate whole cache
  444. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  445. mcr p15, 0, r0, c8, c7, 0 @ flush UTLB
  446. mrc p15, 0, r0, c1, c0, 0 @ read control reg
  447. orr r0, r0, #0x1000 @ I-cache enable
  448. bl __common_mmu_cache_on
  449. mov r0, #0
  450. mcr p15, 0, r0, c8, c7, 0 @ flush UTLB
  451. mov pc, r12
  452. __arm6_mmu_cache_on:
  453. mov r12, lr
  454. bl __setup_mmu
  455. mov r0, #0
  456. mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
  457. mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
  458. mov r0, #0x30
  459. bl __common_mmu_cache_on
  460. mov r0, #0
  461. mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
  462. mov pc, r12
  463. __common_mmu_cache_on:
  464. #ifndef CONFIG_THUMB2_KERNEL
  465. #ifndef DEBUG
  466. orr r0, r0, #0x000d @ Write buffer, mmu
  467. #endif
  468. mov r1, #-1
  469. mcr p15, 0, r3, c2, c0, 0 @ load page table pointer
  470. mcr p15, 0, r1, c3, c0, 0 @ load domain access control
  471. b 1f
  472. .align 5 @ cache line aligned
  473. 1: mcr p15, 0, r0, c1, c0, 0 @ load control register
  474. mrc p15, 0, r0, c1, c0, 0 @ and read it back to
  475. sub pc, lr, r0, lsr #32 @ properly flush pipeline
  476. #endif
  477. /*
  478. * All code following this line is relocatable. It is relocated by
  479. * the above code to the end of the decompressed kernel image and
  480. * executed there. During this time, we have no stacks.
  481. *
  482. * r0 = decompressed kernel length
  483. * r1-r3 = unused
  484. * r4 = kernel execution address
  485. * r5 = decompressed kernel start
  486. * r6 = processor ID
  487. * r7 = architecture ID
  488. * r8 = atags pointer
  489. * r9-r12,r14 = corrupted
  490. */
  491. .align 5
  492. reloc_start: add r9, r5, r0
  493. sub r9, r9, #128 @ do not copy the stack
  494. debug_reloc_start
  495. mov r1, r4
  496. 1:
  497. .rept 4
  498. ldmia r5!, {r0, r2, r3, r10 - r12, r14} @ relocate kernel
  499. stmia r1!, {r0, r2, r3, r10 - r12, r14}
  500. .endr
  501. cmp r5, r9
  502. blo 1b
  503. mov sp, r1
  504. add sp, sp, #128 @ relocate the stack
  505. debug_reloc_end
  506. call_kernel: bl cache_clean_flush
  507. bl cache_off
  508. mov r0, #0 @ must be zero
  509. mov r1, r7 @ restore architecture number
  510. mov r2, r8 @ restore atags pointer
  511. mov pc, r4 @ call kernel
  512. /*
  513. * Here follow the relocatable cache support functions for the
  514. * various processors. This is a generic hook for locating an
  515. * entry and jumping to an instruction at the specified offset
  516. * from the start of the block. Please note this is all position
  517. * independent code.
  518. *
  519. * r1 = corrupted
  520. * r2 = corrupted
  521. * r3 = block offset
  522. * r6 = corrupted
  523. * r12 = corrupted
  524. */
  525. call_cache_fn: adr r12, proc_types
  526. #ifdef CONFIG_CPU_CP15
  527. mrc p15, 0, r6, c0, c0 @ get processor ID
  528. #else
  529. ldr r6, =CONFIG_PROCESSOR_ID
  530. #endif
  531. 1: ldr r1, [r12, #0] @ get value
  532. ldr r2, [r12, #4] @ get mask
  533. eor r1, r1, r6 @ (real ^ match)
  534. tst r1, r2 @ & mask
  535. ARM( addeq pc, r12, r3 ) @ call cache function
  536. THUMB( addeq r12, r3 )
  537. THUMB( moveq pc, r12 ) @ call cache function
  538. add r12, r12, #4*5
  539. b 1b
  540. /*
  541. * Table for cache operations. This is basically:
  542. * - CPU ID match
  543. * - CPU ID mask
  544. * - 'cache on' method instruction
  545. * - 'cache off' method instruction
  546. * - 'cache flush' method instruction
  547. *
  548. * We match an entry using: ((real_id ^ match) & mask) == 0
  549. *
  550. * Writethrough caches generally only need 'on' and 'off'
  551. * methods. Writeback caches _must_ have the flush method
  552. * defined.
  553. */
  554. .align 2
  555. .type proc_types,#object
  556. proc_types:
  557. .word 0x41560600 @ ARM6/610
  558. .word 0xffffffe0
  559. W(b) __arm6_mmu_cache_off @ works, but slow
  560. W(b) __arm6_mmu_cache_off
  561. mov pc, lr
  562. THUMB( nop )
  563. @ b __arm6_mmu_cache_on @ untested
  564. @ b __arm6_mmu_cache_off
  565. @ b __armv3_mmu_cache_flush
  566. .word 0x00000000 @ old ARM ID
  567. .word 0x0000f000
  568. mov pc, lr
  569. THUMB( nop )
  570. mov pc, lr
  571. THUMB( nop )
  572. mov pc, lr
  573. THUMB( nop )
  574. .word 0x41007000 @ ARM7/710
  575. .word 0xfff8fe00
  576. W(b) __arm7_mmu_cache_off
  577. W(b) __arm7_mmu_cache_off
  578. mov pc, lr
  579. THUMB( nop )
  580. .word 0x41807200 @ ARM720T (writethrough)
  581. .word 0xffffff00
  582. W(b) __armv4_mmu_cache_on
  583. W(b) __armv4_mmu_cache_off
  584. mov pc, lr
  585. THUMB( nop )
  586. .word 0x41007400 @ ARM74x
  587. .word 0xff00ff00
  588. W(b) __armv3_mpu_cache_on
  589. W(b) __armv3_mpu_cache_off
  590. W(b) __armv3_mpu_cache_flush
  591. .word 0x41009400 @ ARM94x
  592. .word 0xff00ff00
  593. W(b) __armv4_mpu_cache_on
  594. W(b) __armv4_mpu_cache_off
  595. W(b) __armv4_mpu_cache_flush
  596. .word 0x00007000 @ ARM7 IDs
  597. .word 0x0000f000
  598. mov pc, lr
  599. THUMB( nop )
  600. mov pc, lr
  601. THUMB( nop )
  602. mov pc, lr
  603. THUMB( nop )
  604. @ Everything from here on will be the new ID system.
  605. .word 0x4401a100 @ sa110 / sa1100
  606. .word 0xffffffe0
  607. W(b) __armv4_mmu_cache_on
  608. W(b) __armv4_mmu_cache_off
  609. W(b) __armv4_mmu_cache_flush
  610. .word 0x6901b110 @ sa1110
  611. .word 0xfffffff0
  612. W(b) __armv4_mmu_cache_on
  613. W(b) __armv4_mmu_cache_off
  614. W(b) __armv4_mmu_cache_flush
  615. .word 0x56056930
  616. .word 0xff0ffff0 @ PXA935
  617. W(b) __armv4_mmu_cache_on
  618. W(b) __armv4_mmu_cache_off
  619. W(b) __armv4_mmu_cache_flush
  620. .word 0x56158000 @ PXA168
  621. .word 0xfffff000
  622. W(b) __armv4_mmu_cache_on
  623. W(b) __armv4_mmu_cache_off
  624. W(b) __armv5tej_mmu_cache_flush
  625. .word 0x56056930
  626. .word 0xff0ffff0 @ PXA935
  627. W(b) __armv4_mmu_cache_on
  628. W(b) __armv4_mmu_cache_off
  629. W(b) __armv4_mmu_cache_flush
  630. .word 0x56050000 @ Feroceon
  631. .word 0xff0f0000
  632. W(b) __armv4_mmu_cache_on
  633. W(b) __armv4_mmu_cache_off
  634. W(b) __armv5tej_mmu_cache_flush
  635. #ifdef CONFIG_CPU_FEROCEON_OLD_ID
  636. /* this conflicts with the standard ARMv5TE entry */
  637. .long 0x41009260 @ Old Feroceon
  638. .long 0xff00fff0
  639. b __armv4_mmu_cache_on
  640. b __armv4_mmu_cache_off
  641. b __armv5tej_mmu_cache_flush
  642. #endif
  643. .word 0x66015261 @ FA526
  644. .word 0xff01fff1
  645. W(b) __fa526_cache_on
  646. W(b) __armv4_mmu_cache_off
  647. W(b) __fa526_cache_flush
  648. @ These match on the architecture ID
  649. .word 0x00020000 @ ARMv4T
  650. .word 0x000f0000
  651. W(b) __armv4_mmu_cache_on
  652. W(b) __armv4_mmu_cache_off
  653. W(b) __armv4_mmu_cache_flush
  654. .word 0x00050000 @ ARMv5TE
  655. .word 0x000f0000
  656. W(b) __armv4_mmu_cache_on
  657. W(b) __armv4_mmu_cache_off
  658. W(b) __armv4_mmu_cache_flush
  659. .word 0x00060000 @ ARMv5TEJ
  660. .word 0x000f0000
  661. W(b) __armv4_mmu_cache_on
  662. W(b) __armv4_mmu_cache_off
  663. W(b) __armv4_mmu_cache_flush
  664. .word 0x0007b000 @ ARMv6
  665. .word 0x000ff000
  666. W(b) __armv4_mmu_cache_on
  667. W(b) __armv4_mmu_cache_off
  668. W(b) __armv6_mmu_cache_flush
  669. .word 0x000f0000 @ new CPU Id
  670. .word 0x000f0000
  671. W(b) __armv7_mmu_cache_on
  672. W(b) __armv7_mmu_cache_off
  673. W(b) __armv7_mmu_cache_flush
  674. .word 0 @ unrecognised type
  675. .word 0
  676. mov pc, lr
  677. THUMB( nop )
  678. mov pc, lr
  679. THUMB( nop )
  680. mov pc, lr
  681. THUMB( nop )
  682. .size proc_types, . - proc_types
  683. /*
  684. * Turn off the Cache and MMU. ARMv3 does not support
  685. * reading the control register, but ARMv4 does.
  686. *
  687. * On entry, r6 = processor ID
  688. * On exit, r0, r1, r2, r3, r12 corrupted
  689. * This routine must preserve: r4, r6, r7
  690. */
  691. .align 5
  692. cache_off: mov r3, #12 @ cache_off function
  693. b call_cache_fn
  694. __armv4_mpu_cache_off:
  695. mrc p15, 0, r0, c1, c0
  696. bic r0, r0, #0x000d
  697. mcr p15, 0, r0, c1, c0 @ turn MPU and cache off
  698. mov r0, #0
  699. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
  700. mcr p15, 0, r0, c7, c6, 0 @ flush D-Cache
  701. mcr p15, 0, r0, c7, c5, 0 @ flush I-Cache
  702. mov pc, lr
  703. __armv3_mpu_cache_off:
  704. mrc p15, 0, r0, c1, c0
  705. bic r0, r0, #0x000d
  706. mcr p15, 0, r0, c1, c0, 0 @ turn MPU and cache off
  707. mov r0, #0
  708. mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
  709. mov pc, lr
  710. __armv4_mmu_cache_off:
  711. #ifdef CONFIG_MMU
  712. mrc p15, 0, r0, c1, c0
  713. bic r0, r0, #0x000d
  714. mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
  715. mov r0, #0
  716. mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4
  717. mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4
  718. #endif
  719. mov pc, lr
  720. __armv7_mmu_cache_off:
  721. mrc p15, 0, r0, c1, c0
  722. #ifdef CONFIG_MMU
  723. bic r0, r0, #0x000d
  724. #else
  725. bic r0, r0, #0x000c
  726. #endif
  727. mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
  728. mov r12, lr
  729. bl __armv7_mmu_cache_flush
  730. mov r0, #0
  731. #ifdef CONFIG_MMU
  732. mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB
  733. #endif
  734. mcr p15, 0, r0, c7, c5, 6 @ invalidate BTC
  735. mcr p15, 0, r0, c7, c10, 4 @ DSB
  736. mcr p15, 0, r0, c7, c5, 4 @ ISB
  737. mov pc, r12
  738. __arm6_mmu_cache_off:
  739. mov r0, #0x00000030 @ ARM6 control reg.
  740. b __armv3_mmu_cache_off
  741. __arm7_mmu_cache_off:
  742. mov r0, #0x00000070 @ ARM7 control reg.
  743. b __armv3_mmu_cache_off
  744. __armv3_mmu_cache_off:
  745. mcr p15, 0, r0, c1, c0, 0 @ turn MMU and cache off
  746. mov r0, #0
  747. mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
  748. mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
  749. mov pc, lr
  750. /*
  751. * Clean and flush the cache to maintain consistency.
  752. *
  753. * On entry,
  754. * r6 = processor ID
  755. * On exit,
  756. * r1, r2, r3, r11, r12 corrupted
  757. * This routine must preserve:
  758. * r0, r4, r5, r6, r7
  759. */
  760. .align 5
  761. cache_clean_flush:
  762. mov r3, #16
  763. b call_cache_fn
  764. __armv4_mpu_cache_flush:
  765. mov r2, #1
  766. mov r3, #0
  767. mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
  768. mov r1, #7 << 5 @ 8 segments
  769. 1: orr r3, r1, #63 << 26 @ 64 entries
  770. 2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index
  771. subs r3, r3, #1 << 26
  772. bcs 2b @ entries 63 to 0
  773. subs r1, r1, #1 << 5
  774. bcs 1b @ segments 7 to 0
  775. teq r2, #0
  776. mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
  777. mcr p15, 0, ip, c7, c10, 4 @ drain WB
  778. mov pc, lr
  779. __fa526_cache_flush:
  780. mov r1, #0
  781. mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache
  782. mcr p15, 0, r1, c7, c5, 0 @ flush I cache
  783. mcr p15, 0, r1, c7, c10, 4 @ drain WB
  784. mov pc, lr
  785. __armv6_mmu_cache_flush:
  786. mov r1, #0
  787. mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D
  788. mcr p15, 0, r1, c7, c5, 0 @ invalidate I+BTB
  789. mcr p15, 0, r1, c7, c15, 0 @ clean+invalidate unified
  790. mcr p15, 0, r1, c7, c10, 4 @ drain WB
  791. mov pc, lr
  792. __armv7_mmu_cache_flush:
  793. mrc p15, 0, r10, c0, c1, 5 @ read ID_MMFR1
  794. tst r10, #0xf << 16 @ hierarchical cache (ARMv7)
  795. mov r10, #0
  796. beq hierarchical
  797. mcr p15, 0, r10, c7, c14, 0 @ clean+invalidate D
  798. b iflush
  799. hierarchical:
  800. mcr p15, 0, r10, c7, c10, 5 @ DMB
  801. stmfd sp!, {r0-r7, r9-r11}
  802. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  803. ands r3, r0, #0x7000000 @ extract loc from clidr
  804. mov r3, r3, lsr #23 @ left align loc bit field
  805. beq finished @ if loc is 0, then no need to clean
  806. mov r10, #0 @ start clean at cache level 0
  807. loop1:
  808. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  809. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  810. and r1, r1, #7 @ mask of the bits for current cache only
  811. cmp r1, #2 @ see what cache we have at this level
  812. blt skip @ skip if no cache, or just i-cache
  813. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  814. mcr p15, 0, r10, c7, c5, 4 @ isb to sych the new cssr&csidr
  815. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  816. and r2, r1, #7 @ extract the length of the cache lines
  817. add r2, r2, #4 @ add 4 (line length offset)
  818. ldr r4, =0x3ff
  819. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  820. clz r5, r4 @ find bit position of way size increment
  821. ldr r7, =0x7fff
  822. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  823. loop2:
  824. mov r9, r4 @ create working copy of max way size
  825. loop3:
  826. ARM( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
  827. ARM( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
  828. THUMB( lsl r6, r9, r5 )
  829. THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
  830. THUMB( lsl r6, r7, r2 )
  831. THUMB( orr r11, r11, r6 ) @ factor index number into r11
  832. mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
  833. subs r9, r9, #1 @ decrement the way
  834. bge loop3
  835. subs r7, r7, #1 @ decrement the index
  836. bge loop2
  837. skip:
  838. add r10, r10, #2 @ increment cache number
  839. cmp r3, r10
  840. bgt loop1
  841. finished:
  842. ldmfd sp!, {r0-r7, r9-r11}
  843. mov r10, #0 @ swith back to cache level 0
  844. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  845. iflush:
  846. mcr p15, 0, r10, c7, c10, 4 @ DSB
  847. mcr p15, 0, r10, c7, c5, 0 @ invalidate I+BTB
  848. mcr p15, 0, r10, c7, c10, 4 @ DSB
  849. mcr p15, 0, r10, c7, c5, 4 @ ISB
  850. mov pc, lr
  851. __armv5tej_mmu_cache_flush:
  852. 1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate D cache
  853. bne 1b
  854. mcr p15, 0, r0, c7, c5, 0 @ flush I cache
  855. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  856. mov pc, lr
  857. __armv4_mmu_cache_flush:
  858. mov r2, #64*1024 @ default: 32K dcache size (*2)
  859. mov r11, #32 @ default: 32 byte line size
  860. mrc p15, 0, r3, c0, c0, 1 @ read cache type
  861. teq r3, r6 @ cache ID register present?
  862. beq no_cache_id
  863. mov r1, r3, lsr #18
  864. and r1, r1, #7
  865. mov r2, #1024
  866. mov r2, r2, lsl r1 @ base dcache size *2
  867. tst r3, #1 << 14 @ test M bit
  868. addne r2, r2, r2, lsr #1 @ +1/2 size if M == 1
  869. mov r3, r3, lsr #12
  870. and r3, r3, #3
  871. mov r11, #8
  872. mov r11, r11, lsl r3 @ cache line size in bytes
  873. no_cache_id:
  874. mov r1, pc
  875. bic r1, r1, #63 @ align to longest cache line
  876. add r2, r1, r2
  877. 1:
  878. ARM( ldr r3, [r1], r11 ) @ s/w flush D cache
  879. THUMB( ldr r3, [r1] ) @ s/w flush D cache
  880. THUMB( add r1, r1, r11 )
  881. teq r1, r2
  882. bne 1b
  883. mcr p15, 0, r1, c7, c5, 0 @ flush I cache
  884. mcr p15, 0, r1, c7, c6, 0 @ flush D cache
  885. mcr p15, 0, r1, c7, c10, 4 @ drain WB
  886. mov pc, lr
  887. __armv3_mmu_cache_flush:
  888. __armv3_mpu_cache_flush:
  889. mov r1, #0
  890. mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
  891. mov pc, lr
  892. /*
  893. * Various debugging routines for printing hex characters and
  894. * memory, which again must be relocatable.
  895. */
  896. #ifdef DEBUG
  897. .align 2
  898. .type phexbuf,#object
  899. phexbuf: .space 12
  900. .size phexbuf, . - phexbuf
  901. phex: adr r3, phexbuf
  902. mov r2, #0
  903. strb r2, [r3, r1]
  904. 1: subs r1, r1, #1
  905. movmi r0, r3
  906. bmi puts
  907. and r2, r0, #15
  908. mov r0, r0, lsr #4
  909. cmp r2, #10
  910. addge r2, r2, #7
  911. add r2, r2, #'0'
  912. strb r2, [r3, r1]
  913. b 1b
  914. puts: loadsp r3
  915. 1: ldrb r2, [r0], #1
  916. teq r2, #0
  917. moveq pc, lr
  918. 2: writeb r2, r3
  919. mov r1, #0x00020000
  920. 3: subs r1, r1, #1
  921. bne 3b
  922. teq r2, #'\n'
  923. moveq r2, #'\r'
  924. beq 2b
  925. teq r0, #0
  926. bne 1b
  927. mov pc, lr
  928. putc:
  929. mov r2, r0
  930. mov r0, #0
  931. loadsp r3
  932. b 2b
  933. memdump: mov r12, r0
  934. mov r10, lr
  935. mov r11, #0
  936. 2: mov r0, r11, lsl #2
  937. add r0, r0, r12
  938. mov r1, #8
  939. bl phex
  940. mov r0, #':'
  941. bl putc
  942. 1: mov r0, #' '
  943. bl putc
  944. ldr r0, [r12, r11, lsl #2]
  945. mov r1, #8
  946. bl phex
  947. and r0, r11, #7
  948. teq r0, #3
  949. moveq r0, #' '
  950. bleq putc
  951. and r0, r11, #7
  952. add r11, r11, #1
  953. teq r0, #7
  954. bne 1b
  955. mov r0, #'\n'
  956. bl putc
  957. cmp r11, #64
  958. blt 2b
  959. mov pc, r10
  960. #endif
  961. .ltorg
  962. reloc_end:
  963. .align
  964. .section ".stack", "w"
  965. user_stack: .space 4096