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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/arm/mm/arm1020.S: MMU functions for ARM1020
  3.  *
  4.  *  Copyright (C) 2000 ARM Limited
  5.  *  Copyright (C) 2000 Deep Blue Solutions Ltd.
  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 as published by
  9.  * the Free Software Foundation; either version 2 of the License, or
  10.  * (at your option) any later version.
  11.  *
  12.  * This program is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  * GNU General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with this program; if not, write to the Free Software
  19.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20.  *
  21.  *
  22.  * These are the low level assembler for performing cache and TLB
  23.  * functions on the arm1020.
  24.  */
  25. #include <linux/linkage.h>
  26. #include <linux/config.h>
  27. #include <asm/assembler.h>
  28. #include <asm/constants.h>
  29. #include <asm/procinfo.h>
  30. #include <asm/hardware.h>
  31. /*
  32.  * This is the maximum size of an area which will be invalidated
  33.  * using the single invalidate entry instructions.  Anything larger
  34.  * than this, and we go for the whole cache.
  35.  *
  36.  * This value should be chosen such that we choose the cheapest
  37.  * alternative.
  38.  */
  39. #define MAX_AREA_SIZE 32768
  40. /*
  41.  * the cache line size of the I and D cache
  42.  */
  43. #define DCACHELINESIZE 32
  44. #define ICACHELINESIZE 32
  45. /*
  46.  * and the page size
  47.  */
  48. #define PAGESIZE 4096
  49. .text
  50. /*
  51.  * cpu_arm1020_data_abort()
  52.  *
  53.  * obtain information about current aborted instruction
  54.  * Note: we read user space.  This means we might cause a data
  55.  * abort here if the I-TLB and D-TLB aren't seeing the same
  56.  * picture.  Unfortunately, this does happen.  We live with it.
  57.  *
  58.  *  r2 = address of aborted instruction
  59.  *  r3 = cpsr
  60.  *
  61.  * Returns:
  62.  *  r0 = address of abort
  63.  *  r1 != 0 if writing
  64.  *  r3 = FSR
  65.  *  r4 = corrupted
  66.  */
  67. .align 5
  68. ENTRY(cpu_arm1020_data_abort)
  69. mrc p15, 0, r3, c5, c0, 0 @ get FSR
  70. mrc p15, 0, r0, c6, c0, 0 @ get FAR
  71. ldr r1, [r2] @ read aborted instruction
  72. and r3, r3, #255
  73. tst r1, r1, lsr #21  @ C = bit 20
  74. sbc r1, r1, r1 @ r1 = C - 1
  75. mov pc, lr
  76. /*
  77.  * cpu_arm1020_check_bugs()
  78.  */
  79. ENTRY(cpu_arm1020_check_bugs)
  80. mrs ip, cpsr
  81. bic ip, ip, #F_BIT
  82. msr cpsr, ip
  83. mov pc, lr
  84. /*
  85.  * cpu_arm1020_proc_init()
  86.  */
  87. ENTRY(cpu_arm1020_proc_init)
  88. mov pc, lr
  89. /*
  90.  * cpu_arm1020_proc_fin()
  91.  */
  92. ENTRY(cpu_arm1020_proc_fin)
  93. stmfd sp!, {lr}
  94. mov ip, #F_BIT | I_BIT | SVC_MODE
  95. msr cpsr_c, ip
  96. bl cpu_arm1020_cache_clean_invalidate_all
  97. mrc p15, 0, r0, c1, c0, 0 @ ctrl register
  98. bic r0, r0, #0x1000  @ ...i............
  99. bic r0, r0, #0x000e  @ ............wca.
  100. mcr p15, 0, r0, c1, c0, 0 @ disable caches
  101. ldmfd sp!, {pc}
  102. /*
  103.  * cpu_arm1020_reset(loc)
  104.  *
  105.  * Perform a soft reset of the system. Put the CPU into the
  106.  * same state as it would be if it had been reset, and branch
  107.  * to what would be the reset vector.
  108.  *
  109.  * loc: location to jump to for soft reset
  110.  */
  111. .align 5
  112. ENTRY(cpu_arm1020_reset)
  113. mov ip, #0
  114. mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
  115. mcr p15, 0, ip, c7, c10, 4 @ drain WB
  116. mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
  117. mrc p15, 0, ip, c1, c0, 0 @ ctrl register
  118. bic ip, ip, #0x000f  @ ............wcam
  119. bic ip, ip, #0x1100  @ ...i...s........
  120. mcr p15, 0, ip, c1, c0, 0 @ ctrl register
  121. mov pc, r0
  122. /*
  123.  * cpu_arm1020_do_idle()
  124.  */
  125. .align 5
  126. ENTRY(cpu_arm1020_do_idle)
  127. mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
  128. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  129. mov r0, r0
  130. mov r0, r0
  131. #endif
  132. mov pc, lr
  133. /* ================================= CACHE ================================ */
  134. /*
  135.  * cpu_arm1020_cache_clean_invalidate_all()
  136.  *
  137.  * clean and invalidate all cache lines
  138.  *
  139.  * Note:
  140.  *  1. we should preserve r0 at all times
  141.  */
  142. .align 5
  143. ENTRY(cpu_arm1020_cache_clean_invalidate_all)
  144. mov r2, #1
  145. cpu_arm1020_cache_clean_invalidate_all_r2:
  146. #ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
  147. mcr p15, 0, ip, c7, c10, 4
  148. mov r1, #0xf @ 16 segments
  149. 1: mov r3, #0x3F @ 64 entries
  150. 2: mov ip, r3, LSL #26  @ shift up entry
  151. orr ip, ip, r1, LSL #5 @ shift in/up index
  152. mcr p15, 0, ip, c7, c14, 2 @ Clean & Inval DCache entry
  153. mcr p15, 0, ip, c7, c10, 4 @ drain WB 
  154. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  155. mov ip, ip
  156. #endif
  157. subs r3, r3, #1
  158. cmp r3, #0
  159. bge 2b @ entries 3F to 0
  160. subs r1, r1, #1
  161. cmp r1, #0
  162. bge 1b @ segments 7 to 0
  163. #endif
  164.         
  165. #ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
  166. teq r2, #0
  167. mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
  168. #endif
  169. mcr p15, 0, ip, c7, c10, 4 @ drain WB
  170. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  171. mov ip, ip
  172. mov ip, ip
  173. #endif
  174. mov pc, lr
  175. /*
  176.  * cpu_arm1020_cache_clean_invalidate_range(start, end, flags)
  177.  *
  178.  * clean and invalidate all cache lines associated with this area of memory
  179.  *
  180.  * start: Area start address
  181.  * end:   Area end address
  182.  * flags: nonzero for I cache as well
  183.  */
  184. .align 5
  185. ENTRY(cpu_arm1020_cache_clean_invalidate_range)
  186. bic r0, r0, #DCACHELINESIZE - 1
  187. sub r3, r1, r0
  188. cmp r3, #MAX_AREA_SIZE
  189. bgt cpu_arm1020_cache_clean_invalidate_all_r2
  190. mcr p15, 0, r3, c7, c10, 4
  191. #ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
  192. 1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
  193. mcr p15, 0, r3, c7, c10, 4 @ drain WB
  194. add r0, r0, #DCACHELINESIZE
  195. mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
  196. mcr p15, 0, r3, c7, c10, 4 @ drain WB
  197. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  198. mov r0, r0
  199. #endif
  200. add r0, r0, #DCACHELINESIZE
  201. cmp r0, r1
  202. blt 1b
  203. #endif
  204. #ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
  205. teq r2, #0
  206. movne r0, #0
  207. mcrne p15, 0, r0, c7, c5, 0 @ invalidate I cache
  208. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  209. mov r0, r0
  210. mov r0, r0
  211. #endif
  212. #endif
  213. mov pc, lr
  214. /*
  215.  * cpu_arm1020_flush_ram_page(page)
  216.  *
  217.  * clean and invalidate all cache lines associated with this area of memory
  218.  *
  219.  * page: page to clean and invalidate
  220.  */
  221. .align 5
  222. ENTRY(cpu_arm1020_flush_ram_page)
  223. mcr p15, 0, r1, c7, c10, 4
  224. #ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
  225. mov r1, #PAGESIZE
  226. 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  227. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  228. add r0, r0, #DCACHELINESIZE
  229. mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  230. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  231. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  232. mov r0, r0
  233. mov r0, r0
  234. #endif
  235. subs r1, r1, #2 * DCACHELINESIZE
  236. bne 1b
  237. mov r0, #0
  238. #endif
  239. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  240. mov r0, r0
  241. mov r0, r0
  242. #endif
  243. mov pc, lr
  244. /* ================================ D-CACHE =============================== */
  245. /*
  246.  * cpu_arm1020_dcache_invalidate_range(start, end)
  247.  *
  248.  * throw away all D-cached data in specified region without an obligation
  249.  * to write them back. Note however that we must clean the D-cached entries
  250.  * around the boundaries if the start and/or end address are not cache
  251.  * aligned.
  252.  *
  253.  * start: virtual start address
  254.  * end:   virtual end address
  255.  */
  256. .align 5
  257. ENTRY(cpu_arm1020_dcache_invalidate_range)
  258. #ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
  259. /* D cache are on */
  260. tst r0, #DCACHELINESIZE - 1
  261. bic r0, r0, #DCACHELINESIZE - 1
  262. mcrne p15, 0, r0, c7, c10, 4
  263. mcrne p15, 0, r0, c7, c10, 1 @ clean D entry at start
  264. mcrne p15, 0, r0, c7, c10, 4 @ drain WB
  265. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  266. mov r0, r0
  267. mov r0, r0
  268. #endif
  269. tst r1, #DCACHELINESIZE - 1
  270. mcrne p15, 0, r1, c7, c10, 4
  271. mcrne p15, 0, r1, c7, c10, 1 @ clean D entry at end
  272. mcrne p15, 0, r1, c7, c10, 4 @ drain WB
  273. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  274. mov r1, r1
  275. mov r1, r1
  276. mov r1, r1
  277. #endif
  278.         
  279. 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
  280. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  281. mov r0, r0
  282. #endif
  283. add r0, r0, #DCACHELINESIZE
  284. cmp r0, r1
  285. blt 1b
  286. #else
  287. /* D cache off, but still drain the write buffer */
  288. mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer
  289. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  290. mov r0, r0
  291. mov r0, r0
  292. #endif
  293. #endif
  294. mov pc, lr
  295. /*
  296.  * cpu_arm1020_dcache_clean_range(start, end)
  297.  *
  298.  * For the specified virtual address range, ensure that all caches contain
  299.  * clean data, such that peripheral accesses to the physical RAM fetch
  300.  * correct data.
  301.  *
  302.  * start: virtual start address
  303.  * end:   virtual end address
  304.  */
  305. .align 5
  306. ENTRY(cpu_arm1020_dcache_clean_range)
  307. bic r0, r0, #DCACHELINESIZE - 1
  308. sub r3, r1, r0
  309. cmp r3, #MAX_AREA_SIZE
  310. bgt cpu_arm1020_cache_clean_invalidate_all_r2
  311. mcr p15, 0, r3, c7, c10, 4
  312. #ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
  313. 1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
  314. mcr p15, 0, r3, c7, c10, 4 @ drain WB
  315. add r0, r0, #DCACHELINESIZE
  316. mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
  317. mcr p15, 0, r3, c7, c10, 4 @ drain WB
  318. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  319. mov r0, r0
  320. #endif
  321. add r0, r0, #DCACHELINESIZE
  322. cmp r0, r1
  323. blt 1b
  324. #endif
  325. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  326. mov r0, r0
  327. mov r0, r0
  328. #endif
  329. mov pc, lr
  330. /*
  331.  * cpu_arm1020_dcache_clean_page(page)
  332.  *
  333.  * Cleans a single page of dcache so that if we have any future aliased
  334.  * mappings, they will be consistent at the time that they are created.
  335.  *
  336.  * page: virtual address of page to clean from dcache
  337.  *
  338.  * Note:
  339.  *  1. we don't need to flush the write buffer in this case.
  340.  *  2. we don't invalidate the entries since when we write the page
  341.  *     out to disk, the entries may get reloaded into the cache.
  342.  */
  343. .align 5
  344. ENTRY(cpu_arm1020_dcache_clean_page)
  345. mov r1, #PAGESIZE
  346. mcr p15, 0, r0, c7, c10, 4
  347. #ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
  348. 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry  (drain is done by TLB fns)
  349. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  350. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  351. mov r0, r0
  352. #endif
  353. add r0, r0, #DCACHELINESIZE
  354. mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  355. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  356. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  357. mov r0, r0
  358. #endif
  359. add r0, r0, #DCACHELINESIZE
  360. subs r1, r1, #2 * DCACHELINESIZE
  361. bhi 1b
  362. #endif
  363. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  364. mov r0, r0
  365. mov r0, r0
  366. #endif
  367. mov pc, lr
  368. /*
  369.  * cpu_arm1020_dcache_clean_entry(addr)
  370.  *
  371.  * Clean the specified entry of any caches such that the MMU
  372.  * translation fetches will obtain correct data.
  373.  *
  374.  * addr: cache-unaligned virtual address
  375.  */
  376. .align 5
  377. ENTRY(cpu_arm1020_dcache_clean_entry)
  378. mov r1, #0
  379. mcr p15, 0, r1, c7, c10, 4
  380. #ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
  381. mcr p15, 0, r0, c7, c10, 1 @ clean single D entry
  382. mcr p15, 0, r1, c7, c10, 4 @ drain WB
  383. #endif
  384. #ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
  385. mcr p15, 0, r1, c7, c5, 1 @ invalidate I entry
  386. #endif
  387. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  388. mov r1, r1
  389. mov r1, r1
  390. #endif
  391. mov pc, lr
  392. /* ================================ I-CACHE =============================== */
  393. /*
  394.  * cpu_arm1020_icache_invalidate_range(start, end)
  395.  *
  396.  * invalidate a range of virtual addresses from the Icache
  397.  *
  398.  * start: virtual start address
  399.  * end:   virtual end address
  400.  */
  401. .align 5
  402. ENTRY(cpu_arm1020_icache_invalidate_range)
  403. 1: mcr p15, 0, r0, c7, c10, 4
  404. #ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
  405. mcr p15, 0, r0, c7, c10, 1 @ Clean D entry
  406. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  407. add r0, r0, #DCACHELINESIZE
  408. mcr p15, 0, r0, c7, c10, 1 @ Clean D entry
  409. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  410. #endif
  411. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  412. mov r0, r0
  413. #endif
  414. add r0, r0, #DCACHELINESIZE
  415. cmp r0, r1
  416. blo 1b
  417. ENTRY(cpu_arm1020_icache_invalidate_page)
  418. mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
  419. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  420. mov r0, r0
  421. mov r0, r0
  422. #endif
  423. mov pc, lr
  424. /* ================================== TLB ================================= */
  425. /*
  426.  * cpu_arm1020_tlb_invalidate_all()
  427.  *
  428.  * Invalidate all TLB entries
  429.  */
  430. .align 5
  431. ENTRY(cpu_arm1020_tlb_invalidate_all)
  432. mov r0, #0
  433. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  434. mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D tlbs
  435. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  436. mov r0, r0
  437. mov r0, r0
  438. #endif
  439. mov pc, lr
  440. /*
  441.  * cpu_arm1020_tlb_invalidate_range(start, end)
  442.  *
  443.  * invalidate TLB entries covering the specified range
  444.  *
  445.  * start: range start address
  446.  * end:   range end address
  447.  */
  448. .align 5
  449. ENTRY(cpu_arm1020_tlb_invalidate_range)
  450. sub r3, r1, r0
  451. cmp r3, #256 * PAGESIZE
  452. bhi cpu_arm1020_tlb_invalidate_all
  453. mov r3, #0
  454. mcr p15, 0, r3, c7, c10, 4 @ drain WB
  455. 1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
  456. mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
  457. add r0, r0, #PAGESIZE
  458. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  459. mov r0, r0
  460. #endif
  461. cmp r0, r1
  462. blt 1b
  463. mov pc, lr
  464. /*
  465.  * cpu_arm1020_tlb_invalidate_page(page, flags)
  466.  *
  467.  * invalidate the TLB entries for the specified page.
  468.  *
  469.  * page:  page to invalidate
  470.  * flags: non-zero if we include the I TLB
  471.  */
  472. .align 5
  473. ENTRY(cpu_arm1020_tlb_invalidate_page)
  474. mov r3, #0
  475. mcr p15, 0, r3, c7, c10, 4 @ drain WB
  476. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  477. mov r0, r0
  478. mov r0, r0
  479. #endif
  480. teq r1, #0
  481. mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
  482. mcrne p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
  483. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  484. mov r0, r0
  485. mov r0, r0
  486. #endif
  487. mov pc, lr
  488. /* =============================== PageTable ============================== */
  489. /*
  490.  * cpu_arm1020_set_pgd(pgd)
  491.  *
  492.  * Set the translation base pointer to be as described by pgd.
  493.  *
  494.  * pgd: new page tables
  495.  */
  496. .align 5
  497. ENTRY(cpu_arm1020_set_pgd)
  498. #ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
  499. mcr p15, 0, r3, c7, c10, 4
  500. mov r1, #0xF @ 16 segments
  501. 1: mov r3, #0x3F @ 64 entries
  502. 2: mov ip, r3, LSL #26  @ shift up entry
  503. orr ip, ip, r1, LSL #5 @ shift in/up index
  504. mcr p15, 0, ip, c7, c14, 2 @ Clean & Inval DCache entry
  505. mov ip, #0
  506. mcr p15, 0, ip, c7, c10, 4
  507. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  508. mov ip, ip
  509. #endif
  510. subs r3, r3, #1
  511. cmp r3, #0
  512. bge 2b @ entries 3F to 0
  513. subs r1, r1, #1
  514. cmp r1, #0
  515. bge 1b @ segments 15 to 0
  516. #endif
  517. mov r1, #0
  518. #ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
  519. mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
  520. #endif
  521. mcr p15, 0, r1, c7, c10, 4 @ drain WB
  522. mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
  523. mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
  524. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  525. mov ip, ip
  526. mov ip, ip
  527. #endif
  528. mov pc, lr
  529.         
  530. /*
  531.  * cpu_arm1020_set_pmd(pmdp, pmd)
  532.  *
  533.  * Set a level 1 translation table entry, and clean it out of
  534.  * any caches such that the MMUs can load it correctly.
  535.  *
  536.  * pmdp: pointer to PMD entry
  537.  * pmd:  PMD value to store
  538.  */
  539. .align 5
  540. ENTRY(cpu_arm1020_set_pmd)
  541. #ifdef CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH
  542. eor r2, r1, #0x0a @ C & Section
  543. tst r2, #0x0b
  544. biceq r1, r1, #4 @ clear bufferable bit
  545. #endif
  546. str r1, [r0]
  547. #ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
  548. mcr p15, 0, r0, c7, c10, 4
  549. mcr p15, 0, r0, c7, c10, 1 @ clean D entry  (drain is done by TLB fns)
  550. #endif
  551. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  552. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  553. mov r0, r0
  554. mov r0, r0
  555. #endif
  556. mov pc, lr
  557. /*
  558.  * cpu_arm1020_set_pte(ptep, pte)
  559.  *
  560.  * Set a PTE and flush it out
  561.  */
  562. .align 5
  563. ENTRY(cpu_arm1020_set_pte)
  564. str r1, [r0], #-1024 @ linux version
  565. eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
  566. bic r2, r1, #0xff0
  567. bic r2, r2, #3
  568. orr r2, r2, #HPTE_TYPE_SMALL
  569. tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
  570. orrne r2, r2, #HPTE_AP_READ
  571. tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
  572. orreq r2, r2, #HPTE_AP_WRITE
  573. tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young?
  574. movne r2, #0
  575. #ifdef CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH
  576. eor r3, r1, #0x0a @ C & small page?
  577. tst r3, #0x0b
  578. biceq r2, r2, #4
  579. #endif
  580. str r2, [r0] @ hardware version
  581. mov r0, r0
  582. #ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
  583. mcr p15, 0, r0, c7, c10, 4
  584. mcr p15, 0, r0, c7, c10, 1 @ clean D entry
  585. #endif
  586. mcr p15, 0, r0, c7, c10, 4 @ drain WB
  587. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  588. mov r0, r0
  589. mov r0, r0
  590. #endif
  591. mov pc, lr
  592. cpu_manu_name:
  593. .asciz "ARM/VLSI"
  594. ENTRY(cpu_arm1020_name)
  595. .ascii "Arm1020"
  596. #if defined(CONFIG_CPU_ARM1020_CPU_IDLE)
  597. .ascii "s"
  598. #endif
  599. #if defined(CONFIG_CPU_ARM1020_I_CACHE_ON)
  600. .ascii "i"
  601. #endif
  602. #if defined(CONFIG_CPU_ARM1020_D_CACHE_ON)
  603. .ascii "d"
  604. #if defined(CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH)
  605. .ascii "(wt)"
  606. #else
  607. .ascii "(wb)"
  608. #endif
  609. #endif
  610. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  611. .ascii "B"
  612. #endif
  613. #ifdef CONFIG_CPU_ARM1020_ROUND_ROBIN
  614. .ascii "RR"
  615. #endif
  616. .ascii ""
  617. .align
  618. .section ".text.init", #alloc, #execinstr
  619. __arm1020_setup:
  620. mov r0, #0
  621. mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
  622. mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
  623. mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
  624. mcr p15, 0, r4, c2, c0 @ load page table pointer
  625. mov r0, #0x1f @ Domains 0, 1 = client
  626. mcr p15, 0, r0, c3, c0 @ load domain access register
  627. mrc p15, 0, r0, c1, c0 @ get control register v4
  628. /*
  629.  * Clear out 'unwanted' bits (then put them in if we need them)
  630.  */
  631. bic r0, r0, #0x0e00  @ ....??r.........
  632. bic r0, r0, #0x0002  @ ..............a.
  633. bic r0, r0, #0x000c  @ W,D
  634. bic r0, r0, #0x1000  @ I
  635. /*
  636.  * Turn on what we want
  637.  */
  638. orr r0, r0, #0x0031  @ ..........DP...M
  639. orr r0, r0, #0x0100  @ .......S........
  640. #ifdef CONFIG_CPU_ARM1020_ROUND_ROBIN
  641. orr r0, r0, #0x4000  @ .R..............
  642. #endif
  643. #ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
  644. orr r0, r0, #0x0800  @ ....Z...........
  645. #endif
  646. #ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
  647. orr r0, r0, #0x0004  @ Enable D cache
  648. #endif
  649. #ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
  650. orr r0, r0, #0x1000  @ I Cache on
  651. #endif
  652. mov pc, lr
  653. .text
  654. /*
  655.  * Purpose : Function pointers used to access above functions - all calls
  656.  *      come through these
  657.  */
  658. .type arm1020_processor_functions, #object
  659. arm1020_processor_functions:
  660. .word cpu_arm1020_data_abort
  661. .word cpu_arm1020_check_bugs
  662. .word cpu_arm1020_proc_init
  663. .word cpu_arm1020_proc_fin
  664. .word cpu_arm1020_reset
  665. .word cpu_arm1020_do_idle
  666. /* cache */
  667. .word cpu_arm1020_cache_clean_invalidate_all
  668. .word cpu_arm1020_cache_clean_invalidate_range
  669. .word cpu_arm1020_flush_ram_page
  670. /* dcache */
  671. .word cpu_arm1020_dcache_invalidate_range
  672. .word cpu_arm1020_dcache_clean_range
  673. .word cpu_arm1020_dcache_clean_page
  674. .word cpu_arm1020_dcache_clean_entry
  675. /* icache */
  676. .word cpu_arm1020_icache_invalidate_range
  677. .word cpu_arm1020_icache_invalidate_page
  678. /* tlb */
  679. .word cpu_arm1020_tlb_invalidate_all
  680. .word cpu_arm1020_tlb_invalidate_range
  681. .word cpu_arm1020_tlb_invalidate_page
  682. /* pgtable */
  683. .word cpu_arm1020_set_pgd
  684. .word cpu_arm1020_set_pmd
  685. .word cpu_arm1020_set_pte
  686. .size arm1020_processor_functions, . - arm1020_processor_functions
  687. .type cpu_arm1020_info, #object
  688. cpu_arm1020_info:
  689. .long cpu_manu_name
  690. .long cpu_arm1020_name
  691. .size cpu_arm1020_info, . - cpu_arm1020_info
  692. .type cpu_arch_name, #object
  693. cpu_arch_name:
  694. .asciz "armv4"
  695. .size cpu_arch_name, . - cpu_arch_name
  696. .type cpu_elf_name, #object
  697. cpu_elf_name:
  698. .asciz "v4"
  699. .size cpu_elf_name, . - cpu_elf_name
  700. .align
  701. .section ".proc.info", #alloc, #execinstr
  702. .type __arm1020_proc_info,#object
  703. __arm1020_proc_info:
  704. .long 0x4100a200
  705. .long 0xff00fff0
  706. .long 0x00000c02 @ mmuflags
  707. b __arm1020_setup
  708. .long cpu_arch_name
  709. .long cpu_elf_name
  710. .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
  711. .long cpu_arm1020_info
  712. .long arm1020_processor_functions
  713. .size __arm1020_proc_info, . - __arm1020_proc_info