cache.S 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. * Cache-handling routined for MIPS CPUs
  3. *
  4. * Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
  5. *
  6. * See file CREDITS for list of people who contributed to this
  7. * project.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation; either version 2 of
  12. * the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22. * MA 02111-1307 USA
  23. */
  24. #include <config.h>
  25. #include <asm/asm.h>
  26. #include <asm/regdef.h>
  27. #include <asm/mipsregs.h>
  28. #include <asm/addrspace.h>
  29. #include <asm/cacheops.h>
  30. #define RA t8
  31. /*
  32. * 16kB is the maximum size of instruction and data caches on MIPS 4K,
  33. * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience.
  34. *
  35. * Note that the above size is the maximum size of primary cache. U-Boot
  36. * doesn't have L2 cache support for now.
  37. */
  38. #define MIPS_MAX_CACHE_SIZE 0x10000
  39. #define INDEX_BASE CKSEG0
  40. .macro cache_op op addr
  41. .set push
  42. .set noreorder
  43. .set mips3
  44. cache \op, 0(\addr)
  45. .set pop
  46. .endm
  47. /*
  48. * cacheop macro to automate cache operations
  49. * first some helpers...
  50. */
  51. #define _mincache(size, maxsize) \
  52. bltu size,maxsize,9f ; \
  53. move size,maxsize ; \
  54. 9:
  55. #define _align(minaddr, maxaddr, linesize) \
  56. .set noat ; \
  57. subu AT,linesize,1 ; \
  58. not AT ; \
  59. and minaddr,AT ; \
  60. addu maxaddr,-1 ; \
  61. and maxaddr,AT ; \
  62. .set at
  63. /* general operations */
  64. #define doop1(op1) \
  65. cache op1,0(a0)
  66. #define doop2(op1, op2) \
  67. cache op1,0(a0) ; \
  68. nop ; \
  69. cache op2,0(a0)
  70. /* specials for cache initialisation */
  71. #define doop1lw(op1) \
  72. lw zero,0(a0)
  73. #define doop1lw1(op1) \
  74. cache op1,0(a0) ; \
  75. lw zero,0(a0) ; \
  76. cache op1,0(a0)
  77. #define doop121(op1,op2) \
  78. cache op1,0(a0) ; \
  79. nop; \
  80. cache op2,0(a0) ; \
  81. nop; \
  82. cache op1,0(a0)
  83. #define _oploopn(minaddr, maxaddr, linesize, tag, ops) \
  84. .set noreorder ; \
  85. 10: doop##tag##ops ; \
  86. bne minaddr,maxaddr,10b ; \
  87. add minaddr,linesize ; \
  88. .set reorder
  89. /* finally the cache operation macros */
  90. #define vcacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
  91. blez n,11f ; \
  92. addu n,kva ; \
  93. _align(kva, n, cacheLineSize) ; \
  94. _oploopn(kva, n, cacheLineSize, tag, ops) ; \
  95. 11:
  96. #define icacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
  97. _mincache(n, cacheSize); \
  98. blez n,11f ; \
  99. addu n,kva ; \
  100. _align(kva, n, cacheLineSize) ; \
  101. _oploopn(kva, n, cacheLineSize, tag, ops) ; \
  102. 11:
  103. #define vcacheop(kva, n, cacheSize, cacheLineSize, op) \
  104. vcacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
  105. #define icacheop(kva, n, cacheSize, cacheLineSize, op) \
  106. icacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
  107. .macro f_fill64 dst, offset, val
  108. LONG_S \val, (\offset + 0 * LONGSIZE)(\dst)
  109. LONG_S \val, (\offset + 1 * LONGSIZE)(\dst)
  110. LONG_S \val, (\offset + 2 * LONGSIZE)(\dst)
  111. LONG_S \val, (\offset + 3 * LONGSIZE)(\dst)
  112. LONG_S \val, (\offset + 4 * LONGSIZE)(\dst)
  113. LONG_S \val, (\offset + 5 * LONGSIZE)(\dst)
  114. LONG_S \val, (\offset + 6 * LONGSIZE)(\dst)
  115. LONG_S \val, (\offset + 7 * LONGSIZE)(\dst)
  116. #if LONGSIZE == 4
  117. LONG_S \val, (\offset + 8 * LONGSIZE)(\dst)
  118. LONG_S \val, (\offset + 9 * LONGSIZE)(\dst)
  119. LONG_S \val, (\offset + 10 * LONGSIZE)(\dst)
  120. LONG_S \val, (\offset + 11 * LONGSIZE)(\dst)
  121. LONG_S \val, (\offset + 12 * LONGSIZE)(\dst)
  122. LONG_S \val, (\offset + 13 * LONGSIZE)(\dst)
  123. LONG_S \val, (\offset + 14 * LONGSIZE)(\dst)
  124. LONG_S \val, (\offset + 15 * LONGSIZE)(\dst)
  125. #endif
  126. .endm
  127. /*
  128. * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
  129. */
  130. LEAF(mips_init_icache)
  131. blez a1, 9f
  132. mtc0 zero, CP0_TAGLO
  133. /* clear tag to invalidate */
  134. PTR_LI t0, INDEX_BASE
  135. PTR_ADDU t1, t0, a1
  136. 1: cache_op Index_Store_Tag_I t0
  137. PTR_ADDU t0, a2
  138. bne t0, t1, 1b
  139. /* fill once, so data field parity is correct */
  140. PTR_LI t0, INDEX_BASE
  141. 2: cache_op Fill t0
  142. PTR_ADDU t0, a2
  143. bne t0, t1, 2b
  144. /* invalidate again - prudent but not strictly neccessary */
  145. PTR_LI t0, INDEX_BASE
  146. 1: cache_op Index_Store_Tag_I t0
  147. PTR_ADDU t0, a2
  148. bne t0, t1, 1b
  149. 9: jr ra
  150. END(mips_init_icache)
  151. /*
  152. * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
  153. */
  154. LEAF(mips_init_dcache)
  155. blez a1, 9f
  156. mtc0 zero, CP0_TAGLO
  157. /* clear all tags */
  158. PTR_LI t0, INDEX_BASE
  159. PTR_ADDU t1, t0, a1
  160. 1: cache_op Index_Store_Tag_D t0
  161. PTR_ADDU t0, a2
  162. bne t0, t1, 1b
  163. /* load from each line (in cached space) */
  164. PTR_LI t0, INDEX_BASE
  165. 2: LONG_L zero, 0(t0)
  166. PTR_ADDU t0, a2
  167. bne t0, t1, 2b
  168. /* clear all tags */
  169. PTR_LI t0, INDEX_BASE
  170. 1: cache_op Index_Store_Tag_D t0
  171. PTR_ADDU t0, a2
  172. bne t0, t1, 1b
  173. 9: jr ra
  174. END(mips_init_dcache)
  175. /*******************************************************************************
  176. *
  177. * mips_cache_reset - low level initialisation of the primary caches
  178. *
  179. * This routine initialises the primary caches to ensure that they
  180. * have good parity. It must be called by the ROM before any cached locations
  181. * are used to prevent the possibility of data with bad parity being written to
  182. * memory.
  183. * To initialise the instruction cache it is essential that a source of data
  184. * with good parity is available. This routine
  185. * will initialise an area of memory starting at location zero to be used as
  186. * a source of parity.
  187. *
  188. * RETURNS: N/A
  189. *
  190. */
  191. NESTED(mips_cache_reset, 0, ra)
  192. move RA, ra
  193. li t2, CFG_ICACHE_SIZE
  194. li t3, CFG_DCACHE_SIZE
  195. li t4, CFG_CACHELINE_SIZE
  196. move t5, t4
  197. li v0, MIPS_MAX_CACHE_SIZE
  198. /*
  199. * Now clear that much memory starting from zero.
  200. */
  201. PTR_LI a0, CKSEG1
  202. PTR_ADDU a1, a0, v0
  203. 2: PTR_ADDIU a0, 64
  204. f_fill64 a0, -64, zero
  205. bne a0, a1, 2b
  206. /*
  207. * The caches are probably in an indeterminate state,
  208. * so we force good parity into them by doing an
  209. * invalidate, load/fill, invalidate for each line.
  210. */
  211. /*
  212. * Assume bottom of RAM will generate good parity for the cache.
  213. */
  214. /*
  215. * Initialize the I-cache first,
  216. */
  217. move a1, t2
  218. move a2, t4
  219. PTR_LA t7, mips_init_icache
  220. jalr t7
  221. /*
  222. * then initialize D-cache.
  223. */
  224. move a1, t3
  225. move a2, t5
  226. PTR_LA t7, mips_init_dcache
  227. jalr t7
  228. jr RA
  229. END(mips_cache_reset)
  230. /*******************************************************************************
  231. *
  232. * dcache_status - get cache status
  233. *
  234. * RETURNS: 0 - cache disabled; 1 - cache enabled
  235. *
  236. */
  237. LEAF(dcache_status)
  238. mfc0 t0, CP0_CONFIG
  239. li t1, CONF_CM_UNCACHED
  240. andi t0, t0, CONF_CM_CMASK
  241. move v0, zero
  242. beq t0, t1, 2f
  243. li v0, 1
  244. 2: jr ra
  245. END(dcache_status)
  246. /*******************************************************************************
  247. *
  248. * dcache_disable - disable cache
  249. *
  250. * RETURNS: N/A
  251. *
  252. */
  253. LEAF(dcache_disable)
  254. mfc0 t0, CP0_CONFIG
  255. li t1, -8
  256. and t0, t0, t1
  257. ori t0, t0, CONF_CM_UNCACHED
  258. mtc0 t0, CP0_CONFIG
  259. jr ra
  260. END(dcache_disable)
  261. /*******************************************************************************
  262. *
  263. * dcache_enable - enable cache
  264. *
  265. * RETURNS: N/A
  266. *
  267. */
  268. LEAF(dcache_enable)
  269. mfc0 t0, CP0_CONFIG
  270. ori t0, CONF_CM_CMASK
  271. xori t0, CONF_CM_CMASK
  272. ori t0, CONF_CM_CACHABLE_NONCOHERENT
  273. mtc0 t0, CP0_CONFIG
  274. jr ra
  275. END(dcache_enable)
  276. #ifdef CFG_INIT_RAM_LOCK_MIPS
  277. /*******************************************************************************
  278. *
  279. * mips_cache_lock - lock RAM area pointed to by a0 in cache.
  280. *
  281. * RETURNS: N/A
  282. *
  283. */
  284. #if defined(CONFIG_PURPLE)
  285. # define CACHE_LOCK_SIZE (CFG_DCACHE_SIZE/2)
  286. #else
  287. # define CACHE_LOCK_SIZE (CFG_DCACHE_SIZE)
  288. #endif
  289. .globl mips_cache_lock
  290. .ent mips_cache_lock
  291. mips_cache_lock:
  292. li a1, CKSEG0 - CACHE_LOCK_SIZE
  293. addu a0, a1
  294. li a2, CACHE_LOCK_SIZE
  295. li a3, CFG_CACHELINE_SIZE
  296. move a1, a2
  297. icacheop(a0,a1,a2,a3,0x1d)
  298. jr ra
  299. .end mips_cache_lock
  300. #endif /* CFG_INIT_RAM_LOCK_MIPS */