cache.S 7.5 KB

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