cache.S 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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/regdef.h>
  27. #include <asm/mipsregs.h>
  28. #include <asm/addrspace.h>
  29. #include <asm/cacheops.h>
  30. /* 16KB is the maximum size of instruction and data caches on
  31. * MIPS 4K.
  32. */
  33. #define MIPS_MAX_CACHE_SIZE 0x4000
  34. /*
  35. * cacheop macro to automate cache operations
  36. * first some helpers...
  37. */
  38. #define _mincache(size, maxsize) \
  39. bltu size,maxsize,9f ; \
  40. move size,maxsize ; \
  41. 9:
  42. #define _align(minaddr, maxaddr, linesize) \
  43. .set noat ; \
  44. subu AT,linesize,1 ; \
  45. not AT ; \
  46. and minaddr,AT ; \
  47. addu maxaddr,-1 ; \
  48. and maxaddr,AT ; \
  49. .set at
  50. /* general operations */
  51. #define doop1(op1) \
  52. cache op1,0(a0)
  53. #define doop2(op1, op2) \
  54. cache op1,0(a0) ; \
  55. nop ; \
  56. cache op2,0(a0)
  57. /* specials for cache initialisation */
  58. #define doop1lw(op1) \
  59. lw zero,0(a0)
  60. #define doop1lw1(op1) \
  61. cache op1,0(a0) ; \
  62. lw zero,0(a0) ; \
  63. cache op1,0(a0)
  64. #define doop121(op1,op2) \
  65. cache op1,0(a0) ; \
  66. nop; \
  67. cache op2,0(a0) ; \
  68. nop; \
  69. cache op1,0(a0)
  70. #define _oploopn(minaddr, maxaddr, linesize, tag, ops) \
  71. .set noreorder ; \
  72. 10: doop##tag##ops ; \
  73. bne minaddr,maxaddr,10b ; \
  74. add minaddr,linesize ; \
  75. .set reorder
  76. /* finally the cache operation macros */
  77. #define vcacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
  78. blez n,11f ; \
  79. addu n,kva ; \
  80. _align(kva, n, cacheLineSize) ; \
  81. _oploopn(kva, n, cacheLineSize, tag, ops) ; \
  82. 11:
  83. #define icacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
  84. _mincache(n, cacheSize); \
  85. blez n,11f ; \
  86. addu n,kva ; \
  87. _align(kva, n, cacheLineSize) ; \
  88. _oploopn(kva, n, cacheLineSize, tag, ops) ; \
  89. 11:
  90. #define vcacheop(kva, n, cacheSize, cacheLineSize, op) \
  91. vcacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
  92. #define icacheop(kva, n, cacheSize, cacheLineSize, op) \
  93. icacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
  94. /*******************************************************************************
  95. *
  96. * mips_cache_reset - low level initialisation of the primary caches
  97. *
  98. * This routine initialises the primary caches to ensure that they
  99. * have good parity. It must be called by the ROM before any cached locations
  100. * are used to prevent the possibility of data with bad parity being written to
  101. * memory.
  102. * To initialise the instruction cache it is essential that a source of data
  103. * with good parity is available. This routine
  104. * will initialise an area of memory starting at location zero to be used as
  105. * a source of parity.
  106. *
  107. * RETURNS: N/A
  108. *
  109. */
  110. .globl mips_cache_reset
  111. .ent mips_cache_reset
  112. mips_cache_reset:
  113. li t2, CFG_ICACHE_SIZE
  114. li t3, CFG_DCACHE_SIZE
  115. li t4, CFG_CACHELINE_SIZE
  116. move t5, t4
  117. li v0, MIPS_MAX_CACHE_SIZE
  118. /* Now clear that much memory starting from zero.
  119. */
  120. li a0, KSEG1
  121. addu a1, a0, v0
  122. 2: 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. .globl dcache_status
  180. .ent dcache_status
  181. dcache_status:
  182. mfc0 v0, CP0_CONFIG
  183. andi v0, v0, 1
  184. j ra
  185. .end dcache_status
  186. /*******************************************************************************
  187. *
  188. * dcache_disable - disable cache
  189. *
  190. * RETURNS: N/A
  191. *
  192. */
  193. .globl dcache_disable
  194. .ent dcache_disable
  195. dcache_disable:
  196. mfc0 t0, CP0_CONFIG
  197. li t1, -8
  198. and t0, t0, t1
  199. ori t0, t0, CONF_CM_UNCACHED
  200. mtc0 t0, CP0_CONFIG
  201. j ra
  202. .end dcache_disable
  203. /*******************************************************************************
  204. *
  205. * mips_cache_lock - lock RAM area pointed to by a0 in cache.
  206. *
  207. * RETURNS: N/A
  208. *
  209. */
  210. #if defined(CONFIG_PURPLE)
  211. # define CACHE_LOCK_SIZE (CFG_DCACHE_SIZE/2)
  212. #else
  213. # define CACHE_LOCK_SIZE (CFG_DCACHE_SIZE)
  214. #endif
  215. .globl mips_cache_lock
  216. .ent mips_cache_lock
  217. mips_cache_lock:
  218. li a1, K0BASE - CACHE_LOCK_SIZE
  219. addu a0, a1
  220. li a2, CACHE_LOCK_SIZE
  221. li a3, CFG_CACHELINE_SIZE
  222. move a1, a2
  223. icacheop(a0,a1,a2,a3,0x1d)
  224. j ra
  225. .end mips_cache_lock