cache.S 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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:
  123. sw zero, 0(a0)
  124. sw zero, 4(a0)
  125. sw zero, 8(a0)
  126. sw zero, 12(a0)
  127. sw zero, 16(a0)
  128. sw zero, 20(a0)
  129. sw zero, 24(a0)
  130. sw zero, 28(a0)
  131. addu a0, 32
  132. bltu a0, a1, 2b
  133. /* Set invalid tag.
  134. */
  135. mtc0 zero, CP0_TAGLO
  136. /*
  137. * The caches are probably in an indeterminate state,
  138. * so we force good parity into them by doing an
  139. * invalidate, load/fill, invalidate for each line.
  140. */
  141. /* Assume bottom of RAM will generate good parity for the cache.
  142. */
  143. li a0, K0BASE
  144. move a2, t2 # icacheSize
  145. move a3, t4 # icacheLineSize
  146. move a1, a2
  147. icacheopn(a0,a1,a2,a3,121,(Index_Store_Tag_I,Fill))
  148. /* To support Orion/R4600, we initialise the data cache in 3 passes.
  149. */
  150. /* 1: initialise dcache tags.
  151. */
  152. li a0, K0BASE
  153. move a2, t3 # dcacheSize
  154. move a3, t5 # dcacheLineSize
  155. move a1, a2
  156. icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
  157. /* 2: fill dcache.
  158. */
  159. li a0, K0BASE
  160. move a2, t3 # dcacheSize
  161. move a3, t5 # dcacheLineSize
  162. move a1, a2
  163. icacheopn(a0,a1,a2,a3,1lw,(dummy))
  164. /* 3: clear dcache tags.
  165. */
  166. li a0, K0BASE
  167. move a2, t3 # dcacheSize
  168. move a3, t5 # dcacheLineSize
  169. move a1, a2
  170. icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
  171. j ra
  172. .end mips_cache_reset
  173. /*******************************************************************************
  174. *
  175. * dcache_status - get cache status
  176. *
  177. * RETURNS: 0 - cache disabled; 1 - cache enabled
  178. *
  179. */
  180. .globl dcache_status
  181. .ent dcache_status
  182. dcache_status:
  183. mfc0 v0, CP0_CONFIG
  184. andi v0, v0, 1
  185. j ra
  186. .end dcache_status
  187. /*******************************************************************************
  188. *
  189. * dcache_disable - disable cache
  190. *
  191. * RETURNS: N/A
  192. *
  193. */
  194. .globl dcache_disable
  195. .ent dcache_disable
  196. dcache_disable:
  197. mfc0 t0, CP0_CONFIG
  198. li t1, -8
  199. and t0, t0, t1
  200. ori t0, t0, CONF_CM_UNCACHED
  201. mtc0 t0, CP0_CONFIG
  202. j ra
  203. .end dcache_disable
  204. /*******************************************************************************
  205. *
  206. * mips_cache_lock - lock RAM area pointed to by a0 in cache.
  207. *
  208. * RETURNS: N/A
  209. *
  210. */
  211. #if defined(CONFIG_PURPLE)
  212. # define CACHE_LOCK_SIZE (CFG_DCACHE_SIZE/2)
  213. #else
  214. # define CACHE_LOCK_SIZE (CFG_DCACHE_SIZE)
  215. #endif
  216. .globl mips_cache_lock
  217. .ent mips_cache_lock
  218. mips_cache_lock:
  219. li a1, K0BASE - CACHE_LOCK_SIZE
  220. addu a0, a1
  221. li a2, CACHE_LOCK_SIZE
  222. li a3, CFG_CACHELINE_SIZE
  223. move a1, a2
  224. icacheop(a0,a1,a2,a3,0x1d)
  225. j ra
  226. .end mips_cache_lock