cache.S 7.7 KB

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