cache.S 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Cache-handling routined for MIPS CPUs
  3. *
  4. * Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <asm-offsets.h>
  9. #include <config.h>
  10. #include <asm/asm.h>
  11. #include <asm/regdef.h>
  12. #include <asm/mipsregs.h>
  13. #include <asm/addrspace.h>
  14. #include <asm/cacheops.h>
  15. #define RA t9
  16. /*
  17. * 16kB is the maximum size of instruction and data caches on MIPS 4K,
  18. * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience.
  19. *
  20. * Note that the above size is the maximum size of primary cache. U-Boot
  21. * doesn't have L2 cache support for now.
  22. */
  23. #define MIPS_MAX_CACHE_SIZE 0x10000
  24. #define INDEX_BASE CKSEG0
  25. .macro cache_op op addr
  26. .set push
  27. .set noreorder
  28. .set mips3
  29. cache \op, 0(\addr)
  30. .set pop
  31. .endm
  32. .macro f_fill64 dst, offset, val
  33. LONG_S \val, (\offset + 0 * LONGSIZE)(\dst)
  34. LONG_S \val, (\offset + 1 * LONGSIZE)(\dst)
  35. LONG_S \val, (\offset + 2 * LONGSIZE)(\dst)
  36. LONG_S \val, (\offset + 3 * LONGSIZE)(\dst)
  37. LONG_S \val, (\offset + 4 * LONGSIZE)(\dst)
  38. LONG_S \val, (\offset + 5 * LONGSIZE)(\dst)
  39. LONG_S \val, (\offset + 6 * LONGSIZE)(\dst)
  40. LONG_S \val, (\offset + 7 * LONGSIZE)(\dst)
  41. #if LONGSIZE == 4
  42. LONG_S \val, (\offset + 8 * LONGSIZE)(\dst)
  43. LONG_S \val, (\offset + 9 * LONGSIZE)(\dst)
  44. LONG_S \val, (\offset + 10 * LONGSIZE)(\dst)
  45. LONG_S \val, (\offset + 11 * LONGSIZE)(\dst)
  46. LONG_S \val, (\offset + 12 * LONGSIZE)(\dst)
  47. LONG_S \val, (\offset + 13 * LONGSIZE)(\dst)
  48. LONG_S \val, (\offset + 14 * LONGSIZE)(\dst)
  49. LONG_S \val, (\offset + 15 * LONGSIZE)(\dst)
  50. #endif
  51. .endm
  52. /*
  53. * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
  54. */
  55. LEAF(mips_init_icache)
  56. blez a1, 9f
  57. mtc0 zero, CP0_TAGLO
  58. /* clear tag to invalidate */
  59. PTR_LI t0, INDEX_BASE
  60. PTR_ADDU t1, t0, a1
  61. 1: cache_op INDEX_STORE_TAG_I t0
  62. PTR_ADDU t0, a2
  63. bne t0, t1, 1b
  64. /* fill once, so data field parity is correct */
  65. PTR_LI t0, INDEX_BASE
  66. 2: cache_op FILL t0
  67. PTR_ADDU t0, a2
  68. bne t0, t1, 2b
  69. /* invalidate again - prudent but not strictly neccessary */
  70. PTR_LI t0, INDEX_BASE
  71. 1: cache_op INDEX_STORE_TAG_I t0
  72. PTR_ADDU t0, a2
  73. bne t0, t1, 1b
  74. 9: jr ra
  75. END(mips_init_icache)
  76. /*
  77. * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
  78. */
  79. LEAF(mips_init_dcache)
  80. blez a1, 9f
  81. mtc0 zero, CP0_TAGLO
  82. /* clear all tags */
  83. PTR_LI t0, INDEX_BASE
  84. PTR_ADDU t1, t0, a1
  85. 1: cache_op INDEX_STORE_TAG_D t0
  86. PTR_ADDU t0, a2
  87. bne t0, t1, 1b
  88. /* load from each line (in cached space) */
  89. PTR_LI t0, INDEX_BASE
  90. 2: LONG_L zero, 0(t0)
  91. PTR_ADDU t0, a2
  92. bne t0, t1, 2b
  93. /* clear all tags */
  94. PTR_LI t0, INDEX_BASE
  95. 1: cache_op INDEX_STORE_TAG_D t0
  96. PTR_ADDU t0, a2
  97. bne t0, t1, 1b
  98. 9: jr ra
  99. END(mips_init_dcache)
  100. /*
  101. * mips_cache_reset - low level initialisation of the primary caches
  102. *
  103. * This routine initialises the primary caches to ensure that they have good
  104. * parity. It must be called by the ROM before any cached locations are used
  105. * to prevent the possibility of data with bad parity being written to memory.
  106. *
  107. * To initialise the instruction cache it is essential that a source of data
  108. * with good parity is available. This routine will initialise an area of
  109. * memory starting at location zero to be used as a source of parity.
  110. *
  111. * RETURNS: N/A
  112. *
  113. */
  114. NESTED(mips_cache_reset, 0, ra)
  115. move RA, ra
  116. li t2, CONFIG_SYS_ICACHE_SIZE
  117. li t3, CONFIG_SYS_DCACHE_SIZE
  118. li t8, CONFIG_SYS_CACHELINE_SIZE
  119. li v0, MIPS_MAX_CACHE_SIZE
  120. /*
  121. * Now clear that much memory starting from zero.
  122. */
  123. PTR_LI a0, CKSEG1
  124. PTR_ADDU a1, a0, v0
  125. 2: PTR_ADDIU a0, 64
  126. f_fill64 a0, -64, zero
  127. bne a0, a1, 2b
  128. /*
  129. * The caches are probably in an indeterminate state,
  130. * so we force good parity into them by doing an
  131. * invalidate, load/fill, invalidate for each line.
  132. */
  133. /*
  134. * Assume bottom of RAM will generate good parity for the cache.
  135. */
  136. /*
  137. * Initialize the I-cache first,
  138. */
  139. move a1, t2
  140. move a2, t8
  141. PTR_LA v1, mips_init_icache
  142. jalr v1
  143. /*
  144. * then initialize D-cache.
  145. */
  146. move a1, t3
  147. move a2, t8
  148. PTR_LA v1, mips_init_dcache
  149. jalr v1
  150. jr RA
  151. END(mips_cache_reset)
  152. /*
  153. * dcache_status - get cache status
  154. *
  155. * RETURNS: 0 - cache disabled; 1 - cache enabled
  156. *
  157. */
  158. LEAF(dcache_status)
  159. mfc0 t0, CP0_CONFIG
  160. li t1, CONF_CM_UNCACHED
  161. andi t0, t0, CONF_CM_CMASK
  162. move v0, zero
  163. beq t0, t1, 2f
  164. li v0, 1
  165. 2: jr ra
  166. END(dcache_status)
  167. /*
  168. * dcache_disable - disable cache
  169. *
  170. * RETURNS: N/A
  171. *
  172. */
  173. LEAF(dcache_disable)
  174. mfc0 t0, CP0_CONFIG
  175. li t1, -8
  176. and t0, t0, t1
  177. ori t0, t0, CONF_CM_UNCACHED
  178. mtc0 t0, CP0_CONFIG
  179. jr ra
  180. END(dcache_disable)
  181. /*
  182. * dcache_enable - enable cache
  183. *
  184. * RETURNS: N/A
  185. *
  186. */
  187. LEAF(dcache_enable)
  188. mfc0 t0, CP0_CONFIG
  189. ori t0, CONF_CM_CMASK
  190. xori t0, CONF_CM_CMASK
  191. ori t0, CONF_CM_CACHABLE_NONCOHERENT
  192. mtc0 t0, CP0_CONFIG
  193. jr ra
  194. END(dcache_enable)