cache-mtk-v7.S 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  1. /*
  2. * Copyright (C) 2016 MediaTek Inc.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. .text
  14. .global __inner_flush_dcache_all
  15. .global __inner_flush_dcache_L1
  16. .global __inner_flush_dcache_L2
  17. .global __inner_clean_dcache_all
  18. .global __inner_clean_dcache_L1
  19. .global __inner_clean_dcache_L2
  20. .global __inner_inv_dcache_all
  21. .global __inner_inv_dcache_L1
  22. .global __inner_inv_dcache_L2
  23. .global __enable_dcache
  24. .global __enable_icache
  25. .global __enable_cache
  26. .global __disable_dcache
  27. .global __disable_icache
  28. .global __disable_cache
  29. .global __disable_dcache__inner_flush_dcache_L1
  30. .global __disable_dcache__inner_flush_dcache_L1__inner_flush_dcache_L2
  31. .global __disable_dcache__inner_flush_dcache_L1__inner_clean_dcache_L2
  32. .global dis_D_inner_fL1L2
  33. .global d_i_dis_flush_all
  34. .equ C1_IBIT , 0x00001000
  35. .equ C1_CBIT , 0x00000004
  36. .equ PSR_F_BIT, 0x00000040
  37. .equ PSR_I_BIT, 0x00000080
  38. __enable_icache:
  39. MRC p15,0,r0,c1,c0,0
  40. ORR r0,r0,#C1_IBIT
  41. MCR p15,0,r0,c1,c0,0
  42. BX lr
  43. __disable_icache:
  44. MRC p15,0,r0,c1,c0,0
  45. BIC r0,r0,#C1_IBIT
  46. MCR p15,0,r0,c1,c0,0
  47. BX lr
  48. __enable_dcache:
  49. MRC p15,0,r0,c1,c0,0
  50. ORR r0,r0,#C1_CBIT
  51. dsb
  52. MCR p15,0,r0,c1,c0,0
  53. dsb
  54. isb
  55. BX lr
  56. __disable_dcache:
  57. MRC p15,0,r0,c1,c0,0
  58. BIC r0,r0,#C1_CBIT
  59. dsb
  60. MCR p15,0,r0,c1,c0,0
  61. dsb
  62. isb
  63. /*
  64. Erratum:794322,An instruction fetch can be allocated into the L2 cache after the cache is disabled Status
  65. This erratum can be avoided by inserting both of the following after the SCTLR.C bit is cleared to 0,
  66. and before the caches are cleaned or invalidated:
  67. 1) A TLBIMVA operation to any address.
  68. 2) A DSB instruction.
  69. */
  70. MCR p15,0,r0,c8,c7,1
  71. dsb
  72. isb
  73. BX lr
  74. __enable_cache:
  75. MRC p15,0,r0,c1,c0,0
  76. ORR r0,r0,#C1_IBIT
  77. ORR r0,r0,#C1_CBIT
  78. MCR p15,0,r0,c1,c0,0
  79. BX lr
  80. __disable_cache:
  81. MRC p15,0,r0,c1,c0,0
  82. BIC r0,r0,#C1_IBIT
  83. BIC r0,r0,#C1_CBIT
  84. MCR p15,0,r0,c1,c0,0
  85. /*
  86. Erratum:794322,An instruction fetch can be allocated into the L2 cache after the cache is disabled Status
  87. This erratum can be avoided by inserting both of the following after the SCTLR.C bit is cleared to 0,
  88. and before the caches are cleaned or invalidated:
  89. 1) A TLBIMVA operation to any address.
  90. 2) A DSB instruction.
  91. */
  92. MCR p15,0,r0,c8,c7,1
  93. dsb
  94. BX lr
  95. __inner_flush_dcache_all:
  96. push {r0,r1,r2,r3,r4,r5,r7,r8,r9,r10,r11,r14}
  97. dmb @ ensure ordering with previous memory accesses
  98. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  99. ands r3, r0, #0x7000000 @ extract loc from clidr
  100. mov r3, r3, lsr #23 @ left align loc bit field
  101. beq all_finished @ if loc is 0, then no need to clean
  102. mov r10, #0 @ start clean at cache level 0
  103. all_loop1:
  104. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  105. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  106. and r1, r1, #7 @ mask of the bits for current cache only
  107. cmp r1, #2 @ see what cache we have at this level
  108. blt all_skip @ skip if no cache, or just i-cache
  109. #ifdef CONFIG_ARM_ERRATA_814220
  110. dsb
  111. #endif
  112. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  113. isb @ isb to sych the new cssr&csidr
  114. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  115. and r2, r1, #7 @ extract the length of the cache lines
  116. add r2, r2, #4 @ add 4 (line length offset)
  117. ldr r4, =0x3ff
  118. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  119. clz r5, r4 @ find bit position of way size increment
  120. ldr r7, =0x7fff
  121. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  122. all_loop2:
  123. mov r9, r4 @ create working copy of max way size
  124. all_loop3:
  125. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  126. orr r11, r11, r7, lsl r2 @ factor index number into r11
  127. #ifdef CONFIG_L1C_OPT
  128. #replace DCCISW by DCISW+DCCSW
  129. cmp r10, #2
  130. mrsne r1, cpsr @disable IRQ and save flag to make clean and invalidate atomic
  131. orrne r8, r1, #PSR_I_BIT | PSR_F_BIT
  132. msrne cpsr_c, r8
  133. mcrne p15, 0, r11, c7, c10, 2 @ clean by set/way
  134. mcrne p15, 0, r11, c7, c6, 2 @ invalidate by set/way
  135. msrne cpsr_c, r1
  136. mcreq p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
  137. #else
  138. mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
  139. #endif
  140. subs r9, r9, #1 @ decrement the way
  141. bge all_loop3
  142. subs r7, r7, #1 @ decrement the index
  143. bge all_loop2
  144. all_skip:
  145. add r10, r10, #2 @ increment cache number
  146. cmp r3, r10
  147. bgt all_loop1
  148. all_finished:
  149. mov r10, #0 @ swith back to cache level 0
  150. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  151. dsb
  152. isb
  153. pop {r0,r1,r2,r3,r4,r5,r7,r8,r9,r10,r11,r14}
  154. bx lr
  155. __inner_flush_dcache_L1:
  156. push {r0,r1,r2,r3,r4,r5,r7,r8,r9,r10,r11,r14}
  157. dmb @ ensure ordering with previous memory accesses
  158. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  159. ands r3, r0, #0x7000000 @ extract loc from clidr
  160. mov r3, r3, lsr #23 @ left align loc bit field
  161. beq L1_finished @ if loc is 0, then no need to clean
  162. mov r10, #0 @ start clean at cache level 1
  163. L1_loop1:
  164. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  165. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  166. and r1, r1, #7 @ mask of the bits for current cache only
  167. cmp r1, #2 @ see what cache we have at this level
  168. blt L1_skip @ skip if no cache, or just i-cache
  169. #ifdef CONFIG_ARM_ERRATA_814220
  170. dsb
  171. #endif
  172. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  173. isb @ isb to sych the new cssr&csidr
  174. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  175. and r2, r1, #7 @ extract the length of the cache lines
  176. add r2, r2, #4 @ add 4 (line length offset)
  177. ldr r4, =0x3ff
  178. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  179. clz r5, r4 @ find bit position of way size increment
  180. ldr r7, =0x7fff
  181. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  182. L1_loop2:
  183. mov r9, r4 @ create working copy of max way size
  184. L1_loop3:
  185. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  186. orr r11, r11, r7, lsl r2 @ factor index number into r11
  187. #ifdef CONFIG_L1C_OPT
  188. #replace DCCISW by DCISW+DCCSW
  189. mrs r1, cpsr @disable IRQ and save flag to make clean and invalidate atomic
  190. orr r8, r1, #PSR_I_BIT | PSR_F_BIT
  191. msr cpsr_c, r8
  192. mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
  193. mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
  194. msr cpsr_c, r1
  195. #else
  196. mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
  197. #endif
  198. subs r9, r9, #1 @ decrement the way
  199. bge L1_loop3
  200. subs r7, r7, #1 @ decrement the index
  201. bge L1_loop2
  202. L1_skip:
  203. @add r10, r10, #2 @ increment cache number
  204. @cmp r3, r10
  205. @bgt L1_loop1
  206. L1_finished:
  207. mov r10, #0 @ swith back to cache level 0
  208. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  209. dsb
  210. isb
  211. pop {r0,r1,r2,r3,r4,r5,r7,r8,r9,r10,r11,r14}
  212. bx lr
  213. __inner_flush_dcache_L2:
  214. push {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  215. @push {r4,r5,r7,r9,r10,r11}
  216. dmb @ ensure ordering with previous memory accesses
  217. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  218. ands r3, r0, #0x7000000 @ extract loc from clidr
  219. mov r3, r3, lsr #23 @ left align loc bit field
  220. beq L2_finished @ if loc is 0, then no need to clean
  221. mov r10, #2 @ start clean at cache level 2
  222. L2_loop1:
  223. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  224. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  225. and r1, r1, #7 @ mask of the bits for current cache only
  226. cmp r1, #2 @ see what cache we have at this level
  227. blt L2_skip @ skip if no cache, or just i-cache
  228. #ifdef CONFIG_ARM_ERRATA_814220
  229. dsb
  230. #endif
  231. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  232. isb @ isb to sych the new cssr&csidr
  233. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  234. and r2, r1, #7 @ extract the length of the cache lines
  235. add r2, r2, #4 @ add 4 (line length offset)
  236. ldr r4, =0x3ff
  237. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  238. clz r5, r4 @ find bit position of way size increment
  239. ldr r7, =0x7fff
  240. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  241. L2_loop2:
  242. mov r9, r4 @ create working copy of max way size
  243. L2_loop3:
  244. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  245. orr r11, r11, r7, lsl r2 @ factor index number into r11
  246. mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
  247. subs r9, r9, #1 @ decrement the way
  248. bge L2_loop3
  249. subs r7, r7, #1 @ decrement the index
  250. bge L2_loop2
  251. L2_skip:
  252. @add r10, r10, #2 @ increment cache number
  253. @cmp r3, r10
  254. @bgt L2_loop1
  255. L2_finished:
  256. mov r10, #0 @ swith back to cache level 0
  257. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  258. dsb
  259. isb
  260. @pop {r4,r5,r7,r9,r10,r11}
  261. pop {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  262. bx lr
  263. __inner_clean_dcache_all:
  264. push {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  265. @push {r4,r5,r7,r9,r10,r11}
  266. dmb @ ensure ordering with previous memory accesses
  267. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  268. ands r3, r0, #0x7000000 @ extract loc from clidr
  269. mov r3, r3, lsr #23 @ left align loc bit field
  270. beq all_cl_finished @ if loc is 0, then no need to clean
  271. mov r10, #0 @ start clean at cache level 0
  272. all_cl_loop1:
  273. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  274. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  275. and r1, r1, #7 @ mask of the bits for current cache only
  276. cmp r1, #2 @ see what cache we have at this level
  277. blt all_cl_skip @ skip if no cache, or just i-cache
  278. #ifdef CONFIG_ARM_ERRATA_814220
  279. dsb
  280. #endif
  281. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  282. isb @ isb to sych the new cssr&csidr
  283. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  284. and r2, r1, #7 @ extract the length of the cache lines
  285. add r2, r2, #4 @ add 4 (line length offset)
  286. ldr r4, =0x3ff
  287. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  288. clz r5, r4 @ find bit position of way size increment
  289. ldr r7, =0x7fff
  290. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  291. all_cl_loop2:
  292. mov r9, r4 @ create working copy of max way size
  293. all_cl_loop3:
  294. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  295. orr r11, r11, r7, lsl r2 @ factor index number into r11
  296. mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
  297. subs r9, r9, #1 @ decrement the way
  298. bge all_cl_loop3
  299. subs r7, r7, #1 @ decrement the index
  300. bge all_cl_loop2
  301. all_cl_skip:
  302. add r10, r10, #2 @ increment cache number
  303. cmp r3, r10
  304. bgt all_cl_loop1
  305. all_cl_finished:
  306. mov r10, #0 @ swith back to cache level 0
  307. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  308. dsb
  309. isb
  310. @pop {r4,r5,r7,r9,r10,r11}
  311. pop {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  312. bx lr
  313. __inner_clean_dcache_L1:
  314. push {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  315. @push {r4,r5,r7,r9,r10,r11}
  316. dmb @ ensure ordering with previous memory accesses
  317. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  318. ands r3, r0, #0x7000000 @ extract loc from clidr
  319. mov r3, r3, lsr #23 @ left align loc bit field
  320. beq L1_cl_finished @ if loc is 0, then no need to clean
  321. mov r10, #0 @ start clean at cache level 1
  322. L1_cl_loop1:
  323. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  324. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  325. and r1, r1, #7 @ mask of the bits for current cache only
  326. cmp r1, #2 @ see what cache we have at this level
  327. blt L1_cl_skip @ skip if no cache, or just i-cache
  328. #ifdef CONFIG_ARM_ERRATA_814220
  329. dsb
  330. #endif
  331. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  332. isb @ isb to sych the new cssr&csidr
  333. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  334. and r2, r1, #7 @ extract the length of the cache lines
  335. add r2, r2, #4 @ add 4 (line length offset)
  336. ldr r4, =0x3ff
  337. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  338. clz r5, r4 @ find bit position of way size increment
  339. ldr r7, =0x7fff
  340. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  341. L1_cl_loop2:
  342. mov r9, r4 @ create working copy of max way size
  343. L1_cl_loop3:
  344. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  345. orr r11, r11, r7, lsl r2 @ factor index number into r11
  346. mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
  347. subs r9, r9, #1 @ decrement the way
  348. bge L1_cl_loop3
  349. subs r7, r7, #1 @ decrement the index
  350. bge L1_cl_loop2
  351. L1_cl_skip:
  352. @add r10, r10, #2 @ increment cache number
  353. @cmp r3, r10
  354. @bgt L1_cl_loop1
  355. L1_cl_finished:
  356. mov r10, #0 @ swith back to cache level 0
  357. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  358. dsb
  359. isb
  360. @pop {r4,r5,r7,r9,r10,r11}
  361. pop {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  362. bx lr
  363. __inner_clean_dcache_L2:
  364. #if 0
  365. mov r0, sp
  366. mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
  367. dsb
  368. sub r0, r0, #64
  369. mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
  370. dsb
  371. #endif
  372. push {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  373. @push {r4,r5,r7,r9,r10,r11}
  374. #if 0
  375. mov r0, sp
  376. mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
  377. dsb
  378. sub r0, r0, #64
  379. mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
  380. dsb
  381. #endif
  382. dmb @ ensure ordering with previous memory accesses
  383. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  384. ands r3, r0, #0x7000000 @ extract loc from clidr
  385. mov r3, r3, lsr #23 @ left align loc bit field
  386. beq L2_cl_finished @ if loc is 0, then no need to clean
  387. mov r10, #2 @ start clean at cache level 2
  388. L2_cl_loop1:
  389. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  390. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  391. and r1, r1, #7 @ mask of the bits for current cache only
  392. cmp r1, #2 @ see what cache we have at this level
  393. blt L2_cl_skip @ skip if no cache, or just i-cache
  394. #ifdef CONFIG_ARM_ERRATA_814220
  395. dsb
  396. #endif
  397. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  398. isb @ isb to sych the new cssr&csidr
  399. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  400. and r2, r1, #7 @ extract the length of the cache lines
  401. add r2, r2, #4 @ add 4 (line length offset)
  402. ldr r4, =0x3ff
  403. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  404. clz r5, r4 @ find bit position of way size increment
  405. ldr r7, =0x7fff
  406. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  407. L2_cl_loop2:
  408. mov r9, r4 @ create working copy of max way size
  409. L2_cl_loop3:
  410. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  411. orr r11, r11, r7, lsl r2 @ factor index number into r11
  412. mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
  413. subs r9, r9, #1 @ decrement the way
  414. bge L2_cl_loop3
  415. subs r7, r7, #1 @ decrement the index
  416. bge L2_cl_loop2
  417. L2_cl_skip:
  418. @add r10, r10, #2 @ increment cache number
  419. @cmp r3, r10
  420. @bgt L2_cl_loop1
  421. L2_cl_finished:
  422. mov r10, #0 @ swith back to cache level 0
  423. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  424. dsb
  425. isb
  426. @pop {r4,r5,r7,r9,r10,r11}
  427. pop {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  428. bx lr
  429. __inner_inv_dcache_all:
  430. push {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  431. @push {r4,r5,r7,r9,r10,r11}
  432. dmb @ ensure ordering with previous memory accesses
  433. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  434. ands r3, r0, #0x7000000 @ extract loc from clidr
  435. mov r3, r3, lsr #23 @ left align loc bit field
  436. beq all_inv_finished @ if loc is 0, then no need to clean
  437. mov r10, #0 @ start clean at cache level 0
  438. all_inv_loop1:
  439. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  440. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  441. and r1, r1, #7 @ mask of the bits for current cache only
  442. cmp r1, #2 @ see what cache we have at this level
  443. blt all_inv_skip @ skip if no cache, or just i-cache
  444. #ifdef CONFIG_ARM_ERRATA_814220
  445. dsb
  446. #endif
  447. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  448. isb @ isb to sych the new cssr&csidr
  449. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  450. and r2, r1, #7 @ extract the length of the cache lines
  451. add r2, r2, #4 @ add 4 (line length offset)
  452. ldr r4, =0x3ff
  453. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  454. clz r5, r4 @ find bit position of way size increment
  455. ldr r7, =0x7fff
  456. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  457. all_inv_loop2:
  458. mov r9, r4 @ create working copy of max way size
  459. all_inv_loop3:
  460. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  461. orr r11, r11, r7, lsl r2 @ factor index number into r11
  462. mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
  463. subs r9, r9, #1 @ decrement the way
  464. bge all_inv_loop3
  465. subs r7, r7, #1 @ decrement the index
  466. bge all_inv_loop2
  467. all_inv_skip:
  468. add r10, r10, #2 @ increment cache number
  469. cmp r3, r10
  470. bgt all_inv_loop1
  471. all_inv_finished:
  472. mov r10, #0 @ swith back to cache level 0
  473. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  474. dsb
  475. isb
  476. @pop {r4,r5,r7,r9,r10,r11}
  477. pop {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  478. bx lr
  479. __inner_inv_dcache_L1:
  480. push {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  481. @push {r4,r5,r7,r9,r10,r11}
  482. dmb @ ensure ordering with previous memory accesses
  483. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  484. ands r3, r0, #0x7000000 @ extract loc from clidr
  485. mov r3, r3, lsr #23 @ left align loc bit field
  486. beq L1_inv_finished @ if loc is 0, then no need to clean
  487. mov r10, #0 @ start clean at cache level 1
  488. L1_inv_loop1:
  489. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  490. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  491. and r1, r1, #7 @ mask of the bits for current cache only
  492. cmp r1, #2 @ see what cache we have at this level
  493. blt L1_inv_skip @ skip if no cache, or just i-cache
  494. #ifdef CONFIG_ARM_ERRATA_814220
  495. dsb
  496. #endif
  497. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  498. isb @ isb to sych the new cssr&csidr
  499. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  500. and r2, r1, #7 @ extract the length of the cache lines
  501. add r2, r2, #4 @ add 4 (line length offset)
  502. ldr r4, =0x3ff
  503. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  504. clz r5, r4 @ find bit position of way size increment
  505. ldr r7, =0x7fff
  506. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  507. L1_inv_loop2:
  508. mov r9, r4 @ create working copy of max way size
  509. L1_inv_loop3:
  510. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  511. orr r11, r11, r7, lsl r2 @ factor index number into r11
  512. mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
  513. subs r9, r9, #1 @ decrement the way
  514. bge L1_inv_loop3
  515. subs r7, r7, #1 @ decrement the index
  516. bge L1_inv_loop2
  517. L1_inv_skip:
  518. @add r10, r10, #2 @ increment cache number
  519. @cmp r3, r10
  520. @bgt L1_inv_loop1
  521. L1_inv_finished:
  522. mov r10, #0 @ swith back to cache level 0
  523. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  524. dsb
  525. isb
  526. @pop {r4,r5,r7,r9,r10,r11}
  527. pop {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  528. bx lr
  529. __inner_inv_dcache_L2:
  530. push {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  531. @push {r4,r5,r7,r9,r10,r11}
  532. dmb @ ensure ordering with previous memory accesses
  533. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  534. ands r3, r0, #0x7000000 @ extract loc from clidr
  535. mov r3, r3, lsr #23 @ left align loc bit field
  536. beq L2_inv_finished @ if loc is 0, then no need to clean
  537. mov r10, #2 @ start clean at cache level 2
  538. L2_inv_loop1:
  539. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  540. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  541. and r1, r1, #7 @ mask of the bits for current cache only
  542. cmp r1, #2 @ see what cache we have at this level
  543. blt L2_inv_skip @ skip if no cache, or just i-cache
  544. #ifdef CONFIG_ARM_ERRATA_814220
  545. dsb
  546. #endif
  547. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  548. isb @ isb to sych the new cssr&csidr
  549. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  550. and r2, r1, #7 @ extract the length of the cache lines
  551. add r2, r2, #4 @ add 4 (line length offset)
  552. ldr r4, =0x3ff
  553. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  554. clz r5, r4 @ find bit position of way size increment
  555. ldr r7, =0x7fff
  556. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  557. L2_inv_loop2:
  558. mov r9, r4 @ create working copy of max way size
  559. L2_inv_loop3:
  560. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  561. orr r11, r11, r7, lsl r2 @ factor index number into r11
  562. mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
  563. subs r9, r9, #1 @ decrement the way
  564. bge L2_inv_loop3
  565. subs r7, r7, #1 @ decrement the index
  566. bge L2_inv_loop2
  567. L2_inv_skip:
  568. @add r10, r10, #2 @ increment cache number
  569. @cmp r3, r10
  570. @bgt L2_inv_loop1
  571. L2_inv_finished:
  572. mov r10, #0 @ swith back to cache level 0
  573. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  574. dsb
  575. isb
  576. @pop {r4,r5,r7,r9,r10,r11}
  577. pop {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  578. bx lr
  579. __disable_dcache__inner_flush_dcache_L1:
  580. /*******************************************************************************
  581. * push stack *
  582. ******************************************************************************/
  583. push {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  584. /*******************************************************************************
  585. * __disable_dcache *
  586. ******************************************************************************/
  587. MRC p15,0,r0,c1,c0,0
  588. BIC r0,r0,#C1_CBIT
  589. dsb
  590. MCR p15,0,r0,c1,c0,0
  591. dsb
  592. isb
  593. /*
  594. Erratum:794322,An instruction fetch can be allocated into the L2 cache after the cache is disabled Status
  595. This erratum can be avoided by inserting both of the following after the SCTLR.C bit is cleared to 0,
  596. and before the caches are cleaned or invalidated:
  597. 1) A TLBIMVA operation to any address.
  598. 2) A DSB instruction.
  599. */
  600. MCR p15,0,r0,c8,c7,1
  601. dsb
  602. isb
  603. /*******************************************************************************
  604. * __inner_flush_dcache_L1 *
  605. ******************************************************************************/
  606. dmb @ ensure ordering with previous memory accesses
  607. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  608. ands r3, r0, #0x7000000 @ extract loc from clidr
  609. mov r3, r3, lsr #23 @ left align loc bit field
  610. beq DF1_L1_finished @ if loc is 0, then no need to clean
  611. mov r10, #0 @ start clean at cache level 1
  612. DF1_L1_loop1:
  613. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  614. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  615. and r1, r1, #7 @ mask of the bits for current cache only
  616. cmp r1, #2 @ see what cache we have at this level
  617. blt DF1_L1_skip @ skip if no cache, or just i-cache
  618. #ifdef CONFIG_ARM_ERRATA_814220
  619. dsb
  620. #endif
  621. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  622. isb @ isb to sych the new cssr&csidr
  623. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  624. and r2, r1, #7 @ extract the length of the cache lines
  625. add r2, r2, #4 @ add 4 (line length offset)
  626. ldr r4, =0x3ff
  627. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  628. clz r5, r4 @ find bit position of way size increment
  629. ldr r7, =0x7fff
  630. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  631. DF1_L1_loop2:
  632. mov r9, r4 @ create working copy of max way size
  633. DF1_L1_loop3:
  634. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  635. orr r11, r11, r7, lsl r2 @ factor index number into r11
  636. #if 1
  637. mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
  638. mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
  639. #endif
  640. #if 0
  641. mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
  642. #endif
  643. subs r9, r9, #1 @ decrement the way
  644. bge DF1_L1_loop3
  645. subs r7, r7, #1 @ decrement the index
  646. bge DF1_L1_loop2
  647. DF1_L1_skip:
  648. @add r10, r10, #2 @ increment cache number
  649. @cmp r3, r10
  650. @bgt DF1_L1_loop1
  651. DF1_L1_finished:
  652. mov r10, #0 @ swith back to cache level 0
  653. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  654. dsb
  655. isb
  656. /*******************************************************************************
  657. * pop stack *
  658. ******************************************************************************/
  659. pop {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  660. bx lr
  661. __disable_dcache__inner_flush_dcache_L1__inner_flush_dcache_L2:
  662. /*******************************************************************************
  663. * push stack *
  664. ******************************************************************************/
  665. push {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  666. /*******************************************************************************
  667. * __disable_dcache *
  668. ******************************************************************************/
  669. MRC p15,0,r0,c1,c0,0
  670. BIC r0,r0,#C1_CBIT
  671. dsb
  672. MCR p15,0,r0,c1,c0,0
  673. dsb
  674. isb
  675. /*
  676. Erratum:794322,An instruction fetch can be allocated into the L2 cache after the cache is disabled Status
  677. This erratum can be avoided by inserting both of the following after the SCTLR.C bit is cleared to 0,
  678. and before the caches are cleaned or invalidated:
  679. 1) A TLBIMVA operation to any address.
  680. 2) A DSB instruction.
  681. */
  682. MCR p15,0,r0,c8,c7,1
  683. dsb
  684. isb
  685. /*******************************************************************************
  686. * __inner_flush_dcache_L1 *
  687. ******************************************************************************/
  688. dmb @ ensure ordering with previous memory accesses
  689. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  690. ands r3, r0, #0x7000000 @ extract loc from clidr
  691. mov r3, r3, lsr #23 @ left align loc bit field
  692. beq DF1F2_L1_finished @ if loc is 0, then no need to clean
  693. mov r10, #0 @ start clean at cache level 1
  694. DF1F2_L1_loop1:
  695. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  696. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  697. and r1, r1, #7 @ mask of the bits for current cache only
  698. cmp r1, #2 @ see what cache we have at this level
  699. blt DF1F2_L1_skip @ skip if no cache, or just i-cache
  700. #ifdef CONFIG_ARM_ERRATA_814220
  701. dsb
  702. #endif
  703. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  704. isb @ isb to sych the new cssr&csidr
  705. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  706. and r2, r1, #7 @ extract the length of the cache lines
  707. add r2, r2, #4 @ add 4 (line length offset)
  708. ldr r4, =0x3ff
  709. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  710. clz r5, r4 @ find bit position of way size increment
  711. ldr r7, =0x7fff
  712. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  713. DF1F2_L1_loop2:
  714. mov r9, r4 @ create working copy of max way size
  715. DF1F2_L1_loop3:
  716. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  717. orr r11, r11, r7, lsl r2 @ factor index number into r11
  718. #if 1
  719. mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
  720. mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
  721. #endif
  722. #if 0
  723. mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
  724. #endif
  725. subs r9, r9, #1 @ decrement the way
  726. bge DF1F2_L1_loop3
  727. subs r7, r7, #1 @ decrement the index
  728. bge DF1F2_L1_loop2
  729. DF1F2_L1_skip:
  730. @add r10, r10, #2 @ increment cache number
  731. @cmp r3, r10
  732. @bgt DF1F2_L1_loop1
  733. DF1F2_L1_finished:
  734. mov r10, #0 @ swith back to cache level 0
  735. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  736. dsb
  737. isb
  738. /*******************************************************************************
  739. * clrex *
  740. ******************************************************************************/
  741. clrex
  742. /*******************************************************************************
  743. * __inner_flush_dcache_L2 *
  744. ******************************************************************************/
  745. dmb @ ensure ordering with previous memory accesses
  746. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  747. ands r3, r0, #0x7000000 @ extract loc from clidr
  748. mov r3, r3, lsr #23 @ left align loc bit field
  749. beq DF1F2_L2_finished @ if loc is 0, then no need to clean
  750. mov r10, #2 @ start clean at cache level 2
  751. DF1F2_L2_loop1:
  752. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  753. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  754. and r1, r1, #7 @ mask of the bits for current cache only
  755. cmp r1, #2 @ see what cache we have at this level
  756. blt DF1F2_L2_skip @ skip if no cache, or just i-cache
  757. #ifdef CONFIG_ARM_ERRATA_814220
  758. dsb
  759. #endif
  760. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  761. isb @ isb to sych the new cssr&csidr
  762. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  763. and r2, r1, #7 @ extract the length of the cache lines
  764. add r2, r2, #4 @ add 4 (line length offset)
  765. ldr r4, =0x3ff
  766. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  767. clz r5, r4 @ find bit position of way size increment
  768. ldr r7, =0x7fff
  769. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  770. DF1F2_L2_loop2:
  771. mov r9, r4 @ create working copy of max way size
  772. DF1F2_L2_loop3:
  773. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  774. orr r11, r11, r7, lsl r2 @ factor index number into r11
  775. mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
  776. subs r9, r9, #1 @ decrement the way
  777. bge DF1F2_L2_loop3
  778. subs r7, r7, #1 @ decrement the index
  779. bge DF1F2_L2_loop2
  780. DF1F2_L2_skip:
  781. @add r10, r10, #2 @ increment cache number
  782. @cmp r3, r10
  783. @bgt DF1F2_L2_loop1
  784. DF1F2_L2_finished:
  785. mov r10, #0 @ swith back to cache level 0
  786. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  787. dsb
  788. isb
  789. /*******************************************************************************
  790. * pop stack *
  791. ******************************************************************************/
  792. pop {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  793. bx lr
  794. dis_D_inner_fL1L2:
  795. __disable_dcache__inner_flush_dcache_L1__inner_clean_dcache_L2:
  796. /*******************************************************************************
  797. * push stack *
  798. ******************************************************************************/
  799. push {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  800. /*******************************************************************************
  801. * __disable_dcache *
  802. ******************************************************************************/
  803. MRC p15,0,r0,c1,c0,0
  804. BIC r0,r0,#C1_CBIT
  805. dsb
  806. MCR p15,0,r0,c1,c0,0
  807. dsb
  808. isb
  809. /*
  810. Erratum:794322,An instruction fetch can be allocated into the L2 cache after the cache is disabled Status
  811. This erratum can be avoided by inserting both of the following after the SCTLR.C bit is cleared to 0,
  812. and before the caches are cleaned or invalidated:
  813. 1) A TLBIMVA operation to any address.
  814. 2) A DSB instruction.
  815. */
  816. MCR p15,0,r0,c8,c7,1
  817. dsb
  818. isb
  819. /*******************************************************************************
  820. * __inner_flush_dcache_L1 *
  821. ******************************************************************************/
  822. dmb @ ensure ordering with previous memory accesses
  823. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  824. ands r3, r0, #0x7000000 @ extract loc from clidr
  825. mov r3, r3, lsr #23 @ left align loc bit field
  826. beq DF1C2_L1_finished @ if loc is 0, then no need to clean
  827. mov r10, #0 @ start clean at cache level 1
  828. DF1C2_L1_loop1:
  829. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  830. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  831. and r1, r1, #7 @ mask of the bits for current cache only
  832. cmp r1, #2 @ see what cache we have at this level
  833. blt DF1C2_L1_skip @ skip if no cache, or just i-cache
  834. #ifdef CONFIG_ARM_ERRATA_814220
  835. dsb
  836. #endif
  837. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  838. isb @ isb to sych the new cssr&csidr
  839. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  840. and r2, r1, #7 @ extract the length of the cache lines
  841. add r2, r2, #4 @ add 4 (line length offset)
  842. ldr r4, =0x3ff
  843. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  844. clz r5, r4 @ find bit position of way size increment
  845. ldr r7, =0x7fff
  846. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  847. DF1C2_L1_loop2:
  848. mov r9, r4 @ create working copy of max way size
  849. DF1C2_L1_loop3:
  850. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  851. orr r11, r11, r7, lsl r2 @ factor index number into r11
  852. #if 1
  853. mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
  854. mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
  855. #endif
  856. #if 0
  857. mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
  858. #endif
  859. subs r9, r9, #1 @ decrement the way
  860. bge DF1C2_L1_loop3
  861. subs r7, r7, #1 @ decrement the index
  862. bge DF1C2_L1_loop2
  863. DF1C2_L1_skip:
  864. @add r10, r10, #2 @ increment cache number
  865. @cmp r3, r10
  866. @bgt DF1C2_L1_loop1
  867. DF1C2_L1_finished:
  868. mov r10, #0 @ swith back to cache level 0
  869. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  870. dsb
  871. isb
  872. /*******************************************************************************
  873. * clrex *
  874. ******************************************************************************/
  875. clrex
  876. /*******************************************************************************
  877. * __inner_clean_dcache_L2 *
  878. ******************************************************************************/
  879. dmb @ ensure ordering with previous memory accesses
  880. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  881. ands r3, r0, #0x7000000 @ extract loc from clidr
  882. mov r3, r3, lsr #23 @ left align loc bit field
  883. beq DF1C2_L2_cl_finished @ if loc is 0, then no need to clean
  884. mov r10, #2 @ start clean at cache level 2
  885. DF1C2_L2_cl_loop1:
  886. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  887. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  888. and r1, r1, #7 @ mask of the bits for current cache only
  889. cmp r1, #2 @ see what cache we have at this level
  890. blt DF1C2_L2_cl_skip @ skip if no cache, or just i-cache
  891. #ifdef CONFIG_ARM_ERRATA_814220
  892. dsb
  893. #endif
  894. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  895. isb @ isb to sych the new cssr&csidr
  896. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  897. and r2, r1, #7 @ extract the length of the cache lines
  898. add r2, r2, #4 @ add 4 (line length offset)
  899. ldr r4, =0x3ff
  900. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  901. clz r5, r4 @ find bit position of way size increment
  902. ldr r7, =0x7fff
  903. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  904. DF1C2_L2_cl_loop2:
  905. mov r9, r4 @ create working copy of max way size
  906. DF1C2_L2_cl_loop3:
  907. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  908. orr r11, r11, r7, lsl r2 @ factor index number into r11
  909. mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
  910. subs r9, r9, #1 @ decrement the way
  911. bge DF1C2_L2_cl_loop3
  912. subs r7, r7, #1 @ decrement the index
  913. bge DF1C2_L2_cl_loop2
  914. DF1C2_L2_cl_skip:
  915. @add r10, r10, #2 @ increment cache number
  916. @cmp r3, r10
  917. @bgt DF1C2_L2_cl_loop1
  918. DF1C2_L2_cl_finished:
  919. mov r10, #0 @ swith back to cache level 0
  920. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  921. dsb
  922. isb
  923. /*******************************************************************************
  924. * pop stack *
  925. ******************************************************************************/
  926. pop {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  927. bx lr
  928. d_i_dis_flush_all:
  929. /*******************************************************************************
  930. * push stack *
  931. ******************************************************************************/
  932. push {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  933. /*******************************************************************************
  934. * __disable_dcache *
  935. ******************************************************************************/
  936. MRC p15,0,r0,c1,c0,0
  937. BIC r0,r0,#C1_CBIT
  938. BIC r0,r0,#C1_IBIT
  939. dsb
  940. MCR p15,0,r0,c1,c0,0
  941. dsb
  942. isb
  943. /*
  944. Erratum:794322,An instruction fetch can be allocated into the L2 cache after the cache is disabled Status
  945. This erratum can be avoided by inserting both of the following after the SCTLR.C bit is cleared to 0,
  946. and before the caches are cleaned or invalidated:
  947. 1) A TLBIMVA operation to any address.
  948. 2) A DSB instruction.
  949. */
  950. MCR p15,0,r0,c8,c7,1
  951. dsb
  952. isb
  953. /*******************************************************************************
  954. * __inner_flush_dcache_L1 *
  955. ******************************************************************************/
  956. dmb @ ensure ordering with previous memory accesses
  957. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  958. ands r3, r0, #0x7000000 @ extract loc from clidr
  959. mov r3, r3, lsr #23 @ left align loc bit field
  960. beq DIF1F2_L1_finished @ if loc is 0, then no need to clean
  961. mov r10, #0 @ start clean at cache level 1
  962. DIF1F2_L1_loop1:
  963. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  964. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  965. and r1, r1, #7 @ mask of the bits for current cache only
  966. cmp r1, #2 @ see what cache we have at this level
  967. blt DIF1F2_L1_skip @ skip if no cache, or just i-cache
  968. #ifdef CONFIG_ARM_ERRATA_814220
  969. dsb
  970. #endif
  971. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  972. isb @ isb to sych the new cssr&csidr
  973. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  974. and r2, r1, #7 @ extract the length of the cache lines
  975. add r2, r2, #4 @ add 4 (line length offset)
  976. ldr r4, =0x3ff
  977. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  978. clz r5, r4 @ find bit position of way size increment
  979. ldr r7, =0x7fff
  980. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  981. DIF1F2_L1_loop2:
  982. mov r9, r4 @ create working copy of max way size
  983. DIF1F2_L1_loop3:
  984. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  985. orr r11, r11, r7, lsl r2 @ factor index number into r11
  986. #if 1
  987. mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
  988. mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
  989. #endif
  990. #if 0
  991. mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
  992. #endif
  993. subs r9, r9, #1 @ decrement the way
  994. bge DIF1F2_L1_loop3
  995. subs r7, r7, #1 @ decrement the index
  996. bge DIF1F2_L1_loop2
  997. DIF1F2_L1_skip:
  998. @add r10, r10, #2 @ increment cache number
  999. @cmp r3, r10
  1000. @bgt DIF1F2_L1_loop1
  1001. DIF1F2_L1_finished:
  1002. mov r10, #0 @ swith back to cache level 0
  1003. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  1004. dsb
  1005. isb
  1006. /*******************************************************************************
  1007. * clrex *
  1008. ******************************************************************************/
  1009. clrex
  1010. /*******************************************************************************
  1011. * __inner_flush_dcache_L2 *
  1012. ******************************************************************************/
  1013. dmb @ ensure ordering with previous memory accesses
  1014. mrc p15, 1, r0, c0, c0, 1 @ read clidr
  1015. ands r3, r0, #0x7000000 @ extract loc from clidr
  1016. mov r3, r3, lsr #23 @ left align loc bit field
  1017. beq DIF1F2_L2_finished @ if loc is 0, then no need to clean
  1018. mov r10, #2 @ start clean at cache level 2
  1019. DIF1F2_L2_loop1:
  1020. add r2, r10, r10, lsr #1 @ work out 3x current cache level
  1021. mov r1, r0, lsr r2 @ extract cache type bits from clidr
  1022. and r1, r1, #7 @ mask of the bits for current cache only
  1023. cmp r1, #2 @ see what cache we have at this level
  1024. blt DIF1F2_L2_skip @ skip if no cache, or just i-cache
  1025. #ifdef CONFIG_ARM_ERRATA_814220
  1026. dsb
  1027. #endif
  1028. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  1029. isb @ isb to sych the new cssr&csidr
  1030. mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
  1031. and r2, r1, #7 @ extract the length of the cache lines
  1032. add r2, r2, #4 @ add 4 (line length offset)
  1033. ldr r4, =0x3ff
  1034. ands r4, r4, r1, lsr #3 @ find maximum number on the way size
  1035. clz r5, r4 @ find bit position of way size increment
  1036. ldr r7, =0x7fff
  1037. ands r7, r7, r1, lsr #13 @ extract max number of the index size
  1038. DIF1F2_L2_loop2:
  1039. mov r9, r4 @ create working copy of max way size
  1040. DIF1F2_L2_loop3:
  1041. orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
  1042. orr r11, r11, r7, lsl r2 @ factor index number into r11
  1043. mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
  1044. subs r9, r9, #1 @ decrement the way
  1045. bge DIF1F2_L2_loop3
  1046. subs r7, r7, #1 @ decrement the index
  1047. bge DIF1F2_L2_loop2
  1048. DIF1F2_L2_skip:
  1049. @add r10, r10, #2 @ increment cache number
  1050. @cmp r3, r10
  1051. @bgt DIF1F2_L2_loop1
  1052. DIF1F2_L2_finished:
  1053. mov r10, #0 @ swith back to cache level 0
  1054. mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
  1055. dsb
  1056. isb
  1057. /*******************************************************************************
  1058. * pop stack *
  1059. ******************************************************************************/
  1060. pop {r0,r1,r2,r3,r4,r5,r7,r9,r10,r11,r14}
  1061. bx lr
  1062. .end