cache_init.S 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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. #ifndef CONFIG_SYS_MIPS_CACHE_MODE
  16. #define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
  17. #endif
  18. #define INDEX_BASE CKSEG0
  19. .macro f_fill64 dst, offset, val
  20. LONG_S \val, (\offset + 0 * LONGSIZE)(\dst)
  21. LONG_S \val, (\offset + 1 * LONGSIZE)(\dst)
  22. LONG_S \val, (\offset + 2 * LONGSIZE)(\dst)
  23. LONG_S \val, (\offset + 3 * LONGSIZE)(\dst)
  24. LONG_S \val, (\offset + 4 * LONGSIZE)(\dst)
  25. LONG_S \val, (\offset + 5 * LONGSIZE)(\dst)
  26. LONG_S \val, (\offset + 6 * LONGSIZE)(\dst)
  27. LONG_S \val, (\offset + 7 * LONGSIZE)(\dst)
  28. #if LONGSIZE == 4
  29. LONG_S \val, (\offset + 8 * LONGSIZE)(\dst)
  30. LONG_S \val, (\offset + 9 * LONGSIZE)(\dst)
  31. LONG_S \val, (\offset + 10 * LONGSIZE)(\dst)
  32. LONG_S \val, (\offset + 11 * LONGSIZE)(\dst)
  33. LONG_S \val, (\offset + 12 * LONGSIZE)(\dst)
  34. LONG_S \val, (\offset + 13 * LONGSIZE)(\dst)
  35. LONG_S \val, (\offset + 14 * LONGSIZE)(\dst)
  36. LONG_S \val, (\offset + 15 * LONGSIZE)(\dst)
  37. #endif
  38. .endm
  39. .macro cache_loop curr, end, line_sz, op
  40. 10: cache \op, 0(\curr)
  41. PTR_ADDU \curr, \curr, \line_sz
  42. bne \curr, \end, 10b
  43. .endm
  44. .macro l1_info sz, line_sz, off
  45. .set push
  46. .set noat
  47. mfc0 $1, CP0_CONFIG, 1
  48. /* detect line size */
  49. srl \line_sz, $1, \off + MIPS_CONF1_DL_SHF - MIPS_CONF1_DA_SHF
  50. andi \line_sz, \line_sz, (MIPS_CONF1_DL >> MIPS_CONF1_DL_SHF)
  51. move \sz, zero
  52. beqz \line_sz, 10f
  53. li \sz, 2
  54. sllv \line_sz, \sz, \line_sz
  55. /* detect associativity */
  56. srl \sz, $1, \off + MIPS_CONF1_DA_SHF - MIPS_CONF1_DA_SHF
  57. andi \sz, \sz, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHF)
  58. addiu \sz, \sz, 1
  59. /* sz *= line_sz */
  60. mul \sz, \sz, \line_sz
  61. /* detect log32(sets) */
  62. srl $1, $1, \off + MIPS_CONF1_DS_SHF - MIPS_CONF1_DA_SHF
  63. andi $1, $1, (MIPS_CONF1_DS >> MIPS_CONF1_DS_SHF)
  64. addiu $1, $1, 1
  65. andi $1, $1, 0x7
  66. /* sz <<= log32(sets) */
  67. sllv \sz, \sz, $1
  68. /* sz *= 32 */
  69. li $1, 32
  70. mul \sz, \sz, $1
  71. 10:
  72. .set pop
  73. .endm
  74. /*
  75. * mips_cache_reset - low level initialisation of the primary caches
  76. *
  77. * This routine initialises the primary caches to ensure that they have good
  78. * parity. It must be called by the ROM before any cached locations are used
  79. * to prevent the possibility of data with bad parity being written to memory.
  80. *
  81. * To initialise the instruction cache it is essential that a source of data
  82. * with good parity is available. This routine will initialise an area of
  83. * memory starting at location zero to be used as a source of parity.
  84. *
  85. * RETURNS: N/A
  86. *
  87. */
  88. #define R_IC_SIZE t2
  89. #define R_IC_LINE t8
  90. #define R_DC_SIZE t3
  91. #define R_DC_LINE t9
  92. LEAF(mips_cache_reset)
  93. #ifndef CONFIG_SYS_CACHE_SIZE_AUTO
  94. li R_IC_SIZE, CONFIG_SYS_ICACHE_SIZE
  95. li R_IC_LINE, CONFIG_SYS_ICACHE_LINE_SIZE
  96. #else
  97. l1_info R_IC_SIZE, R_IC_LINE, MIPS_CONF1_IA_SHF
  98. #endif
  99. #ifndef CONFIG_SYS_CACHE_SIZE_AUTO
  100. li R_DC_SIZE, CONFIG_SYS_DCACHE_SIZE
  101. li R_DC_LINE, CONFIG_SYS_DCACHE_LINE_SIZE
  102. #else
  103. l1_info R_DC_SIZE, R_DC_LINE, MIPS_CONF1_DA_SHF
  104. #endif
  105. #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
  106. /* Determine the largest L1 cache size */
  107. #ifndef CONFIG_SYS_CACHE_SIZE_AUTO
  108. #if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE
  109. li v0, CONFIG_SYS_ICACHE_SIZE
  110. #else
  111. li v0, CONFIG_SYS_DCACHE_SIZE
  112. #endif
  113. #else
  114. move v0, R_IC_SIZE
  115. sltu t1, R_IC_SIZE, R_DC_SIZE
  116. movn v0, R_DC_SIZE, t1
  117. #endif
  118. /*
  119. * Now clear that much memory starting from zero.
  120. */
  121. PTR_LI a0, CKSEG1
  122. PTR_ADDU a1, a0, v0
  123. 2: PTR_ADDIU a0, 64
  124. f_fill64 a0, -64, zero
  125. bne a0, a1, 2b
  126. #endif /* CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD */
  127. /*
  128. * The TagLo registers used depend upon the CPU implementation, but the
  129. * architecture requires that it is safe for software to write to both
  130. * TagLo selects 0 & 2 covering supported cases.
  131. */
  132. mtc0 zero, CP0_TAGLO
  133. mtc0 zero, CP0_TAGLO, 2
  134. /*
  135. * The caches are probably in an indeterminate state, so we force good
  136. * parity into them by doing an invalidate for each line. If
  137. * CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD is set then we'll proceed to
  138. * perform a load/fill & a further invalidate for each line, assuming
  139. * that the bottom of RAM (having just been cleared) will generate good
  140. * parity for the cache.
  141. */
  142. /*
  143. * Initialize the I-cache first,
  144. */
  145. blez R_IC_SIZE, 1f
  146. PTR_LI t0, INDEX_BASE
  147. PTR_ADDU t1, t0, R_IC_SIZE
  148. /* clear tag to invalidate */
  149. cache_loop t0, t1, R_IC_LINE, INDEX_STORE_TAG_I
  150. #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
  151. /* fill once, so data field parity is correct */
  152. PTR_LI t0, INDEX_BASE
  153. cache_loop t0, t1, R_IC_LINE, FILL
  154. /* invalidate again - prudent but not strictly neccessary */
  155. PTR_LI t0, INDEX_BASE
  156. cache_loop t0, t1, R_IC_LINE, INDEX_STORE_TAG_I
  157. #endif
  158. /* Enable use of the I-cache by setting Config.K0 */
  159. sync
  160. mfc0 t0, CP0_CONFIG
  161. li t1, CONFIG_SYS_MIPS_CACHE_MODE
  162. #if __mips_isa_rev >= 2
  163. ins t0, t1, 0, 3
  164. #else
  165. ori t0, t0, CONF_CM_CMASK
  166. xori t0, t0, CONF_CM_CMASK
  167. or t0, t0, t1
  168. #endif
  169. mtc0 t0, CP0_CONFIG
  170. /*
  171. * then initialize D-cache.
  172. */
  173. 1: blez R_DC_SIZE, 3f
  174. PTR_LI t0, INDEX_BASE
  175. PTR_ADDU t1, t0, R_DC_SIZE
  176. /* clear all tags */
  177. cache_loop t0, t1, R_DC_LINE, INDEX_STORE_TAG_D
  178. #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
  179. /* load from each line (in cached space) */
  180. PTR_LI t0, INDEX_BASE
  181. 2: LONG_L zero, 0(t0)
  182. PTR_ADDU t0, R_DC_LINE
  183. bne t0, t1, 2b
  184. /* clear all tags */
  185. PTR_LI t0, INDEX_BASE
  186. cache_loop t0, t1, R_DC_LINE, INDEX_STORE_TAG_D
  187. #endif
  188. 3: jr ra
  189. END(mips_cache_reset)
  190. /*
  191. * dcache_status - get cache status
  192. *
  193. * RETURNS: 0 - cache disabled; 1 - cache enabled
  194. *
  195. */
  196. LEAF(dcache_status)
  197. mfc0 t0, CP0_CONFIG
  198. li t1, CONF_CM_UNCACHED
  199. andi t0, t0, CONF_CM_CMASK
  200. move v0, zero
  201. beq t0, t1, 2f
  202. li v0, 1
  203. 2: jr ra
  204. END(dcache_status)
  205. /*
  206. * dcache_disable - disable cache
  207. *
  208. * RETURNS: N/A
  209. *
  210. */
  211. LEAF(dcache_disable)
  212. mfc0 t0, CP0_CONFIG
  213. li t1, -8
  214. and t0, t0, t1
  215. ori t0, t0, CONF_CM_UNCACHED
  216. mtc0 t0, CP0_CONFIG
  217. jr ra
  218. END(dcache_disable)
  219. /*
  220. * dcache_enable - enable cache
  221. *
  222. * RETURNS: N/A
  223. *
  224. */
  225. LEAF(dcache_enable)
  226. mfc0 t0, CP0_CONFIG
  227. ori t0, CONF_CM_CMASK
  228. xori t0, CONF_CM_CMASK
  229. ori t0, CONFIG_SYS_MIPS_CACHE_MODE
  230. mtc0 t0, CP0_CONFIG
  231. jr ra
  232. END(dcache_enable)