r10kcache.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:11k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Inline assembly cache operations.
  7.  *
  8.  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  9.  * Copyright (C) 1999 Ralf Baechle
  10.  * Copyright (C) 1999 Silicon Graphics, Inc.
  11.  *
  12.  * FIXME: Handle split L2 caches.
  13.  */
  14. #ifndef _ASM_R10KCACHE_H
  15. #define _ASM_R10KCACHE_H
  16. #include <asm/asm.h>
  17. #include <asm/r10kcacheops.h>
  18. /* These are fixed for the current R10000.  */
  19. #define icache_size 0x8000
  20. #define dcache_size 0x8000
  21. #define icache_way_size 0x4000
  22. #define dcache_way_size 0x4000
  23. #define ic_lsize 64
  24. #define dc_lsize 32
  25. /* These are configuration dependant.  */
  26. #define scache_size() ({
  27. unsigned long __res;
  28. __res = (read_32bit_cp0_register(CP0_CONFIG) >> 16) & 3;
  29. __res = 1 << (__res + 19);
  30. __res;
  31. })
  32. #define sc_lsize() ({
  33. unsigned long __res;
  34. __res = (read_32bit_cp0_register(CP0_CONFIG) >> 13) & 1;
  35. __res = 1 << (__res + 6);
  36. __res;
  37. })
  38. extern inline void flush_icache_line_indexed(unsigned long addr)
  39. {
  40. __asm__ __volatile__(
  41. ".set noreordernt"
  42. "cache %1, (%0)nt"
  43. ".set reorder"
  44. :
  45. : "r" (addr), "i" (Index_Invalidate_I));
  46. }
  47. extern inline void flush_dcache_line_indexed(unsigned long addr)
  48. {
  49. __asm__ __volatile__(
  50. ".set noreordernt"
  51. "cache %1, (%0)nt"
  52. ".set reorder"
  53. :
  54. : "r" (addr), "i" (Index_Writeback_Inv_D));
  55. }
  56. extern inline void flush_scache_line_indexed(unsigned long addr)
  57. {
  58. __asm__ __volatile__(
  59. ".set noreordernt"
  60. "cache %1, (%0)nt"
  61. ".set reorder"
  62. :
  63. : "r" (addr), "i" (Index_Writeback_Inv_S));
  64. }
  65. extern inline void flush_icache_line(unsigned long addr)
  66. {
  67. __asm__ __volatile__(
  68. ".set noreordernt"
  69. "cache %1, (%0)nt"
  70. ".set reorder"
  71. :
  72. : "r" (addr), "i" (Hit_Invalidate_I));
  73. }
  74. extern inline void flush_dcache_line(unsigned long addr)
  75. {
  76. __asm__ __volatile__(
  77. ".set noreordernt"
  78. "cache %1, (%0)nt"
  79. ".set reorder"
  80. :
  81. : "r" (addr), "i" (Hit_Writeback_Inv_D));
  82. }
  83. extern inline void invalidate_dcache_line(unsigned long addr)
  84. {
  85. __asm__ __volatile__(
  86. ".set noreordernt"
  87. "cache %1, (%0)nt"
  88. ".set reorder"
  89. :
  90. : "r" (addr), "i" (Hit_Invalidate_D));
  91. }
  92. extern inline void invalidate_scache_line(unsigned long addr)
  93. {
  94. __asm__ __volatile__(
  95. ".set noreordernt"
  96. "cache %1, (%0)nt"
  97. ".set reorder"
  98. :
  99. : "r" (addr), "i" (Hit_Invalidate_S));
  100. }
  101. extern inline void flush_scache_line(unsigned long addr)
  102. {
  103. __asm__ __volatile__(
  104. ".set noreordernt"
  105. "cache %1, (%0)nt"
  106. ".set reorder"
  107. :
  108. : "r" (addr), "i" (Hit_Writeback_Inv_S));
  109. }
  110. /*
  111.  * The next two are for badland addresses like signal trampolines.
  112.  */
  113. extern inline void protected_flush_icache_line(unsigned long addr)
  114. {
  115. __asm__ __volatile__(
  116. ".set noreordernt"
  117. "1:tcache %1,(%0)n"
  118. "2:t.set reordernt"
  119. ".sectiont__ex_table,"a"nt"
  120. ".dwordt1b,2bnt"
  121. ".previous"
  122. :
  123. : "r" (addr), "i" (Hit_Invalidate_I));
  124. }
  125. extern inline void protected_writeback_dcache_line(unsigned long addr)
  126. {
  127. __asm__ __volatile__(
  128. ".set noreordernt"
  129. "1:tcache %1,(%0)n"
  130. "2:t.set reordernt"
  131. ".sectiont__ex_table,"a"nt"
  132. ".dwordt1b,2bnt"
  133. ".previous"
  134. :
  135. : "r" (addr), "i" (Hit_Writeback_Inv_D));
  136. }
  137. #define cache32_unroll16(base,op)
  138. __asm__ __volatile__("
  139. .set noreorder;
  140. cache %1, 0x000(%0); cache %1, 0x020(%0);
  141. cache %1, 0x040(%0); cache %1, 0x060(%0);
  142. cache %1, 0x080(%0); cache %1, 0x0a0(%0);
  143. cache %1, 0x0c0(%0); cache %1, 0x0e0(%0);
  144. cache %1, 0x100(%0); cache %1, 0x120(%0);
  145. cache %1, 0x140(%0); cache %1, 0x160(%0);
  146. cache %1, 0x180(%0); cache %1, 0x1a0(%0);
  147. cache %1, 0x1c0(%0); cache %1, 0x1e0(%0);
  148. .set reorder"
  149. :
  150. : "r" (base),
  151.   "i" (op));
  152. #define cache32_unroll32(base,op)
  153. __asm__ __volatile__("
  154. .set noreorder;
  155. cache %1, 0x000(%0); cache %1, 0x020(%0);
  156. cache %1, 0x040(%0); cache %1, 0x060(%0);
  157. cache %1, 0x080(%0); cache %1, 0x0a0(%0);
  158. cache %1, 0x0c0(%0); cache %1, 0x0e0(%0);
  159. cache %1, 0x100(%0); cache %1, 0x120(%0);
  160. cache %1, 0x140(%0); cache %1, 0x160(%0);
  161. cache %1, 0x180(%0); cache %1, 0x1a0(%0);
  162. cache %1, 0x1c0(%0); cache %1, 0x1e0(%0);
  163. cache %1, 0x200(%0); cache %1, 0x220(%0);
  164. cache %1, 0x240(%0); cache %1, 0x260(%0);
  165. cache %1, 0x280(%0); cache %1, 0x2a0(%0);
  166. cache %1, 0x2c0(%0); cache %1, 0x2e0(%0);
  167. cache %1, 0x300(%0); cache %1, 0x320(%0);
  168. cache %1, 0x340(%0); cache %1, 0x360(%0);
  169. cache %1, 0x380(%0); cache %1, 0x3a0(%0);
  170. cache %1, 0x3c0(%0); cache %1, 0x3e0(%0);
  171. .set reorder"
  172. :
  173. : "r" (base),
  174.   "i" (op));
  175. extern inline void blast_dcache32(void)
  176. {
  177. unsigned long way0 = KSEG0;
  178. unsigned long way1 = way0 ^ 1;
  179. unsigned long end = (way0 + dcache_way_size);
  180. while (way0 < end) {
  181. cache32_unroll16(way0, Index_Writeback_Inv_D);
  182. cache32_unroll16(way1, Index_Writeback_Inv_D);
  183. way0 += 0x200;
  184. way1 += 0x200;
  185. }
  186. }
  187. extern inline void blast_dcache32_page(unsigned long page)
  188. {
  189. unsigned long start = page;
  190. unsigned long end = page + PAGE_SIZE;
  191. while (start < end) {
  192. cache32_unroll32(start, Hit_Writeback_Inv_D);
  193. start += 0x400;
  194. }
  195. }
  196. extern inline void blast_dcache32_page_indexed(unsigned long page)
  197. {
  198. unsigned long way0 = page;
  199. unsigned long way1 = page ^ 1;
  200. unsigned long end = page + PAGE_SIZE;
  201. while (way0 < end) {
  202. cache32_unroll16(way0, Index_Writeback_Inv_D);
  203. cache32_unroll16(way1, Index_Writeback_Inv_D);
  204. way0 += 0x200;
  205. way1 += 0x200;
  206. }
  207. }
  208. #define cache64_unroll16(base,op)
  209. __asm__ __volatile__("
  210. .set noreorder;
  211. cache %1, 0x000(%0); cache %1, 0x040(%0);
  212. cache %1, 0x080(%0); cache %1, 0x0c0(%0);
  213. cache %1, 0x100(%0); cache %1, 0x140(%0);
  214. cache %1, 0x180(%0); cache %1, 0x1c0(%0);
  215. cache %1, 0x200(%0); cache %1, 0x240(%0);
  216. cache %1, 0x280(%0); cache %1, 0x2c0(%0);
  217. cache %1, 0x300(%0); cache %1, 0x340(%0);
  218. cache %1, 0x380(%0); cache %1, 0x3c0(%0);
  219. .set reorder"
  220. :
  221. : "r" (base),
  222.   "i" (op));
  223. #define cache64_unroll32(base,op)
  224. __asm__ __volatile__("
  225. .set noreorder;
  226. cache %1, 0x000(%0); cache %1, 0x040(%0);
  227. cache %1, 0x080(%0); cache %1, 0x0c0(%0);
  228. cache %1, 0x100(%0); cache %1, 0x140(%0);
  229. cache %1, 0x180(%0); cache %1, 0x1c0(%0);
  230. cache %1, 0x200(%0); cache %1, 0x240(%0);
  231. cache %1, 0x280(%0); cache %1, 0x2c0(%0);
  232. cache %1, 0x300(%0); cache %1, 0x340(%0);
  233. cache %1, 0x380(%0); cache %1, 0x3c0(%0);
  234. cache %1, 0x400(%0); cache %1, 0x440(%0);
  235. cache %1, 0x480(%0); cache %1, 0x4c0(%0);
  236. cache %1, 0x500(%0); cache %1, 0x540(%0);
  237. cache %1, 0x580(%0); cache %1, 0x5c0(%0);
  238. cache %1, 0x600(%0); cache %1, 0x640(%0);
  239. cache %1, 0x680(%0); cache %1, 0x6c0(%0);
  240. cache %1, 0x700(%0); cache %1, 0x740(%0);
  241. cache %1, 0x780(%0); cache %1, 0x7c0(%0);
  242. .set reorder"
  243. :
  244. : "r" (base),
  245.   "i" (op));
  246. extern inline void blast_icache64(void)
  247. {
  248. unsigned long way0 = KSEG0;
  249. unsigned long way1 = way0 ^ 1;
  250. unsigned long end = way0 + icache_way_size;
  251. while (way0 < end) {
  252. cache64_unroll16(way0,Index_Invalidate_I);
  253. cache64_unroll16(way1,Index_Invalidate_I);
  254. way0 += 0x400;
  255. way1 += 0x400;
  256. }
  257. }
  258. extern inline void blast_icache64_page(unsigned long page)
  259. {
  260. unsigned long start = page;
  261. unsigned long end = page + PAGE_SIZE;
  262. while (start < end) {
  263. cache64_unroll32(start,Hit_Invalidate_I);
  264. start += 0x800;
  265. }
  266. }
  267. extern inline void blast_icache64_page_indexed(unsigned long page)
  268. {
  269. unsigned long way0 = page;
  270. unsigned long way1 = page ^ 1;
  271. unsigned long end = page + PAGE_SIZE;
  272. while (way0 < end) {
  273. cache64_unroll16(way0,Index_Invalidate_I);
  274. cache64_unroll16(way1,Index_Invalidate_I);
  275. way0 += 0x400;
  276. way1 += 0x400;
  277. }
  278. }
  279. extern inline void blast_scache64(void)
  280. {
  281. unsigned long way0 = KSEG0;
  282. unsigned long way1 = way0 ^ 1;
  283. unsigned long end = KSEG0 + scache_size();
  284. while (way0 < end) {
  285. cache64_unroll16(way0,Index_Writeback_Inv_S);
  286. cache64_unroll16(way1,Index_Writeback_Inv_S);
  287. way0 += 0x400;
  288. way1 += 0x400;
  289. }
  290. }
  291. extern inline void blast_scache64_page(unsigned long page)
  292. {
  293. unsigned long start = page;
  294. unsigned long end = page + PAGE_SIZE;
  295. while (start < end) {
  296. cache64_unroll32(start,Hit_Writeback_Inv_S);
  297. start += 0x800;
  298. }
  299. }
  300. extern inline void blast_scache64_page_indexed(unsigned long page)
  301. {
  302. unsigned long way0 = page;
  303. unsigned long way1 = page ^ 1;
  304. unsigned long end = page + PAGE_SIZE;
  305. while (way0 < end) {
  306. cache64_unroll16(way0,Index_Writeback_Inv_S);
  307. cache64_unroll16(way1,Index_Writeback_Inv_S);
  308. way0 += 0x400;
  309. way1 += 0x400;
  310. }
  311. }
  312. #define cache128_unroll16(base,op)
  313. __asm__ __volatile__("
  314. .set noreorder;
  315. cache %1, 0x000(%0); cache %1, 0x080(%0);
  316. cache %1, 0x100(%0); cache %1, 0x180(%0);
  317. cache %1, 0x200(%0); cache %1, 0x280(%0);
  318. cache %1, 0x300(%0); cache %1, 0x380(%0);
  319. cache %1, 0x400(%0); cache %1, 0x480(%0);
  320. cache %1, 0x500(%0); cache %1, 0x580(%0);
  321. cache %1, 0x600(%0); cache %1, 0x680(%0);
  322. cache %1, 0x700(%0); cache %1, 0x780(%0);
  323. .set reorder"
  324. :
  325. : "r" (base),
  326.   "i" (op));
  327. #define cache128_unroll32(base,op)
  328. __asm__ __volatile__("
  329. .set noreorder;
  330. cache %1, 0x000(%0); cache %1, 0x080(%0);
  331. cache %1, 0x100(%0); cache %1, 0x180(%0);
  332. cache %1, 0x200(%0); cache %1, 0x280(%0);
  333. cache %1, 0x300(%0); cache %1, 0x380(%0);
  334. cache %1, 0x400(%0); cache %1, 0x480(%0);
  335. cache %1, 0x500(%0); cache %1, 0x580(%0);
  336. cache %1, 0x600(%0); cache %1, 0x680(%0);
  337. cache %1, 0x700(%0); cache %1, 0x780(%0);
  338. cache %1, 0x800(%0); cache %1, 0x880(%0);
  339. cache %1, 0x900(%0); cache %1, 0x980(%0);
  340. cache %1, 0xa00(%0); cache %1, 0xa80(%0);
  341. cache %1, 0xb00(%0); cache %1, 0xb80(%0);
  342. cache %1, 0xc00(%0); cache %1, 0xc80(%0);
  343. cache %1, 0xd00(%0); cache %1, 0xd80(%0);
  344. cache %1, 0xe00(%0); cache %1, 0xe80(%0);
  345. cache %1, 0xf00(%0); cache %1, 0xf80(%0);
  346. .set reorder"
  347. :
  348. : "r" (base),
  349.   "i" (op));
  350. extern inline void blast_scache128(void)
  351. {
  352. unsigned long way0 = KSEG0;
  353. unsigned long way1 = way0 ^ 1;
  354. unsigned long end = way0 + scache_size();
  355. while (way0 < end) {
  356. cache128_unroll16(way0, Index_Writeback_Inv_S);
  357. cache128_unroll16(way1, Index_Writeback_Inv_S);
  358. way0 += 0x800;
  359. way1 += 0x800;
  360. }
  361. }
  362. extern inline void blast_scache128_page(unsigned long page)
  363. {
  364. cache128_unroll32(page, Hit_Writeback_Inv_S);
  365. }
  366. extern inline void blast_scache128_page_indexed(unsigned long page)
  367. {
  368. cache128_unroll32(page    , Index_Writeback_Inv_S);
  369. cache128_unroll32(page ^ 1, Index_Writeback_Inv_S);
  370. }
  371. #endif /* _ASM_R10KCACHE_H */