cache.S 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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. /* 16KB is the maximum size of instruction and data caches on
  32. * MIPS 4K.
  33. */
  34. #define MIPS_MAX_CACHE_SIZE 0x4000
  35. /*
  36. * cacheop macro to automate cache operations
  37. * first some helpers...
  38. */
  39. #define _mincache(size, maxsize) \
  40. bltu size,maxsize,9f ; \
  41. move size,maxsize ; \
  42. 9:
  43. #define _align(minaddr, maxaddr, linesize) \
  44. .set noat ; \
  45. subu AT,linesize,1 ; \
  46. not AT ; \
  47. and minaddr,AT ; \
  48. addu maxaddr,-1 ; \
  49. and maxaddr,AT ; \
  50. .set at
  51. /* general operations */
  52. #define doop1(op1) \
  53. cache op1,0(a0)
  54. #define doop2(op1, op2) \
  55. cache op1,0(a0) ; \
  56. nop ; \
  57. cache op2,0(a0)
  58. /* specials for cache initialisation */
  59. #define doop1lw(op1) \
  60. lw zero,0(a0)
  61. #define doop1lw1(op1) \
  62. cache op1,0(a0) ; \
  63. lw zero,0(a0) ; \
  64. cache op1,0(a0)
  65. #define doop121(op1,op2) \
  66. cache op1,0(a0) ; \
  67. nop; \
  68. cache op2,0(a0) ; \
  69. nop; \
  70. cache op1,0(a0)
  71. #define _oploopn(minaddr, maxaddr, linesize, tag, ops) \
  72. .set noreorder ; \
  73. 10: doop##tag##ops ; \
  74. bne minaddr,maxaddr,10b ; \
  75. add minaddr,linesize ; \
  76. .set reorder
  77. /* finally the cache operation macros */
  78. #define vcacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
  79. blez n,11f ; \
  80. addu n,kva ; \
  81. _align(kva, n, cacheLineSize) ; \
  82. _oploopn(kva, n, cacheLineSize, tag, ops) ; \
  83. 11:
  84. #define icacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
  85. _mincache(n, cacheSize); \
  86. blez n,11f ; \
  87. addu n,kva ; \
  88. _align(kva, n, cacheLineSize) ; \
  89. _oploopn(kva, n, cacheLineSize, tag, ops) ; \
  90. 11:
  91. #define vcacheop(kva, n, cacheSize, cacheLineSize, op) \
  92. vcacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
  93. #define icacheop(kva, n, cacheSize, cacheLineSize, op) \
  94. icacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
  95. /*******************************************************************************
  96. *
  97. * mips_cache_reset - low level initialisation of the primary caches
  98. *
  99. * This routine initialises the primary caches to ensure that they
  100. * have good parity. It must be called by the ROM before any cached locations
  101. * are used to prevent the possibility of data with bad parity being written to
  102. * memory.
  103. * To initialise the instruction cache it is essential that a source of data
  104. * with good parity is available. This routine
  105. * will initialise an area of memory starting at location zero to be used as
  106. * a source of parity.
  107. *
  108. * RETURNS: N/A
  109. *
  110. */
  111. NESTED(mips_cache_reset, 0, ra)
  112. li t2, CFG_ICACHE_SIZE
  113. li t3, CFG_DCACHE_SIZE
  114. li t4, CFG_CACHELINE_SIZE
  115. move t5, t4
  116. li v0, MIPS_MAX_CACHE_SIZE
  117. /* Now clear that much memory starting from zero.
  118. */
  119. li a0, KSEG1
  120. addu a1, a0, v0
  121. 2:
  122. sw zero, 0(a0)
  123. sw zero, 4(a0)
  124. sw zero, 8(a0)
  125. sw zero, 12(a0)
  126. sw zero, 16(a0)
  127. sw zero, 20(a0)
  128. sw zero, 24(a0)
  129. sw zero, 28(a0)
  130. addu a0, 32
  131. bltu a0, a1, 2b
  132. /* Set invalid tag.
  133. */
  134. mtc0 zero, CP0_TAGLO
  135. /*
  136. * The caches are probably in an indeterminate state,
  137. * so we force good parity into them by doing an
  138. * invalidate, load/fill, invalidate for each line.
  139. */
  140. /* Assume bottom of RAM will generate good parity for the cache.
  141. */
  142. li a0, K0BASE
  143. move a2, t2 # icacheSize
  144. move a3, t4 # icacheLineSize
  145. move a1, a2
  146. icacheopn(a0,a1,a2,a3,121,(Index_Store_Tag_I,Fill))
  147. /* To support Orion/R4600, we initialise the data cache in 3 passes.
  148. */
  149. /* 1: initialise dcache tags.
  150. */
  151. li a0, K0BASE
  152. move a2, t3 # dcacheSize
  153. move a3, t5 # dcacheLineSize
  154. move a1, a2
  155. icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
  156. /* 2: fill dcache.
  157. */
  158. li a0, K0BASE
  159. move a2, t3 # dcacheSize
  160. move a3, t5 # dcacheLineSize
  161. move a1, a2
  162. icacheopn(a0,a1,a2,a3,1lw,(dummy))
  163. /* 3: clear dcache tags.
  164. */
  165. li a0, K0BASE
  166. move a2, t3 # dcacheSize
  167. move a3, t5 # dcacheLineSize
  168. move a1, a2
  169. icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
  170. j ra
  171. END(mips_cache_reset)
  172. /*******************************************************************************
  173. *
  174. * dcache_status - get cache status
  175. *
  176. * RETURNS: 0 - cache disabled; 1 - cache enabled
  177. *
  178. */
  179. LEAF(dcache_status)
  180. mfc0 v0, CP0_CONFIG
  181. andi v0, v0, 1
  182. j ra
  183. END(dcache_status)
  184. /*******************************************************************************
  185. *
  186. * dcache_disable - disable cache
  187. *
  188. * RETURNS: N/A
  189. *
  190. */
  191. LEAF(dcache_disable)
  192. mfc0 t0, CP0_CONFIG
  193. li t1, -8
  194. and t0, t0, t1
  195. ori t0, t0, CONF_CM_UNCACHED
  196. mtc0 t0, CP0_CONFIG
  197. j ra
  198. END(dcache_disable)
  199. #ifdef CFG_INIT_RAM_LOCK_MIPS
  200. /*******************************************************************************
  201. *
  202. * mips_cache_lock - lock RAM area pointed to by a0 in cache.
  203. *
  204. * RETURNS: N/A
  205. *
  206. */
  207. #if defined(CONFIG_PURPLE)
  208. # define CACHE_LOCK_SIZE (CFG_DCACHE_SIZE/2)
  209. #else
  210. # define CACHE_LOCK_SIZE (CFG_DCACHE_SIZE)
  211. #endif
  212. .globl mips_cache_lock
  213. .ent mips_cache_lock
  214. mips_cache_lock:
  215. li a1, K0BASE - CACHE_LOCK_SIZE
  216. addu a0, a1
  217. li a2, CACHE_LOCK_SIZE
  218. li a3, CFG_CACHELINE_SIZE
  219. move a1, a2
  220. icacheop(a0,a1,a2,a3,0x1d)
  221. j ra
  222. .end mips_cache_lock
  223. #endif /* CFG_INIT_RAM_LOCK_MIPS */