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

嵌入式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.  *
  10.  * FIXME: Handle split L2 caches.
  11.  */
  12. #ifndef _ASM_R4KCACHE_H
  13. #define _ASM_R4KCACHE_H
  14. #include <asm/asm.h>
  15. #include <asm/r4kcacheops.h>
  16. extern inline void flush_icache_line_indexed(unsigned long addr)
  17. {
  18. __asm__ __volatile__(
  19. ".set noreordernt"
  20. "cache %1, (%0)nt"
  21. ".set reorder"
  22. :
  23. : "r" (addr), "i" (Index_Invalidate_I));
  24. }
  25. extern inline void flush_dcache_line_indexed(unsigned long addr)
  26. {
  27. __asm__ __volatile__(
  28. ".set noreordernt"
  29. "cache %1, (%0)nt"
  30. ".set reorder"
  31. :
  32. : "r" (addr), "i" (Index_Writeback_Inv_D));
  33. }
  34. extern inline void flush_scache_line_indexed(unsigned long addr)
  35. {
  36. __asm__ __volatile__(
  37. ".set noreordernt"
  38. "cache %1, (%0)nt"
  39. ".set reorder"
  40. :
  41. : "r" (addr), "i" (Index_Writeback_Inv_SD));
  42. }
  43. extern inline void flush_icache_line(unsigned long addr)
  44. {
  45. __asm__ __volatile__(
  46. ".set noreordernt"
  47. "cache %1, (%0)nt"
  48. ".set reorder"
  49. :
  50. : "r" (addr), "i" (Hit_Invalidate_I));
  51. }
  52. extern inline void flush_dcache_line(unsigned long addr)
  53. {
  54. __asm__ __volatile__(
  55. ".set noreordernt"
  56. "cache %1, (%0)nt"
  57. ".set reorder"
  58. :
  59. : "r" (addr), "i" (Hit_Writeback_Inv_D));
  60. }
  61. extern inline void invalidate_dcache_line(unsigned long addr)
  62. {
  63. __asm__ __volatile__(
  64. ".set noreordernt"
  65. "cache %1, (%0)nt"
  66. ".set reorder"
  67. :
  68. : "r" (addr), "i" (Hit_Invalidate_D));
  69. }
  70. extern inline void invalidate_scache_line(unsigned long addr)
  71. {
  72. __asm__ __volatile__(
  73. ".set noreordernt"
  74. "cache %1, (%0)nt"
  75. ".set reorder"
  76. :
  77. : "r" (addr), "i" (Hit_Invalidate_SD));
  78. }
  79. extern inline void flush_scache_line(unsigned long addr)
  80. {
  81. __asm__ __volatile__(
  82. ".set noreordernt"
  83. "cache %1, (%0)nt"
  84. ".set reorder"
  85. :
  86. : "r" (addr), "i" (Hit_Writeback_Inv_SD));
  87. }
  88. /*
  89.  * The next two are for badland addresses like signal trampolines.
  90.  */
  91. extern inline void protected_flush_icache_line(unsigned long addr)
  92. {
  93. __asm__ __volatile__(
  94. ".set noreordernt"
  95. "1:tcache %1,(%0)n"
  96. "2:t.set reordernt"
  97. ".sectiont__ex_table,"a"nt"
  98. ".dwordt1b,2bnt"
  99. ".previous"
  100. :
  101. : "r" (addr), "i" (Hit_Invalidate_I));
  102. }
  103. extern inline void protected_writeback_dcache_line(unsigned long addr)
  104. {
  105. __asm__ __volatile__(
  106. ".set noreordernt"
  107. "1:tcache %1,(%0)n"
  108. "2:t.set reordernt"
  109. ".sectiont__ex_table,"a"nt"
  110. ".dwordt1b,2bnt"
  111. ".previous"
  112. :
  113. : "r" (addr), "i" (Hit_Writeback_D));
  114. }
  115. #define cache16_unroll32(base,op)
  116. __asm__ __volatile__("
  117. .set noreorder;
  118. cache %1, 0x000(%0); cache %1, 0x010(%0);
  119. cache %1, 0x020(%0); cache %1, 0x030(%0);
  120. cache %1, 0x040(%0); cache %1, 0x050(%0);
  121. cache %1, 0x060(%0); cache %1, 0x070(%0);
  122. cache %1, 0x080(%0); cache %1, 0x090(%0);
  123. cache %1, 0x0a0(%0); cache %1, 0x0b0(%0);
  124. cache %1, 0x0c0(%0); cache %1, 0x0d0(%0);
  125. cache %1, 0x0e0(%0); cache %1, 0x0f0(%0);
  126. cache %1, 0x100(%0); cache %1, 0x110(%0);
  127. cache %1, 0x120(%0); cache %1, 0x130(%0);
  128. cache %1, 0x140(%0); cache %1, 0x150(%0);
  129. cache %1, 0x160(%0); cache %1, 0x170(%0);
  130. cache %1, 0x180(%0); cache %1, 0x190(%0);
  131. cache %1, 0x1a0(%0); cache %1, 0x1b0(%0);
  132. cache %1, 0x1c0(%0); cache %1, 0x1d0(%0);
  133. cache %1, 0x1e0(%0); cache %1, 0x1f0(%0);
  134. .set reorder"
  135. :
  136. : "r" (base),
  137.   "i" (op));
  138. extern inline void blast_dcache16(void)
  139. {
  140. unsigned long start = KSEG0;
  141. unsigned long end = (start + dcache_size);
  142. while(start < end) {
  143. cache16_unroll32(start,Index_Writeback_Inv_D);
  144. start += 0x200;
  145. }
  146. }
  147. extern inline void blast_dcache16_page(unsigned long page)
  148. {
  149. unsigned long start = page;
  150. unsigned long end = (start + PAGE_SIZE);
  151. while(start < end) {
  152. cache16_unroll32(start,Hit_Writeback_Inv_D);
  153. start += 0x200;
  154. }
  155. }
  156. extern inline void blast_dcache16_page_indexed(unsigned long page)
  157. {
  158. unsigned long start = page;
  159. unsigned long end = (start + PAGE_SIZE);
  160. while(start < end) {
  161. cache16_unroll32(start,Index_Writeback_Inv_D);
  162. start += 0x200;
  163. }
  164. }
  165. extern inline void blast_icache16(void)
  166. {
  167. unsigned long start = KSEG0;
  168. unsigned long end = (start + icache_size);
  169. while(start < end) {
  170. cache16_unroll32(start,Index_Invalidate_I);
  171. start += 0x200;
  172. }
  173. }
  174. extern inline void blast_icache16_page(unsigned long page)
  175. {
  176. unsigned long start = page;
  177. unsigned long end = (start + PAGE_SIZE);
  178. while(start < end) {
  179. cache16_unroll32(start,Hit_Invalidate_I);
  180. start += 0x200;
  181. }
  182. }
  183. extern inline void blast_icache16_page_indexed(unsigned long page)
  184. {
  185. unsigned long start = page;
  186. unsigned long end = (start + PAGE_SIZE);
  187. while(start < end) {
  188. cache16_unroll32(start,Index_Invalidate_I);
  189. start += 0x200;
  190. }
  191. }
  192. extern inline void blast_scache16(void)
  193. {
  194. unsigned long start = KSEG0;
  195. unsigned long end = KSEG0 + scache_size;
  196. while(start < end) {
  197. cache16_unroll32(start,Index_Writeback_Inv_SD);
  198. start += 0x200;
  199. }
  200. }
  201. extern inline void blast_scache16_page(unsigned long page)
  202. {
  203. unsigned long start = page;
  204. unsigned long end = page + PAGE_SIZE;
  205. while(start < end) {
  206. cache16_unroll32(start,Hit_Writeback_Inv_SD);
  207. start += 0x200;
  208. }
  209. }
  210. extern inline void blast_scache16_page_indexed(unsigned long page)
  211. {
  212. unsigned long start = page;
  213. unsigned long end = page + PAGE_SIZE;
  214. while(start < end) {
  215. cache16_unroll32(start,Index_Writeback_Inv_SD);
  216. start += 0x200;
  217. }
  218. }
  219. #define cache32_unroll32(base,op)
  220. __asm__ __volatile__("
  221. .set noreorder;
  222. cache %1, 0x000(%0); cache %1, 0x020(%0);
  223. cache %1, 0x040(%0); cache %1, 0x060(%0);
  224. cache %1, 0x080(%0); cache %1, 0x0a0(%0);
  225. cache %1, 0x0c0(%0); cache %1, 0x0e0(%0);
  226. cache %1, 0x100(%0); cache %1, 0x120(%0);
  227. cache %1, 0x140(%0); cache %1, 0x160(%0);
  228. cache %1, 0x180(%0); cache %1, 0x1a0(%0);
  229. cache %1, 0x1c0(%0); cache %1, 0x1e0(%0);
  230. cache %1, 0x200(%0); cache %1, 0x220(%0);
  231. cache %1, 0x240(%0); cache %1, 0x260(%0);
  232. cache %1, 0x280(%0); cache %1, 0x2a0(%0);
  233. cache %1, 0x2c0(%0); cache %1, 0x2e0(%0);
  234. cache %1, 0x300(%0); cache %1, 0x320(%0);
  235. cache %1, 0x340(%0); cache %1, 0x360(%0);
  236. cache %1, 0x380(%0); cache %1, 0x3a0(%0);
  237. cache %1, 0x3c0(%0); cache %1, 0x3e0(%0);
  238. .set reorder"
  239. :
  240. : "r" (base),
  241.   "i" (op));
  242. extern inline void blast_dcache32(void)
  243. {
  244. unsigned long start = KSEG0;
  245. unsigned long end = (start + dcache_size);
  246. while(start < end) {
  247. cache32_unroll32(start,Index_Writeback_Inv_D);
  248. start += 0x400;
  249. }
  250. }
  251. /*
  252.  * Call this function only with interrupts disabled or R4600 V2.0 may blow
  253.  * up on you.
  254.  *
  255.  * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D,
  256.  * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Excl_D will only
  257.  * operate correctly if the internal data cache refill buffer is empty.  These
  258.  * CACHE instructions should be separated from any potential data cache miss
  259.  * by a load instruction to an uncached address to empty the response buffer."
  260.  * (Revision 2.0 device errata from IDT available on http://www.idt.com/
  261.  * in .pdf format.)
  262.  */
  263. extern inline void blast_dcache32_page(unsigned long page)
  264. {
  265. unsigned long start = page;
  266. unsigned long end = (start + PAGE_SIZE);
  267. /*
  268.  * Sigh ... workaround for R4600 v1.7 bug.  Explanation see above.
  269.  */
  270. *(volatile unsigned long *)KSEG1;
  271. __asm__ __volatile__("nop;nop;nop;nop");
  272. while(start < end) {
  273. cache32_unroll32(start,Hit_Writeback_Inv_D);
  274. start += 0x400;
  275. }
  276. }
  277. extern inline void blast_dcache32_page_indexed(unsigned long page)
  278. {
  279. unsigned long start = page;
  280. unsigned long end = (start + PAGE_SIZE);
  281. while(start < end) {
  282. cache32_unroll32(start,Index_Writeback_Inv_D);
  283. start += 0x400;
  284. }
  285. }
  286. extern inline void blast_icache32(void)
  287. {
  288. unsigned long start = KSEG0;
  289. unsigned long end = (start + icache_size);
  290. while(start < end) {
  291. cache32_unroll32(start,Index_Invalidate_I);
  292. start += 0x400;
  293. }
  294. }
  295. extern inline void blast_icache32_page(unsigned long page)
  296. {
  297. unsigned long start = page;
  298. unsigned long end = (start + PAGE_SIZE);
  299. while(start < end) {
  300. cache32_unroll32(start,Hit_Invalidate_I);
  301. start += 0x400;
  302. }
  303. }
  304. extern inline void blast_icache32_page_indexed(unsigned long page)
  305. {
  306. unsigned long start = page;
  307. unsigned long end = (start + PAGE_SIZE);
  308. while(start < end) {
  309. cache32_unroll32(start,Index_Invalidate_I);
  310. start += 0x400;
  311. }
  312. }
  313. extern inline void blast_scache32(void)
  314. {
  315. unsigned long start = KSEG0;
  316. unsigned long end = KSEG0 + scache_size;
  317. while(start < end) {
  318. cache32_unroll32(start,Index_Writeback_Inv_SD);
  319. start += 0x400;
  320. }
  321. }
  322. extern inline void blast_scache32_page(unsigned long page)
  323. {
  324. unsigned long start = page;
  325. unsigned long end = page + PAGE_SIZE;
  326. while(start < end) {
  327. cache32_unroll32(start,Hit_Writeback_Inv_SD);
  328. start += 0x400;
  329. }
  330. }
  331. extern inline void blast_scache32_page_indexed(unsigned long page)
  332. {
  333. unsigned long start = page;
  334. unsigned long end = page + PAGE_SIZE;
  335. while(start < end) {
  336. cache32_unroll32(start,Index_Writeback_Inv_SD);
  337. start += 0x400;
  338. }
  339. }
  340. #define cache64_unroll32(base,op)
  341. __asm__ __volatile__("
  342. .set noreorder;
  343. cache %1, 0x000(%0); cache %1, 0x040(%0);
  344. cache %1, 0x080(%0); cache %1, 0x0c0(%0);
  345. cache %1, 0x100(%0); cache %1, 0x140(%0);
  346. cache %1, 0x180(%0); cache %1, 0x1c0(%0);
  347. cache %1, 0x200(%0); cache %1, 0x240(%0);
  348. cache %1, 0x280(%0); cache %1, 0x2c0(%0);
  349. cache %1, 0x300(%0); cache %1, 0x340(%0);
  350. cache %1, 0x380(%0); cache %1, 0x3c0(%0);
  351. cache %1, 0x400(%0); cache %1, 0x440(%0);
  352. cache %1, 0x480(%0); cache %1, 0x4c0(%0);
  353. cache %1, 0x500(%0); cache %1, 0x540(%0);
  354. cache %1, 0x580(%0); cache %1, 0x5c0(%0);
  355. cache %1, 0x600(%0); cache %1, 0x640(%0);
  356. cache %1, 0x680(%0); cache %1, 0x6c0(%0);
  357. cache %1, 0x700(%0); cache %1, 0x740(%0);
  358. cache %1, 0x780(%0); cache %1, 0x7c0(%0);
  359. .set reorder"
  360. :
  361. : "r" (base),
  362.   "i" (op));
  363. extern inline void blast_scache64(void)
  364. {
  365. unsigned long start = KSEG0;
  366. unsigned long end = KSEG0 + scache_size;
  367. while(start < end) {
  368. cache64_unroll32(start,Index_Writeback_Inv_SD);
  369. start += 0x800;
  370. }
  371. }
  372. extern inline void blast_scache64_page(unsigned long page)
  373. {
  374. unsigned long start = page;
  375. unsigned long end = page + PAGE_SIZE;
  376. while(start < end) {
  377. cache64_unroll32(start,Hit_Writeback_Inv_SD);
  378. start += 0x800;
  379. }
  380. }
  381. extern inline void blast_scache64_page_indexed(unsigned long page)
  382. {
  383. unsigned long start = page;
  384. unsigned long end = page + PAGE_SIZE;
  385. while(start < end) {
  386. cache64_unroll32(start,Index_Writeback_Inv_SD);
  387. start += 0x800;
  388. }
  389. }
  390. #define cache128_unroll32(base,op)
  391. __asm__ __volatile__("
  392. .set noreorder;
  393. cache %1, 0x000(%0); cache %1, 0x080(%0);
  394. cache %1, 0x100(%0); cache %1, 0x180(%0);
  395. cache %1, 0x200(%0); cache %1, 0x280(%0);
  396. cache %1, 0x300(%0); cache %1, 0x380(%0);
  397. cache %1, 0x400(%0); cache %1, 0x480(%0);
  398. cache %1, 0x500(%0); cache %1, 0x580(%0);
  399. cache %1, 0x600(%0); cache %1, 0x680(%0);
  400. cache %1, 0x700(%0); cache %1, 0x780(%0);
  401. cache %1, 0x800(%0); cache %1, 0x880(%0);
  402. cache %1, 0x900(%0); cache %1, 0x980(%0);
  403. cache %1, 0xa00(%0); cache %1, 0xa80(%0);
  404. cache %1, 0xb00(%0); cache %1, 0xb80(%0);
  405. cache %1, 0xc00(%0); cache %1, 0xc80(%0);
  406. cache %1, 0xd00(%0); cache %1, 0xd80(%0);
  407. cache %1, 0xe00(%0); cache %1, 0xe80(%0);
  408. cache %1, 0xf00(%0); cache %1, 0xf80(%0);
  409. .set reorder"
  410. :
  411. : "r" (base),
  412.   "i" (op));
  413. extern inline void blast_scache128(void)
  414. {
  415. unsigned long start = KSEG0;
  416. unsigned long end = KSEG0 + scache_size;
  417. while(start < end) {
  418. cache128_unroll32(start,Index_Writeback_Inv_SD);
  419. start += 0x1000;
  420. }
  421. }
  422. extern inline void blast_scache128_page(unsigned long page)
  423. {
  424. cache128_unroll32(page,Hit_Writeback_Inv_SD);
  425. }
  426. extern inline void blast_scache128_page_indexed(unsigned long page)
  427. {
  428. cache128_unroll32(page,Index_Writeback_Inv_SD);
  429. }
  430. #endif /* __ASM_R4KCACHE_H */