cache.S 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. #include <config.h>
  2. #include <mpc86xx.h>
  3. #include <version.h>
  4. #include <ppc_asm.tmpl>
  5. #include <ppc_defs.h>
  6. #include <asm/cache.h>
  7. #include <asm/mmu.h>
  8. #ifndef CACHE_LINE_SIZE
  9. # define CACHE_LINE_SIZE L1_CACHE_BYTES
  10. #endif
  11. #if CACHE_LINE_SIZE == 128
  12. #define LG_CACHE_LINE_SIZE 7
  13. #elif CACHE_LINE_SIZE == 32
  14. #define LG_CACHE_LINE_SIZE 5
  15. #elif CACHE_LINE_SIZE == 16
  16. #define LG_CACHE_LINE_SIZE 4
  17. #elif CACHE_LINE_SIZE == 8
  18. #define LG_CACHE_LINE_SIZE 3
  19. #else
  20. # error "Invalid cache line size!"
  21. #endif
  22. /*
  23. * Most of this code is taken from 74xx_7xx/cache.S
  24. * and then cleaned up a bit
  25. */
  26. /*
  27. * Invalidate L1 instruction cache.
  28. */
  29. _GLOBAL(invalidate_l1_instruction_cache)
  30. /* use invalidate-all bit in HID0 */
  31. mfspr r3,HID0
  32. ori r3,r3,HID0_ICFI
  33. mtspr HID0,r3
  34. isync
  35. blr
  36. /*
  37. * Invalidate L1 data cache.
  38. */
  39. _GLOBAL(invalidate_l1_data_cache)
  40. mfspr r3,HID0
  41. ori r3,r3,HID0_DCFI
  42. mtspr HID0,r3
  43. isync
  44. blr
  45. /*
  46. * Flush data cache.
  47. */
  48. _GLOBAL(flush_data_cache)
  49. lis r3,0
  50. lis r5,CACHE_LINE_SIZE
  51. flush:
  52. cmp 0,1,r3,r5
  53. bge done
  54. lwz r5,0(r3)
  55. lis r5,CACHE_LINE_SIZE
  56. addi r3,r3,0x4
  57. b flush
  58. done:
  59. blr
  60. /*
  61. * Write any modified data cache blocks out to memory
  62. * and invalidate the corresponding instruction cache blocks.
  63. * This is a no-op on the 601.
  64. *
  65. * flush_icache_range(unsigned long start, unsigned long stop)
  66. */
  67. _GLOBAL(flush_icache_range)
  68. li r5,CACHE_LINE_SIZE-1
  69. andc r3,r3,r5
  70. subf r4,r3,r4
  71. add r4,r4,r5
  72. srwi. r4,r4,LG_CACHE_LINE_SIZE
  73. beqlr
  74. mtctr r4
  75. mr r6,r3
  76. 1: dcbst 0,r3
  77. addi r3,r3,CACHE_LINE_SIZE
  78. bdnz 1b
  79. sync /* wait for dcbst's to get to ram */
  80. mtctr r4
  81. 2: icbi 0,r6
  82. addi r6,r6,CACHE_LINE_SIZE
  83. bdnz 2b
  84. sync /* additional sync needed on g4 */
  85. isync
  86. blr
  87. /*
  88. * Write any modified data cache blocks out to memory.
  89. * Does not invalidate the corresponding cache lines (especially for
  90. * any corresponding instruction cache).
  91. *
  92. * clean_dcache_range(unsigned long start, unsigned long stop)
  93. */
  94. _GLOBAL(clean_dcache_range)
  95. li r5,CACHE_LINE_SIZE-1
  96. andc r3,r3,r5 /* align r3 down to cache line */
  97. subf r4,r3,r4 /* r4 = offset of stop from start of cache line */
  98. add r4,r4,r5 /* r4 += cache_line_size-1 */
  99. srwi. r4,r4,LG_CACHE_LINE_SIZE /* r4 = number of cache lines to flush */
  100. beqlr /* if r4 == 0 return */
  101. mtctr r4 /* ctr = r4 */
  102. sync
  103. 1: dcbst 0,r3
  104. addi r3,r3,CACHE_LINE_SIZE
  105. bdnz 1b
  106. sync /* wait for dcbst's to get to ram */
  107. blr
  108. /*
  109. * Write any modified data cache blocks out to memory
  110. * and invalidate the corresponding instruction cache blocks.
  111. *
  112. * flush_dcache_range(unsigned long start, unsigned long stop)
  113. */
  114. _GLOBAL(flush_dcache_range)
  115. li r5,CACHE_LINE_SIZE-1
  116. andc r3,r3,r5
  117. subf r4,r3,r4
  118. add r4,r4,r5
  119. srwi. r4,r4,LG_CACHE_LINE_SIZE
  120. beqlr
  121. mtctr r4
  122. sync
  123. 1: dcbf 0,r3
  124. addi r3,r3,CACHE_LINE_SIZE
  125. bdnz 1b
  126. sync /* wait for dcbf's to get to ram */
  127. blr
  128. /*
  129. * Like above, but invalidate the D-cache. This is used by the 8xx
  130. * to invalidate the cache so the PPC core doesn't get stale data
  131. * from the CPM (no cache snooping here :-).
  132. *
  133. * invalidate_dcache_range(unsigned long start, unsigned long stop)
  134. */
  135. _GLOBAL(invalidate_dcache_range)
  136. li r5,CACHE_LINE_SIZE-1
  137. andc r3,r3,r5
  138. subf r4,r3,r4
  139. add r4,r4,r5
  140. srwi. r4,r4,LG_CACHE_LINE_SIZE
  141. beqlr
  142. mtctr r4
  143. sync
  144. 1: dcbi 0,r3
  145. addi r3,r3,CACHE_LINE_SIZE
  146. bdnz 1b
  147. sync /* wait for dcbi's to get to ram */
  148. blr
  149. /*
  150. * Flush a particular page from the data cache to RAM.
  151. * Note: this is necessary because the instruction cache does *not*
  152. * snoop from the data cache.
  153. *
  154. * void __flush_page_to_ram(void *page)
  155. */
  156. _GLOBAL(__flush_page_to_ram)
  157. rlwinm r3,r3,0,0,19 /* Get page base address */
  158. li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
  159. mtctr r4
  160. mr r6,r3
  161. 0: dcbst 0,r3 /* Write line to ram */
  162. addi r3,r3,CACHE_LINE_SIZE
  163. bdnz 0b
  164. sync
  165. mtctr r4
  166. 1: icbi 0,r6
  167. addi r6,r6,CACHE_LINE_SIZE
  168. bdnz 1b
  169. sync
  170. isync
  171. blr
  172. /*
  173. * Flush a particular page from the instruction cache.
  174. * Note: this is necessary because the instruction cache does *not*
  175. * snoop from the data cache.
  176. *
  177. * void __flush_icache_page(void *page)
  178. */
  179. _GLOBAL(__flush_icache_page)
  180. li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
  181. mtctr r4
  182. 1: icbi 0,r3
  183. addi r3,r3,CACHE_LINE_SIZE
  184. bdnz 1b
  185. sync
  186. isync
  187. blr
  188. /*
  189. * Clear a page using the dcbz instruction, which doesn't cause any
  190. * memory traffic (except to write out any cache lines which get
  191. * displaced). This only works on cacheable memory.
  192. */
  193. _GLOBAL(clear_page)
  194. li r0,4096/CACHE_LINE_SIZE
  195. mtctr r0
  196. 1: dcbz 0,r3
  197. addi r3,r3,CACHE_LINE_SIZE
  198. bdnz 1b
  199. blr
  200. /*
  201. * Enable L1 Instruction cache
  202. */
  203. _GLOBAL(icache_enable)
  204. mfspr r3, HID0
  205. li r5, HID0_ICFI|HID0_ILOCK
  206. andc r3, r3, r5
  207. ori r3, r3, HID0_ICE
  208. ori r5, r3, HID0_ICFI
  209. mtspr HID0, r5
  210. mtspr HID0, r3
  211. isync
  212. blr
  213. /*
  214. * Disable L1 Instruction cache
  215. */
  216. _GLOBAL(icache_disable)
  217. mfspr r3, HID0
  218. li r5, 0
  219. ori r5, r5, HID0_ICE
  220. andc r3, r3, r5
  221. mtspr HID0, r3
  222. isync
  223. blr
  224. /*
  225. * Is instruction cache enabled?
  226. */
  227. _GLOBAL(icache_status)
  228. mfspr r3, HID0
  229. andi. r3, r3, HID0_ICE
  230. blr
  231. _GLOBAL(l1dcache_enable)
  232. mfspr r3, HID0
  233. li r5, HID0_DCFI|HID0_DLOCK
  234. andc r3, r3, r5
  235. mtspr HID0, r3 /* no invalidate, unlock */
  236. ori r3, r3, HID0_DCE
  237. ori r5, r3, HID0_DCFI
  238. mtspr HID0, r5 /* enable + invalidate */
  239. mtspr HID0, r3 /* enable */
  240. sync
  241. blr
  242. /*
  243. * Enable data cache(s) - L1 and optionally L2
  244. * Calls l2cache_enable. LR saved in r5
  245. */
  246. _GLOBAL(dcache_enable)
  247. mfspr r3, HID0
  248. li r5, HID0_DCFI|HID0_DLOCK
  249. andc r3, r3, r5
  250. mtspr HID0, r3 /* no invalidate, unlock */
  251. ori r3, r3, HID0_DCE
  252. ori r5, r3, HID0_DCFI
  253. mtspr HID0, r5 /* enable + invalidate */
  254. mtspr HID0, r3 /* enable */
  255. sync
  256. #ifdef CFG_L2
  257. mflr r5
  258. bl l2cache_enable /* uses r3 and r4 */
  259. sync
  260. mtlr r5
  261. #endif
  262. blr
  263. /*
  264. * Disable data cache(s) - L1 and optionally L2
  265. * Calls flush_data_cache and l2cache_disable_no_flush.
  266. * LR saved in r4
  267. */
  268. _GLOBAL(dcache_disable)
  269. mflr r4 /* save link register */
  270. bl flush_data_cache /* uses r3 and r5 */
  271. sync
  272. mfspr r3, HID0
  273. li r5, HID0_DCFI|HID0_DLOCK
  274. andc r3, r3, r5
  275. mtspr HID0, r3 /* no invalidate, unlock */
  276. li r5, HID0_DCE|HID0_DCFI
  277. andc r3, r3, r5 /* no enable, no invalidate */
  278. mtspr HID0, r3
  279. sync
  280. #ifdef CFG_L2
  281. bl l2cache_disable_no_flush /* uses r3 */
  282. #endif
  283. mtlr r4 /* restore link register */
  284. blr
  285. /*
  286. * Is data cache enabled?
  287. */
  288. _GLOBAL(dcache_status)
  289. mfspr r3, HID0
  290. andi. r3, r3, HID0_DCE
  291. blr
  292. /*
  293. * Invalidate L2 cache using L2I, assume L2 is enabled
  294. */
  295. _GLOBAL(l2cache_invalidate)
  296. mfspr r3, l2cr
  297. rlwinm. r3, r3, 0, 0, 0
  298. beq 1f
  299. mfspr r3, l2cr
  300. rlwinm r3, r3, 0, 1, 31
  301. #ifdef CONFIG_ALTIVEC
  302. dssall
  303. #endif
  304. sync
  305. mtspr l2cr, r3
  306. sync
  307. 1: mfspr r3, l2cr
  308. oris r3, r3, L2CR_L2I@h
  309. mtspr l2cr, r3
  310. invl2:
  311. mfspr r3, l2cr
  312. andi. r3, r3, L2CR_L2I@h
  313. bne invl2
  314. blr
  315. /*
  316. * Enable L2 cache
  317. * Calls l2cache_invalidate. LR is saved in r4
  318. */
  319. _GLOBAL(l2cache_enable)
  320. mflr r4 /* save link register */
  321. bl l2cache_invalidate /* uses r3 */
  322. sync
  323. lis r3, L2_ENABLE@h
  324. ori r3, r3, L2_ENABLE@l
  325. mtspr l2cr, r3
  326. isync
  327. mtlr r4 /* restore link register */
  328. blr
  329. /*
  330. * Disable L2 cache
  331. * Calls flush_data_cache. LR is saved in r4
  332. */
  333. _GLOBAL(l2cache_disable)
  334. mflr r4 /* save link register */
  335. bl flush_data_cache /* uses r3 and r5 */
  336. sync
  337. mtlr r4 /* restore link register */
  338. l2cache_disable_no_flush: /* provide way to disable L2 w/o flushing */
  339. lis r3, L2_INIT@h
  340. ori r3, r3, L2_INIT@l
  341. mtspr l2cr, r3
  342. isync
  343. blr