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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/arm/mm/proc-sa110.S
  3.  *
  4.  *  Copyright (C) 1997-2000 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.  *  MMU functions for SA110
  11.  *
  12.  *  These are the low level assembler for performing cache and TLB
  13.  *  functions on the StrongARM-110, StrongARM-1100 and StrongARM-1110.
  14.  * 
  15.  *  Note that SA1100 and SA1110 share everything but their name and CPU ID.
  16.  *
  17.  *  12-jun-2000, Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
  18.  *    Flush the read buffer at context switches
  19.  */
  20. #include <linux/linkage.h>
  21. #include <asm/assembler.h>
  22. #include <asm/constants.h>
  23. #include <asm/procinfo.h>
  24. #include <asm/hardware.h>
  25. /* This is the maximum size of an area which will be flushed.  If the area
  26.  * is larger than this, then we flush the whole cache
  27.  */
  28. #define MAX_AREA_SIZE 32768
  29. /*
  30.  * the cache line size of the I and D cache
  31.  */
  32. #define DCACHELINESIZE 32
  33. /*
  34.  * and the page size
  35.  */
  36. #define PAGESIZE 4096
  37. #define FLUSH_OFFSET 32768
  38. .macro flush_110_dcache rd, ra, re
  39. add re, ra, #16384 @ only necessary for 16k
  40. 1001: ldr rd, [ra], #DCACHELINESIZE
  41. teq re, ra
  42. bne 1001b
  43. .endm
  44. .macro flush_1100_dcache rd, ra, re
  45. add re, ra, #8192 @ only necessary for 8k
  46. 1001: ldr rd, [ra], #DCACHELINESIZE
  47. teq re, ra
  48. bne 1001b
  49. #ifdef FLUSH_BASE_MINICACHE
  50. add ra, ra, #FLUSH_BASE_MINICACHE - FLUSH_BASE
  51. add re, ra, #512 @ only 512 bytes
  52. 1002: ldr rd, [ra], #DCACHELINESIZE
  53. teq re, ra
  54. bne 1002b
  55. #endif
  56. .endm
  57. .data
  58. Lclean_switch: .long 0
  59. .text
  60. /*
  61.  * cpu_sa110_data_abort()
  62.  *
  63.  * obtain information about current aborted instruction.
  64.  * Note: we read user space.  This means we might cause a data
  65.  * abort here if the I-TLB and D-TLB aren't seeing the same
  66.  * picture.  Unfortunately, this does happen.  We live with it.
  67.  *
  68.  *  r2 = address of aborted instruction
  69.  *  r3 = cpsr
  70.  *
  71.  * Returns:
  72.  *  r0 = address of abort
  73.  *  r1 != 0 if writing
  74.  *  r3 = FSR
  75.  *  r4 = corrupted
  76.  */
  77. .align 5
  78. ENTRY(cpu_sa110_data_abort)
  79. ENTRY(cpu_sa1100_data_abort)
  80. mrc p15, 0, r3, c5, c0, 0 @ get FSR
  81. mrc p15, 0, r0, c6, c0, 0 @ get FAR
  82. ldr r1, [r2] @ read aborted instruction
  83. and r3, r3, #255
  84. tst r1, r1, lsr #21 @ C = bit 20
  85. sbc r1, r1, r1 @ r1 = C - 1
  86. mov pc, lr
  87. /*
  88.  * cpu_sa110_check_bugs()
  89.  */
  90. ENTRY(cpu_sa110_check_bugs)
  91. ENTRY(cpu_sa1100_check_bugs)
  92. mrs ip, cpsr
  93. bic ip, ip, #F_BIT
  94. msr cpsr, ip
  95. mov pc, lr
  96. /*
  97.  * cpu_sa110_proc_init()
  98.  */
  99. ENTRY(cpu_sa110_proc_init)
  100. ENTRY(cpu_sa1100_proc_init)
  101. mov r0, #0
  102. mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching
  103. mov pc, lr
  104. /*
  105.  * cpu_sa110_proc_fin()
  106.  */
  107. ENTRY(cpu_sa110_proc_fin)
  108. stmfd sp!, {lr}
  109. mov ip, #F_BIT | I_BIT | SVC_MODE
  110. msr cpsr_c, ip
  111. bl cpu_sa110_cache_clean_invalidate_all @ clean caches
  112. 1: mov r0, #0
  113. mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching
  114. mrc p15, 0, r0, c1, c0, 0 @ ctrl register
  115. bic r0, r0, #0x1000 @ ...i............
  116. bic r0, r0, #0x000e @ ............wca.
  117. mcr p15, 0, r0, c1, c0, 0 @ disable caches
  118. ldmfd sp!, {pc}
  119. ENTRY(cpu_sa1100_proc_fin)
  120. stmfd sp!, {lr}
  121. mov ip, #F_BIT | I_BIT | SVC_MODE
  122. msr cpsr_c, ip
  123. bl cpu_sa1100_cache_clean_invalidate_all @ clean caches
  124. b 1b
  125. /*
  126.  * cpu_sa110_reset(loc)
  127.  *
  128.  * Perform a soft reset of the system.  Put the CPU into the
  129.  * same state as it would be if it had been reset, and branch
  130.  * to what would be the reset vector.
  131.  *
  132.  * loc: location to jump to for soft reset
  133.  */
  134. .align 5
  135. ENTRY(cpu_sa110_reset)
  136. ENTRY(cpu_sa1100_reset)
  137. mov ip, #0
  138. mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
  139. mcr p15, 0, ip, c7, c10, 4 @ drain WB
  140. mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
  141. mrc p15, 0, ip, c1, c0, 0 @ ctrl register
  142. bic ip, ip, #0x000f @ ............wcam
  143. bic ip, ip, #0x1100 @ ...i...s........
  144. mcr p15, 0, ip, c1, c0, 0 @ ctrl register
  145. mov pc, r0
  146. /*
  147.  * cpu_sa110_do_idle(type)
  148.  *
  149.  * Cause the processor to idle
  150.  *
  151.  * type: call type:
  152.  *   0 = slow idle
  153.  *   1 = fast idle
  154.  *   2 = switch to slow processor clock
  155.  *   3 = switch to fast processor clock
  156.  */
  157. .align 5
  158. idle: mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt, cache aligned
  159. mov r0, r0 @ safety
  160. mov pc, lr
  161. ENTRY(cpu_sa110_do_idle)
  162. mov ip, #0
  163. cmp r0, #4
  164. addcc pc, pc, r0, lsl #2
  165. mov pc, lr
  166. b idle
  167. b idle
  168. b slow_clock
  169. b fast_clock
  170. fast_clock:
  171. mcr p15, 0, ip, c15, c1, 2 @ enable clock switching
  172. mov pc, lr
  173. slow_clock:
  174. mcr p15, 0, ip, c15, c2, 2 @ disable clock switching
  175. ldr r1, =UNCACHEABLE_ADDR @ load from uncacheable loc
  176. ldr r1, [r1, #0] @ force switch to MCLK
  177. mov pc, lr
  178. .align 5
  179. ENTRY(cpu_sa1100_do_idle)
  180. mov r0, r0 @ 4 nop padding
  181. mov r0, r0
  182. mov r0, r0
  183. mov r0, #0
  184. ldr r1, =UNCACHEABLE_ADDR @ ptr to uncacheable address
  185. mrs r2, cpsr
  186. orr r3, r2, #192 @ disallow interrupts
  187. msr cpsr_c, r3
  188. @ --- aligned to a cache line
  189. mcr p15, 0, r0, c15, c2, 2 @ disable clock switching
  190. ldr r1, [r1, #0] @ force switch to MCLK
  191. mcr p15, 0, r0, c15, c8, 2 @ wait for interrupt
  192. mov r0, r0 @ safety
  193. mcr p15, 0, r0, c15, c1, 2 @ enable clock switching
  194. msr cpsr_c, r2 @ allow interrupts
  195. mov pc, lr
  196. /* ================================= CACHE ================================ */
  197. /*
  198.  * cpu_sa110_cache_clean_invalidate_all (void)
  199.  *
  200.  * clean and invalidate all cache lines
  201.  *
  202.  * Note:
  203.  *  1. we should preserve r0 at all times
  204.  */
  205. .align 5
  206. ENTRY(cpu_sa110_cache_clean_invalidate_all)
  207. mov r2, #1
  208. cpu_sa110_cache_clean_invalidate_all_r2:
  209. ldr r3, =Lclean_switch
  210. ldr ip, =FLUSH_BASE
  211. ldr r1, [r3]
  212. ands r1, r1, #1
  213. eor r1, r1, #1
  214. str r1, [r3]
  215. addne ip, ip, #FLUSH_OFFSET
  216. flush_110_dcache r3, ip, r1
  217. mov ip, #0
  218. teq r2, #0
  219. mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
  220. mcr p15, 0, ip, c7, c10, 4 @ drain WB
  221. mov pc, lr
  222. .align 5
  223. ENTRY(cpu_sa1100_cache_clean_invalidate_all)
  224. mov r2, #1
  225. cpu_sa1100_cache_clean_invalidate_all_r2:
  226. ldr r3, =Lclean_switch
  227. ldr ip, =FLUSH_BASE
  228. ldr r1, [r3]
  229. ands r1, r1, #1
  230. eor r1, r1, #1
  231. str r1, [r3]
  232. addne ip, ip, #FLUSH_OFFSET
  233. flush_1100_dcache r3, ip, r1
  234. mov ip, #0
  235. teq r2, #0
  236. mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
  237. mcr p15, 0, r1, c9, c0, 0 @ invalidate RB
  238. mcr p15, 0, ip, c7, c10, 4 @ drain WB
  239. mov pc, lr
  240. /*
  241.  * cpu_sa110_cache_clean_invalidate_range(start, end, flags)
  242.  *
  243.  * clean and invalidate all cache lines associated with this area of memory
  244.  *
  245.  * start: Area start address
  246.  * end:   Area end address
  247.  * flags: nonzero for I cache as well
  248.  */
  249. .align 5
  250. ENTRY(cpu_sa110_cache_clean_invalidate_range)
  251. bic r0, r0, #DCACHELINESIZE - 1
  252. sub r3, r1, r0
  253. cmp r3, #MAX_AREA_SIZE
  254. bhi cpu_sa110_cache_clean_invalidate_all_r2
  255. 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  256. mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
  257. add r0, r0, #DCACHELINESIZE
  258. mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  259. mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
  260. add r0, r0, #DCACHELINESIZE
  261. cmp r0, r1
  262. blo 1b
  263. teq r2, #0
  264. movne r0, #0
  265. mcrne p15, 0, r0, c7, c5, 0 @ invalidate I cache
  266. mov pc, lr
  267. ENTRY(cpu_sa1100_cache_clean_invalidate_range)
  268. sub r3, r1, r0
  269. cmp r3, #MAX_AREA_SIZE
  270. bhi cpu_sa1100_cache_clean_invalidate_all_r2
  271. b 1b
  272. /*
  273.  * cpu_sa110_flush_ram_page(page)
  274.  *
  275.  * clean and invalidate all cache lines associated with this area of memory
  276.  *
  277.  * page: page to clean and invalidate
  278.  */
  279. .align 5
  280. ENTRY(cpu_sa110_flush_ram_page)
  281. ENTRY(cpu_sa1100_flush_ram_page)
  282. mov r1, #PAGESIZE
  283. 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  284. add r0, r0, #DCACHELINESIZE
  285. mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  286. add r0, r0, #DCACHELINESIZE
  287. subs r1, r1, #2 * DCACHELINESIZE
  288. bne 1b
  289. mcr p15, 0, r1, c7, c10, 4 @ drain WB
  290. mov pc, lr
  291. /* ================================ D-CACHE =============================== */
  292. /*
  293.  * cpu_sa110_dcache_invalidate_range(start, end)
  294.  *
  295.  * throw away all D-cached data in specified region without an obligation
  296.  * to write them back.  Note however that we must clean the D-cached entries
  297.  * around the boundaries if the start and/or end address are not cache
  298.  * aligned.
  299.  *
  300.  * start: virtual start address
  301.  * end:   virtual end address
  302.  */
  303. .align 5
  304. ENTRY(cpu_sa110_dcache_invalidate_range)
  305. ENTRY(cpu_sa1100_dcache_invalidate_range)
  306. tst r0, #DCACHELINESIZE - 1
  307. bic r0, r0, #DCACHELINESIZE - 1
  308. mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
  309. tst r1, #DCACHELINESIZE - 1
  310. mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
  311. 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
  312. add r0, r0, #DCACHELINESIZE
  313. cmp r0, r1
  314. blo 1b
  315. mov pc, lr
  316. /*
  317.  * cpu_sa110_dcache_clean_range(start, end)
  318.  *
  319.  * For the specified virtual address range, ensure that all caches contain
  320.  * clean data, such that peripheral accesses to the physical RAM fetch
  321.  * correct data.
  322.  *
  323.  * start: virtual start address
  324.  * end:   virtual end address
  325.  */
  326. .align 5
  327. ENTRY(cpu_sa110_dcache_clean_range)
  328. bic r0, r0, #DCACHELINESIZE - 1
  329. sub r1, r1, r0
  330. cmp r1, #MAX_AREA_SIZE
  331. mov r2, #0
  332. bhi cpu_sa110_cache_clean_invalidate_all_r2
  333. 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  334. add r0, r0, #DCACHELINESIZE
  335. mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  336. add r0, r0, #DCACHELINESIZE
  337. subs r1, r1, #2 * DCACHELINESIZE
  338. bpl 1b
  339. mcr p15, 0, r2, c7, c10, 4 @ drain WB
  340. mov pc, lr
  341. ENTRY(cpu_sa1100_dcache_clean_range)
  342. bic r0, r0, #DCACHELINESIZE - 1
  343. sub r1, r1, r0
  344. cmp r1, #MAX_AREA_SIZE
  345. mov r2, #0
  346. bhi cpu_sa1100_cache_clean_invalidate_all_r2
  347. b 1b
  348. /*
  349.  * cpu_sa110_clean_dcache_page(page)
  350.  *
  351.  * Cleans a single page of dcache so that if we have any future aliased
  352.  * mappings, they will be consistent at the time that they are created.
  353.  *
  354.  * Note:
  355.  *  1. we don't need to flush the write buffer in this case.
  356.  *  2. we don't invalidate the entries since when we write the page
  357.  *     out to disk, the entries may get reloaded into the cache.
  358.  */
  359. .align 5
  360. ENTRY(cpu_sa110_dcache_clean_page)
  361. ENTRY(cpu_sa1100_dcache_clean_page)
  362. mov r1, #PAGESIZE
  363. 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  364. add r0, r0, #DCACHELINESIZE
  365. mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  366. add r0, r0, #DCACHELINESIZE
  367. subs r1, r1, #2 * DCACHELINESIZE
  368. bne 1b
  369. mov pc, lr
  370. /*
  371.  * cpu_sa110_dcache_clean_entry(addr)
  372.  *
  373.  * Clean the specified entry of any caches such that the MMU
  374.  * translation fetches will obtain correct data.
  375.  *
  376.  * addr: cache-unaligned virtual address
  377.  */
  378. .align 5
  379. ENTRY(cpu_sa110_dcache_clean_entry)
  380. ENTRY(cpu_sa1100_dcache_clean_entry)
  381. mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  382. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  383. mov pc, lr
  384. /* ================================ I-CACHE =============================== */
  385. /*
  386.  * cpu_sa110_icache_invalidate_range(start, end)
  387.  *
  388.  * invalidate a range of virtual addresses from the Icache
  389.  *
  390.  * start: virtual start address
  391.  * end:   virtual end address
  392.  */
  393. .align 5
  394. ENTRY(cpu_sa110_icache_invalidate_range)
  395. ENTRY(cpu_sa1100_icache_invalidate_range)
  396. bic r0, r0, #DCACHELINESIZE - 1
  397. 1: mcr p15, 0, r0, c7, c10, 1 @ Clean D entry
  398. add r0, r0, #DCACHELINESIZE
  399. cmp r0, r1
  400. blo 1b
  401. mov r0, #0
  402. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  403. ENTRY(cpu_sa110_icache_invalidate_page)
  404. ENTRY(cpu_sa1100_icache_invalidate_page)
  405. mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
  406. mov pc, lr
  407. /* ================================== TLB ================================= */
  408. /*
  409.  * cpu_sa110_tlb_invalidate_all()
  410.  *
  411.  * Invalidate all TLB entries
  412.  */
  413. .align 5
  414. ENTRY(cpu_sa110_tlb_invalidate_all)
  415. ENTRY(cpu_sa1100_tlb_invalidate_all)
  416. mov r0, #0
  417. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  418. mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D TLBs
  419. mov pc, lr
  420. /*
  421.  * cpu_sa110_tlb_invalidate_range(start, end)
  422.  *
  423.  * invalidate TLB entries covering the specified range
  424.  *
  425.  * start: range start address
  426.  * end:   range end address
  427.  */
  428. .align 5
  429. ENTRY(cpu_sa110_tlb_invalidate_range)
  430. ENTRY(cpu_sa1100_tlb_invalidate_range)
  431. bic r0, r0, #0x0ff
  432. bic r0, r0, #0xf00
  433. sub r3, r1, r0
  434. cmp r3, #256 * PAGESIZE @ arbitary, should be tuned
  435. bhi cpu_sa110_tlb_invalidate_all
  436. mov r3, #0
  437. mcr p15, 0, r3, c7, c10, 4 @ drain WB
  438. 1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
  439. add r0, r0, #PAGESIZE
  440. cmp r0, r1
  441. blo 1b
  442. mcr p15, 0, r3, c8, c5, 0 @ invalidate I TLB
  443. mov pc, lr
  444. /*
  445.  * cpu_sa110_tlb_invalidate_page(page, flags)
  446.  *
  447.  * invalidate the TLB entries for the specified page.
  448.  *
  449.  * page:  page to invalidate
  450.  * flags: non-zero if we include the I TLB
  451.  */
  452. .align 5
  453. ENTRY(cpu_sa110_tlb_invalidate_page)
  454. ENTRY(cpu_sa1100_tlb_invalidate_page)
  455. mov r3, #0
  456. mcr p15, 0, r3, c7, c10, 4 @ drain WB
  457. teq r1, #0
  458. mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
  459. mcrne p15, 0, r3, c8, c5, 0 @ invalidate I TLB
  460. mov pc, lr
  461. /* =============================== PageTable ============================== */
  462. /*
  463.  * cpu_sa110_set_pgd(pgd)
  464.  *
  465.  * Set the translation base pointer to be as described by pgd.
  466.  *
  467.  * pgd: new page tables
  468.  */
  469. .align 5
  470. ENTRY(cpu_sa110_set_pgd)
  471. ldr r3, =Lclean_switch
  472. ldr ip, =FLUSH_BASE
  473. ldr r2, [r3]
  474. ands r2, r2, #1
  475. eor r2, r2, #1
  476. str r2, [r3]
  477. addne ip, ip, #FLUSH_OFFSET
  478. flush_110_dcache r3, ip, r1
  479. mov r1, #0
  480. mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
  481. mcr p15, 0, r1, c7, c10, 4 @ drain WB
  482. mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
  483. mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
  484. mov pc, lr
  485. /*
  486.  * cpu_sa1100_set_pgd(pgd)
  487.  *
  488.  * Set the translation base pointer to be as described by pgd.
  489.  *
  490.  * pgd: new page tables
  491.  */
  492. .align 5
  493. ENTRY(cpu_sa1100_set_pgd)
  494. ldr r3, =Lclean_switch
  495. ldr ip, =FLUSH_BASE
  496. ldr r2, [r3]
  497. ands r2, r2, #1
  498. eor r2, r2, #1
  499. str r2, [r3]
  500. addne ip, ip, #FLUSH_OFFSET
  501. flush_1100_dcache r3, ip, r1
  502. mov ip, #0
  503. mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
  504. mcr p15, 0, ip, c9, c0, 0 @ invalidate RB
  505. mcr p15, 0, ip, c7, c10, 4 @ drain WB
  506. mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
  507. mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
  508. mov pc, lr
  509. /*
  510.  * cpu_sa110_set_pmd(pmdp, pmd)
  511.  *
  512.  * Set a level 1 translation table entry, and clean it out of
  513.  * any caches such that the MMUs can load it correctly.
  514.  *
  515.  * pmdp: pointer to PMD entry
  516.  * pmd:  PMD value to store
  517.  */
  518. .align 5
  519. ENTRY(cpu_sa110_set_pmd)
  520. ENTRY(cpu_sa1100_set_pmd)
  521. str r1, [r0]
  522. mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  523. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  524. mov pc, lr
  525. /*
  526.  * cpu_sa110_set_pte(ptep, pte)
  527.  *
  528.  * Set a PTE and flush it out
  529.  */
  530. .align 5
  531. ENTRY(cpu_sa110_set_pte)
  532. ENTRY(cpu_sa1100_set_pte)
  533. str r1, [r0], #-1024 @ linux version
  534. eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
  535. bic r2, r1, #0xff0
  536. bic r2, r2, #3
  537. orr r2, r2, #HPTE_TYPE_SMALL
  538. tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
  539. orrne r2, r2, #HPTE_AP_READ
  540. tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
  541. orreq r2, r2, #HPTE_AP_WRITE
  542. tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young?
  543. movne r2, #0
  544. str r2, [r0] @ hardware version
  545. mov r0, r0
  546. mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  547. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  548. mov pc, lr
  549. cpu_manu_name:
  550. .asciz "Intel"
  551. cpu_sa110_name:
  552. .asciz "StrongARM-110"
  553. cpu_sa1100_name:
  554. .asciz "StrongARM-1100"
  555. cpu_sa1110_name:
  556. .asciz "StrongARM-1110"
  557. .align
  558. .section ".text.init", #alloc, #execinstr
  559. __sa1100_setup: @ Allow read-buffer operations from userland
  560. mcr p15, 0, r0, c9, c0, 5
  561. mrc p15, 0, r0, c1, c0 @ get control register v4
  562. bic r0, r0, #0x0e00 @ ..VI ZFRS BLDP WCAM
  563. bic r0, r0, #0x0002 @ .... 000. .... ..0.
  564. orr r0, r0, #0x003d
  565. orr r0, r0, #0x3100 @ ..11 ...1 ..11 11.1
  566. b __setup_common
  567. __sa110_setup:
  568. mrc p15, 0, r0, c1, c0 @ get control register v4
  569. bic r0, r0, #0x2e00 @ ..VI ZFRS BLDP WCAM
  570. bic r0, r0, #0x0002 @ ..0. 000. .... ..0.
  571. orr r0, r0, #0x003d
  572. orr r0, r0, #0x1100 @ ...1 ...1 ..11 11.1
  573. __setup_common:
  574. mov r10, #0
  575. mcr p15, 0, r10, c7, c7 @ invalidate I,D caches on v4
  576. mcr p15, 0, r10, c7, c10, 4 @ drain write buffer on v4
  577. mcr p15, 0, r10, c8, c7 @ invalidate I,D TLBs on v4
  578. mcr p15, 0, r4, c2, c0 @ load page table pointer
  579. mov r10, #0x1f @ Domains 0, 1 = client
  580. mcr p15, 0, r10, c3, c0 @ load domain access register
  581. mov pc, lr
  582. .text
  583. /*
  584.  * Purpose : Function pointers used to access above functions - all calls
  585.  *      come through these
  586.  */
  587. .type sa110_processor_functions, #object
  588. ENTRY(sa110_processor_functions)
  589. .word cpu_sa110_data_abort
  590. .word cpu_sa110_check_bugs
  591. .word cpu_sa110_proc_init
  592. .word cpu_sa110_proc_fin
  593. .word cpu_sa110_reset
  594. .word cpu_sa110_do_idle
  595. /* cache */
  596. .word cpu_sa110_cache_clean_invalidate_all
  597. .word cpu_sa110_cache_clean_invalidate_range
  598. .word cpu_sa110_flush_ram_page
  599. /* dcache */
  600. .word cpu_sa110_dcache_invalidate_range
  601. .word cpu_sa110_dcache_clean_range
  602. .word cpu_sa110_dcache_clean_page
  603. .word cpu_sa110_dcache_clean_entry
  604. /* icache */
  605. .word cpu_sa110_icache_invalidate_range
  606. .word cpu_sa110_icache_invalidate_page
  607. /* tlb */
  608. .word cpu_sa110_tlb_invalidate_all
  609. .word cpu_sa110_tlb_invalidate_range
  610. .word cpu_sa110_tlb_invalidate_page
  611. /* pgtable */
  612. .word cpu_sa110_set_pgd
  613. .word cpu_sa110_set_pmd
  614. .word cpu_sa110_set_pte
  615. .size sa110_processor_functions, . - sa110_processor_functions
  616. .type cpu_sa110_info, #object
  617. cpu_sa110_info:
  618. .long cpu_manu_name
  619. .long cpu_sa110_name
  620. .size cpu_sa110_info, . - cpu_sa110_info
  621. /*
  622.  * SA1100 and SA1110 share the same function calls
  623.  */
  624. .type sa1100_processor_functions, #object
  625. ENTRY(sa1100_processor_functions)
  626. .word cpu_sa1100_data_abort
  627. .word cpu_sa1100_check_bugs
  628. .word cpu_sa1100_proc_init
  629. .word cpu_sa1100_proc_fin
  630. .word cpu_sa1100_reset
  631. .word cpu_sa1100_do_idle
  632. /* cache */
  633. .word cpu_sa1100_cache_clean_invalidate_all
  634. .word cpu_sa1100_cache_clean_invalidate_range
  635. .word cpu_sa1100_flush_ram_page
  636. /* dcache */
  637. .word cpu_sa1100_dcache_invalidate_range
  638. .word cpu_sa1100_dcache_clean_range
  639. .word cpu_sa1100_dcache_clean_page
  640. .word cpu_sa1100_dcache_clean_entry
  641. /* icache */
  642. .word cpu_sa1100_icache_invalidate_range
  643. .word cpu_sa1100_icache_invalidate_page
  644. /* tlb */
  645. .word cpu_sa1100_tlb_invalidate_all
  646. .word cpu_sa1100_tlb_invalidate_range
  647. .word cpu_sa1100_tlb_invalidate_page
  648. /* pgtable */
  649. .word cpu_sa1100_set_pgd
  650. .word cpu_sa1100_set_pmd
  651. .word cpu_sa1100_set_pte
  652. .size sa1100_processor_functions, . - sa1100_processor_functions
  653. cpu_sa1100_info:
  654. .long cpu_manu_name
  655. .long cpu_sa1100_name
  656. .size cpu_sa1100_info, . - cpu_sa1100_info
  657. cpu_sa1110_info:
  658. .long cpu_manu_name
  659. .long cpu_sa1110_name
  660. .size cpu_sa1110_info, . - cpu_sa1110_info
  661. .type cpu_arch_name, #object
  662. cpu_arch_name:
  663. .asciz "armv4"
  664. .size cpu_arch_name, . - cpu_arch_name
  665. .type cpu_elf_name, #object
  666. cpu_elf_name:
  667. .asciz "v4"
  668. .size cpu_elf_name, . - cpu_elf_name
  669. .align
  670. .section ".proc.info", #alloc, #execinstr
  671. .type __sa110_proc_info,#object
  672. __sa110_proc_info:
  673. .long 0x4401a100
  674. .long 0xfffffff0
  675. .long 0x00000c0e
  676. b __sa110_setup
  677. .long cpu_arch_name
  678. .long cpu_elf_name
  679. .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
  680. .long cpu_sa110_info
  681. .long sa110_processor_functions
  682. .size __sa110_proc_info, . - __sa110_proc_info
  683. .type __sa1100_proc_info,#object
  684. __sa1100_proc_info:
  685. .long 0x4401a110
  686. .long 0xfffffff0
  687. .long 0x00000c0e
  688. b __sa1100_setup
  689. .long cpu_arch_name
  690. .long cpu_elf_name
  691. .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
  692. .long cpu_sa1100_info
  693. .long sa1100_processor_functions
  694. .size __sa1100_proc_info, . - __sa1100_proc_info
  695. .type __sa1110_proc_info,#object
  696. __sa1110_proc_info:
  697. .long 0x6901b110
  698. .long 0xfffffff0
  699. .long 0x00000c0e
  700. b __sa1100_setup
  701. .long cpu_arch_name
  702. .long cpu_elf_name
  703. .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
  704. .long cpu_sa1110_info
  705. .long sa1100_processor_functions
  706. .size __sa1110_proc_info, . - __sa1110_proc_info