mips64_cache.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:7k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * mips64_cache.h
  3.  *
  4.  * Carsten Langgaard, carstenl@mips.com
  5.  * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
  6.  *
  7.  * ########################################################################
  8.  *
  9.  *  This program is free software; you can distribute it and/or modify it
  10.  *  under the terms of the GNU General Public License (Version 2) as
  11.  *  published by the Free Software Foundation.
  12.  *
  13.  *  This program is distributed in the hope it will be useful, but WITHOUT
  14.  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15.  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16.  *  for more details.
  17.  *
  18.  *  You should have received a copy of the GNU General Public License along
  19.  *  with this program; if not, write to the Free Software Foundation, Inc.,
  20.  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  21.  *
  22.  * ########################################################################
  23.  *
  24.  * Inline assembly cache operations.
  25.  *
  26.  * This file is the original r4cache.c file with modification that makes the
  27.  * cache handling more generic.
  28.  *
  29.  * FIXME: Handle split L2 caches.
  30.  *
  31.  */
  32. #ifndef _MIPS_MIPS64_CACHE_H
  33. #define _MIPS_MIPS64_CACHE_H
  34. #include <asm/asm.h>
  35. #include <asm/cacheops.h>
  36. static inline void flush_icache_line_indexed(unsigned long addr)
  37. {
  38. unsigned long waystep = icache_size/mips_cpu.icache.ways;
  39. unsigned int way;
  40. for (way = 0; way < mips_cpu.icache.ways; way++)
  41. {
  42. __asm__ __volatile__(
  43. ".set noreordernt"
  44. "cache %1, (%0)nt"
  45. ".set reorder"
  46. :
  47. : "r" (addr),
  48. "i" (Index_Invalidate_I));
  49. addr += waystep;
  50. }
  51. }
  52. static inline void flush_dcache_line_indexed(unsigned long addr)
  53. {
  54. unsigned long waystep = dcache_size/mips_cpu.dcache.ways;
  55. unsigned int way;
  56. for (way = 0; way < mips_cpu.dcache.ways; way++)
  57. {
  58. __asm__ __volatile__(
  59. ".set noreordernt"
  60. "cache %1, (%0)nt"
  61. ".set reorder"
  62. :
  63. : "r" (addr),
  64. "i" (Index_Writeback_Inv_D));
  65. addr += waystep;
  66. }
  67. }
  68. static inline void flush_scache_line_indexed(unsigned long addr)
  69. {
  70. unsigned long waystep = scache_size/mips_cpu.scache.ways;
  71. unsigned int way;
  72. for (way = 0; way < mips_cpu.scache.ways; way++)
  73. {
  74. __asm__ __volatile__(
  75. ".set noreordernt"
  76. "cache %1, (%0)nt"
  77. ".set reorder"
  78. :
  79. : "r" (addr),
  80. "i" (Index_Writeback_Inv_SD));
  81. addr += waystep;
  82. }
  83. }
  84. static inline void flush_icache_line(unsigned long addr)
  85. {
  86. __asm__ __volatile__(
  87. ".set noreordernt"
  88. "cache %1, (%0)nt"
  89. ".set reorder"
  90. :
  91. : "r" (addr),
  92.   "i" (Hit_Invalidate_I));
  93. }
  94. static inline void flush_dcache_line(unsigned long addr)
  95. {
  96. __asm__ __volatile__(
  97. ".set noreordernt"
  98. "cache %1, (%0)nt"
  99. ".set reorder"
  100. :
  101. : "r" (addr),
  102.   "i" (Hit_Writeback_Inv_D));
  103. }
  104. static inline void invalidate_dcache_line(unsigned long addr)
  105. {
  106. __asm__ __volatile__(
  107. ".set noreordernt"
  108. "cache %1, (%0)nt"
  109. ".set reorder"
  110. :
  111. : "r" (addr),
  112.   "i" (Hit_Invalidate_D));
  113. }
  114. static inline void invalidate_scache_line(unsigned long addr)
  115. {
  116. __asm__ __volatile__(
  117. ".set noreordernt"
  118. "cache %1, (%0)nt"
  119. ".set reorder"
  120. :
  121. : "r" (addr),
  122.   "i" (Hit_Invalidate_SD));
  123. }
  124. static inline void flush_scache_line(unsigned long addr)
  125. {
  126. __asm__ __volatile__(
  127. ".set noreordernt"
  128. "cache %1, (%0)nt"
  129. ".set reorder"
  130. :
  131. : "r" (addr),
  132.   "i" (Hit_Writeback_Inv_SD));
  133. }
  134. /*
  135.  * The next two are for badland addresses like signal trampolines.
  136.  */
  137. static inline void protected_flush_icache_line(unsigned long addr)
  138. {
  139. __asm__ __volatile__(
  140. ".set noreordernt"
  141. "1:tcache %1,(%0)n"
  142. "2:t.set reordernt"
  143. ".sectiont__ex_table,"a"nt"
  144. ".dwordt1b,2bnt"
  145. ".previous"
  146. :
  147. : "r" (addr), "i" (Hit_Invalidate_I));
  148. }
  149. static inline void protected_writeback_dcache_line(unsigned long addr)
  150. {
  151. __asm__ __volatile__(
  152. ".set noreordernt"
  153. "1:tcache %1,(%0)n"
  154. "2:t.set reordernt"
  155. ".sectiont__ex_table,"a"nt"
  156. ".dwordt1b,2bnt"
  157. ".previous"
  158. :
  159. : "r" (addr), "i" (Hit_Writeback_D));
  160. }
  161. #define cache_unroll(base,op)
  162. __asm__ __volatile__("
  163. .set noreorder;
  164. cache %1, (%0);
  165. .set reorder"
  166. :
  167. : "r" (base),
  168.   "i" (op));
  169. static inline void blast_dcache(void)
  170. {
  171. unsigned long start = KSEG0;
  172. unsigned long end = (start + dcache_size);
  173. while(start < end) {
  174. cache_unroll(start,Index_Writeback_Inv_D);
  175. start += dc_lsize;
  176. }
  177. }
  178. static inline void blast_dcache_page(unsigned long page)
  179. {
  180. unsigned long start = page;
  181. unsigned long end = (start + PAGE_SIZE);
  182. while(start < end) {
  183. cache_unroll(start,Hit_Writeback_Inv_D);
  184. start += dc_lsize;
  185. }
  186. }
  187. static inline void blast_dcache_page_indexed(unsigned long page)
  188. {
  189. unsigned long start;
  190. unsigned long end = (page + PAGE_SIZE);
  191. unsigned long waystep = dcache_size/mips_cpu.dcache.ways;
  192. unsigned int way;
  193. for (way = 0; way < mips_cpu.dcache.ways; way++) {
  194. start = page + way*waystep;
  195. while(start < end) {
  196. cache_unroll(start,Index_Writeback_Inv_D);
  197. start += dc_lsize;
  198. }
  199. }
  200. }
  201. static inline void blast_icache(void)
  202. {
  203. unsigned long start = KSEG0;
  204. unsigned long end = (start + icache_size);
  205. while(start < end) {
  206. cache_unroll(start,Index_Invalidate_I);
  207. start += ic_lsize;
  208. }
  209. }
  210. static inline void blast_icache_page(unsigned long page)
  211. {
  212. unsigned long start = page;
  213. unsigned long end = (start + PAGE_SIZE);
  214. while(start < end) {
  215. cache_unroll(start,Hit_Invalidate_I);
  216. start += ic_lsize;
  217. }
  218. }
  219. static inline void blast_icache_page_indexed(unsigned long page)
  220. {
  221. unsigned long start;
  222. unsigned long end = (page + PAGE_SIZE);
  223. unsigned long waystep = icache_size/mips_cpu.icache.ways;
  224. unsigned int way;
  225. for (way = 0; way < mips_cpu.icache.ways; way++) {
  226. start = page + way*waystep;
  227. while(start < end) {
  228. cache_unroll(start,Index_Invalidate_I);
  229. start += ic_lsize;
  230. }
  231. }
  232. }
  233. static inline void blast_scache(void)
  234. {
  235. unsigned long start = KSEG0;
  236. unsigned long end = KSEG0 + scache_size;
  237. while(start < end) {
  238. cache_unroll(start,Index_Writeback_Inv_SD);
  239. start += sc_lsize;
  240. }
  241. }
  242. static inline void blast_scache_page(unsigned long page)
  243. {
  244. unsigned long start = page;
  245. unsigned long end = page + PAGE_SIZE;
  246. while(start < end) {
  247. cache_unroll(start,Hit_Writeback_Inv_SD);
  248. start += sc_lsize;
  249. }
  250. }
  251. static inline void blast_scache_page_indexed(unsigned long page)
  252. {
  253. unsigned long start;
  254. unsigned long end = (page + PAGE_SIZE);
  255. unsigned long waystep = scache_size/mips_cpu.scache.ways;
  256. unsigned int way;
  257. for (way = 0; way < mips_cpu.scache.ways; way++) {
  258. start = page + way*waystep;
  259. while(start < end) {
  260. cache_unroll(start,Index_Writeback_Inv_SD);
  261. start += sc_lsize;
  262. }
  263. }
  264. }
  265. #endif /* !(_MIPS_MIPS64_CACHE_H) */