cache.S 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*
  2. * File: arch/blackfin/mach-common/cache.S
  3. * Based on:
  4. * Author: LG Soft India
  5. *
  6. * Created:
  7. * Description: cache control support
  8. *
  9. * Modified:
  10. * Copyright 2004-2006 Analog Devices Inc.
  11. *
  12. * Bugs: Enter bugs at http://blackfin.uclinux.org/
  13. *
  14. * This program is free software; you can redistribute it and/or modify
  15. * it under the terms of the GNU General Public License as published by
  16. * the Free Software Foundation; either version 2 of the License, or
  17. * (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, see the file COPYING, or write
  26. * to the Free Software Foundation, Inc.,
  27. * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  28. */
  29. #include <linux/linkage.h>
  30. #include <asm/cplb.h>
  31. #include <asm/entry.h>
  32. #include <asm/blackfin.h>
  33. #include <asm/cache.h>
  34. .text
  35. .align 2
  36. ENTRY(_cache_invalidate)
  37. /*
  38. * Icache or DcacheA or DcacheB Invalidation
  39. * or any combination thereof
  40. * R0 has bits
  41. * CPLB_ENABLE_ICACHE_P,CPLB_ENABLE_DCACHE_P,CPLB_ENABLE_DCACHE2_P
  42. * set as required
  43. */
  44. [--SP] = R7;
  45. R7 = R0;
  46. CC = BITTST(R7,CPLB_ENABLE_ICACHE_P);
  47. IF !CC JUMP .Lno_icache;
  48. [--SP] = RETS;
  49. CALL _icache_invalidate;
  50. RETS = [SP++];
  51. .Lno_icache:
  52. CC = BITTST(R7,CPLB_ENABLE_DCACHE_P);
  53. IF !CC JUMP .Lno_dcache_a;
  54. R0 = 0; /* specifies bank A */
  55. [--SP] = RETS;
  56. CALL _dcache_invalidate;
  57. RETS = [SP++];
  58. .Lno_dcache_a:
  59. CC = BITTST(R7,CPLB_ENABLE_DCACHE2_P);
  60. IF !CC JUMP .Lno_dcache_b;
  61. R0 = 0;
  62. BITSET(R0, 23); /* specifies bank B */
  63. [--SP] = RETS;
  64. CALL _dcache_invalidate;
  65. RETS = [SP++];
  66. .Lno_dcache_b:
  67. R7 = [SP++];
  68. RTS;
  69. /* Invalidate the Entire Instruction cache by
  70. * disabling IMC bit
  71. */
  72. ENTRY(_icache_invalidate)
  73. ENTRY(_invalidate_entire_icache)
  74. [--SP] = ( R7:5);
  75. P0.L = (IMEM_CONTROL & 0xFFFF);
  76. P0.H = (IMEM_CONTROL >> 16);
  77. R7 = [P0];
  78. /* Clear the IMC bit , All valid bits in the instruction
  79. * cache are set to the invalid state
  80. */
  81. BITCLR(R7,IMC_P);
  82. CLI R6;
  83. SSYNC; /* SSYNC required before invalidating cache. */
  84. .align 8;
  85. [P0] = R7;
  86. SSYNC;
  87. STI R6;
  88. /* Configures the instruction cache agian */
  89. R6 = (IMC | ENICPLB);
  90. R7 = R7 | R6;
  91. CLI R6;
  92. SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
  93. .align 8;
  94. [P0] = R7;
  95. SSYNC;
  96. STI R6;
  97. ( R7:5) = [SP++];
  98. RTS;
  99. /*
  100. * blackfin_cache_flush_range(start, end)
  101. * Invalidate all cache lines assocoiated with this
  102. * area of memory.
  103. *
  104. * start: Start address
  105. * end: End address
  106. */
  107. ENTRY(_blackfin_icache_flush_range)
  108. R2 = -L1_CACHE_BYTES;
  109. R2 = R0 & R2;
  110. P0 = R2;
  111. P1 = R1;
  112. CSYNC;
  113. IFLUSH [P0];
  114. 1:
  115. IFLUSH [P0++];
  116. CC = P0 < P1 (iu);
  117. IF CC JUMP 1b (bp);
  118. IFLUSH [P0];
  119. SSYNC;
  120. RTS;
  121. /*
  122. * blackfin_icache_dcache_flush_range(start, end)
  123. * FLUSH all cache lines assocoiated with this
  124. * area of memory.
  125. *
  126. * start: Start address
  127. * end: End address
  128. */
  129. ENTRY(_blackfin_icache_dcache_flush_range)
  130. R2 = -L1_CACHE_BYTES;
  131. R2 = R0 & R2;
  132. P0 = R2;
  133. P1 = R1;
  134. CSYNC;
  135. IFLUSH [P0];
  136. 1:
  137. FLUSH [P0];
  138. IFLUSH [P0++];
  139. CC = P0 < P1 (iu);
  140. IF CC JUMP 1b (bp);
  141. IFLUSH [P0];
  142. FLUSH [P0];
  143. SSYNC;
  144. RTS;
  145. /* Throw away all D-cached data in specified region without any obligation to
  146. * write them back. However, we must clean the D-cached entries around the
  147. * boundaries of the start and/or end address is not cache aligned.
  148. *
  149. * Start: start address,
  150. * end : end address.
  151. */
  152. ENTRY(_blackfin_dcache_invalidate_range)
  153. R2 = -L1_CACHE_BYTES;
  154. R2 = R0 & R2;
  155. P0 = R2;
  156. P1 = R1;
  157. CSYNC;
  158. FLUSHINV[P0];
  159. 1:
  160. FLUSHINV[P0++];
  161. CC = P0 < P1 (iu);
  162. IF CC JUMP 1b (bp);
  163. /* If the data crosses a cache line, then we'll be pointing to
  164. * the last cache line, but won't have flushed/invalidated it yet,
  165. * so do one more.
  166. */
  167. FLUSHINV[P0];
  168. SSYNC;
  169. RTS;
  170. /* Invalidate the Entire Data cache by
  171. * clearing DMC[1:0] bits
  172. */
  173. ENTRY(_invalidate_entire_dcache)
  174. ENTRY(_dcache_invalidate)
  175. [--SP] = ( R7:6);
  176. P0.L = (DMEM_CONTROL & 0xFFFF);
  177. P0.H = (DMEM_CONTROL >> 16);
  178. R7 = [P0];
  179. /* Clear the DMC[1:0] bits, All valid bits in the data
  180. * cache are set to the invalid state
  181. */
  182. BITCLR(R7,DMC0_P);
  183. BITCLR(R7,DMC1_P);
  184. CLI R6;
  185. SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
  186. .align 8;
  187. [P0] = R7;
  188. SSYNC;
  189. STI R6;
  190. /* Configures the data cache again */
  191. R6 = DMEM_CNTR;
  192. R7 = R7 | R6;
  193. CLI R6;
  194. SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
  195. .align 8;
  196. [P0] = R7;
  197. SSYNC;
  198. STI R6;
  199. ( R7:6) = [SP++];
  200. RTS;
  201. ENTRY(_blackfin_dcache_flush_range)
  202. R2 = -L1_CACHE_BYTES;
  203. R2 = R0 & R2;
  204. P0 = R2;
  205. P1 = R1;
  206. CSYNC;
  207. FLUSH[P0];
  208. 1:
  209. FLUSH[P0++];
  210. CC = P0 < P1 (iu);
  211. IF CC JUMP 1b (bp);
  212. /* If the data crosses a cache line, then we'll be pointing to
  213. * the last cache line, but won't have flushed it yet, so do
  214. * one more.
  215. */
  216. FLUSH[P0];
  217. SSYNC;
  218. RTS;
  219. ENTRY(_blackfin_dflush_page)
  220. P1 = 1 << (PAGE_SHIFT - L1_CACHE_SHIFT);
  221. P0 = R0;
  222. CSYNC;
  223. FLUSH[P0];
  224. LSETUP (.Lfl1, .Lfl1) LC0 = P1;
  225. .Lfl1: FLUSH [P0++];
  226. SSYNC;
  227. RTS;