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

Linux/Unix编程

开发平台:

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.  * r49xx.c: TX49 processor variant specific MMU/Cache routines.
  7.  *
  8.  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  9.  * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
  10.  *
  11.  * Modified for R4300/TX49xx (Jun/2001)
  12.  * Copyright (C) 1999-2001 Toshiba Corporation
  13.  *
  14.  * To do:
  15.  *
  16.  *  - this code is a overbloated pig
  17.  *  - many of the bug workarounds are not efficient at all, but at
  18.  *    least they are functional ...
  19.  */
  20. #include <linux/config.h>
  21. #include <linux/init.h>
  22. #include <linux/kernel.h>
  23. #include <linux/sched.h>
  24. #include <linux/mm.h>
  25. #include <asm/bootinfo.h>
  26. #include <asm/cpu.h>
  27. #include <asm/io.h>
  28. #include <asm/page.h>
  29. #include <asm/pgtable.h>
  30. #include <asm/system.h>
  31. #include <asm/mmu_context.h>
  32. /* Primary cache parameters. */
  33. static int icache_size, dcache_size; /* Size in bytes */
  34. #define ic_lsize mips_cpu.icache.linesz
  35. #define dc_lsize mips_cpu.dcache.linesz
  36. static unsigned long scache_size;
  37. #include <asm/cacheops.h>
  38. #include <asm/r4kcache.h>
  39. #undef DEBUG_CACHE
  40. /* TX49 does can not flush the line contains the CACHE insn itself... */
  41. /* r4k_xxx routines are completely same as those in r4xx0.c */
  42. /*
  43.  * If you think for one second that this stuff coming up is a lot
  44.  * of bulky code eating too many kernel cache lines.  Think _again_.
  45.  *
  46.  * Consider:
  47.  * 1) Taken branches have a 3 cycle penalty on R4k
  48.  * 2) The branch itself is a real dead cycle on even R4600/R5000.
  49.  * 3) Only one of the following variants of each type is even used by
  50.  *    the kernel based upon the cache parameters we detect at boot time.
  51.  *
  52.  * QED.
  53.  */
  54. static inline void r49_flush_cache_all_d16i32(void)
  55. {
  56. unsigned long flags, config;
  57. __save_and_cli(flags);
  58. blast_dcache16_wayLSB();
  59. /* disable icache (set ICE#) */
  60. config = read_32bit_cp0_register(CP0_CONFIG);
  61. write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC);
  62. blast_icache32_wayLSB();
  63. write_32bit_cp0_register(CP0_CONFIG, config);
  64. __restore_flags(flags);
  65. }
  66. static inline void r49_flush_cache_all_d32i32(void)
  67. {
  68. unsigned long flags, config;
  69. __save_and_cli(flags);
  70. blast_dcache32_wayLSB();
  71. /* disable icache (set ICE#) */
  72. config = read_32bit_cp0_register(CP0_CONFIG);
  73. write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC);
  74. blast_icache32_wayLSB();
  75. write_32bit_cp0_register(CP0_CONFIG, config);
  76. __restore_flags(flags);
  77. }
  78. static void r49_flush_cache_range_d16i32(struct mm_struct *mm,
  79.  unsigned long start,
  80.  unsigned long end)
  81. {
  82. if (mm->context != 0) {
  83. unsigned long flags, config;
  84. #ifdef DEBUG_CACHE
  85. printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
  86. #endif
  87. __save_and_cli(flags);
  88. blast_dcache16_wayLSB();
  89. /* disable icache (set ICE#) */
  90. config = read_32bit_cp0_register(CP0_CONFIG);
  91. write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC);
  92. blast_icache32_wayLSB();
  93. write_32bit_cp0_register(CP0_CONFIG, config);
  94. __restore_flags(flags);
  95. }
  96. }
  97. static void r49_flush_cache_range_d32i32(struct mm_struct *mm,
  98.        unsigned long start,
  99.        unsigned long end)
  100. {
  101. if (mm->context != 0) {
  102. unsigned long flags, config;
  103. #ifdef DEBUG_CACHE
  104. printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
  105. #endif
  106. __save_and_cli(flags);
  107. blast_dcache32_wayLSB();
  108. /* disable icache (set ICE#) */
  109. config = read_32bit_cp0_register(CP0_CONFIG);
  110. write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC);
  111. blast_icache32_wayLSB();
  112. write_32bit_cp0_register(CP0_CONFIG, config);
  113. __restore_flags(flags);
  114. }
  115. }
  116. /*
  117.  * On architectures like the Sparc, we could get rid of lines in
  118.  * the cache created only by a certain context, but on the MIPS
  119.  * (and actually certain Sparc's) we cannot.
  120.  */
  121. static void r49_flush_cache_mm_d16i32(struct mm_struct *mm)
  122. {
  123. if (mm->context != 0) {
  124. #ifdef DEBUG_CACHE
  125. printk("cmm[%d]", (int)mm->context);
  126. #endif
  127. r49_flush_cache_all_d16i32();
  128. }
  129. }
  130. static void r49_flush_cache_mm_d32i32(struct mm_struct *mm)
  131. {
  132. if (mm->context != 0) {
  133. #ifdef DEBUG_CACHE
  134. printk("cmm[%d]", (int)mm->context);
  135. #endif
  136. r49_flush_cache_all_d32i32();
  137. }
  138. }
  139. static void r49_flush_cache_page_d16i32(struct vm_area_struct *vma,
  140. unsigned long page)
  141. {
  142. struct mm_struct *mm = vma->vm_mm;
  143. unsigned long flags;
  144. pgd_t *pgdp;
  145. pmd_t *pmdp;
  146. pte_t *ptep;
  147. /*
  148.  * If ownes no valid ASID yet, cannot possibly have gotten
  149.  * this page into the cache.
  150.  */
  151. if (mm->context == 0)
  152. return;
  153. #ifdef DEBUG_CACHE
  154. printk("cpage[%d,%08lx]", (int)mm->context, page);
  155. #endif
  156. __save_and_cli(flags);
  157. page &= PAGE_MASK;
  158. pgdp = pgd_offset(mm, page);
  159. pmdp = pmd_offset(pgdp, page);
  160. ptep = pte_offset(pmdp, page);
  161. /*
  162.  * If the page isn't marked valid, the page cannot possibly be
  163.  * in the cache.
  164.  */
  165. if (!(pte_val(*ptep) & _PAGE_PRESENT))
  166. goto out;
  167. /*
  168.  * Doing flushes for another ASID than the current one is
  169.  * too difficult since stupid R4k caches do a TLB translation
  170.  * for every cache flush operation.  So we do indexed flushes
  171.  * in that case, which doesn't overly flush the cache too much.
  172.  */
  173. if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
  174. blast_dcache16_page(page);
  175. } else {
  176. /*
  177.  * Do indexed flush, too much work to get the (possible)
  178.  * tlb refills to work correctly.
  179.  */
  180. page = (KSEG0 + (page & (dcache_size - 1)));
  181. blast_dcache16_page_indexed_wayLSB(page);
  182. }
  183. out:
  184. __restore_flags(flags);
  185. }
  186. static void r49_flush_cache_page_d32i32(struct vm_area_struct *vma,
  187.       unsigned long page)
  188. {
  189. struct mm_struct *mm = vma->vm_mm;
  190. unsigned long flags;
  191. pgd_t *pgdp;
  192. pmd_t *pmdp;
  193. pte_t *ptep;
  194. /*
  195.  * If ownes no valid ASID yet, cannot possibly have gotten
  196.  * this page into the cache.
  197.  */
  198. if (mm->context == 0)
  199. return;
  200. #ifdef DEBUG_CACHE
  201. printk("cpage[%d,%08lx]", (int)mm->context, page);
  202. #endif
  203. __save_and_cli(flags);
  204. page &= PAGE_MASK;
  205. pgdp = pgd_offset(mm, page);
  206. pmdp = pmd_offset(pgdp, page);
  207. ptep = pte_offset(pmdp, page);
  208. /*
  209.  * If the page isn't marked valid, the page cannot possibly be
  210.  * in the cache.
  211.  */
  212. if (!(pte_val(*ptep) & _PAGE_PRESENT))
  213. goto out;
  214. /*
  215.  * Doing flushes for another ASID than the current one is
  216.  * too difficult since stupid R4k caches do a TLB translation
  217.  * for every cache flush operation.  So we do indexed flushes
  218.  * in that case, which doesn't overly flush the cache too much.
  219.  */
  220. if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
  221. blast_dcache32_page(page);
  222. } else {
  223. /*
  224.  * Do indexed flush, too much work to get the (possible)
  225.  * tlb refills to work correctly.
  226.  */
  227. page = (KSEG0 + (page & (dcache_size - 1)));
  228. blast_dcache32_page_indexed_wayLSB(page);
  229. }
  230. out:
  231. __restore_flags(flags);
  232. }
  233. /* If the addresses passed to these routines are valid, they are
  234.  * either:
  235.  *
  236.  * 1) In KSEG0, so we can do a direct flush of the page.
  237.  * 2) In KSEG2, and since every process can translate those
  238.  *    addresses all the time in kernel mode we can do a direct
  239.  *    flush.
  240.  * 3) In KSEG1, no flush necessary.
  241.  */
  242. static void r4k_flush_page_to_ram_d16(struct page *page)
  243. {
  244. blast_dcache16_page((unsigned long)page_address(page));
  245. }
  246. static void r4k_flush_page_to_ram_d32(struct page *page)
  247. {
  248. blast_dcache32_page((unsigned long)page_address(page));
  249. }
  250. static void
  251. r4k_flush_icache_range(unsigned long start, unsigned long end)
  252. {
  253. flush_cache_all();
  254. }
  255. /*
  256.  * Ok, this seriously sucks.  We use them to flush a user page but don't
  257.  * know the virtual address, so we have to blast away the whole icache
  258.  * which is significantly more expensive than the real thing.
  259.  */
  260. static void
  261. r4k_flush_icache_page(struct vm_area_struct *vma, struct page *page)
  262. {
  263. if (!(vma->vm_flags & VM_EXEC))
  264. return;
  265. flush_cache_all();
  266. }
  267. /*
  268.  * Writeback and invalidate the primary cache dcache before DMA.
  269.  */
  270. static void
  271. r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
  272. {
  273. unsigned long end, a;
  274. unsigned int flags;
  275. if (size >= dcache_size) {
  276. flush_cache_all();
  277. } else {
  278. __save_and_cli(flags);
  279. a = addr & ~(dc_lsize - 1);
  280. end = (addr + size) & ~(dc_lsize - 1);
  281. while (1) {
  282. flush_dcache_line(a); /* Hit_Writeback_Inv_D */
  283. if (a == end) break;
  284. a += dc_lsize;
  285. }
  286. __restore_flags(flags);
  287. }
  288. }
  289. static void
  290. r4k_dma_cache_inv(unsigned long addr, unsigned long size)
  291. {
  292. unsigned long end, a;
  293. unsigned int flags;
  294. if (size >= dcache_size) {
  295. flush_cache_all();
  296. } else {
  297. __save_and_cli(flags);
  298. a = addr & ~(dc_lsize - 1);
  299. end = (addr + size) & ~(dc_lsize - 1);
  300. while (1) {
  301. flush_dcache_line(a); /* Hit_Writeback_Inv_D */
  302. if (a == end) break;
  303. a += dc_lsize;
  304. }
  305. __restore_flags(flags);
  306. }
  307. }
  308. static void
  309. r4k_dma_cache_wback(unsigned long addr, unsigned long size)
  310. {
  311. panic("r4k_dma_cache called - should not happen.");
  312. }
  313. /*
  314.  * While we're protected against bad userland addresses we don't care
  315.  * very much about what happens in that case.  Usually a segmentation
  316.  * fault will dump the process later on anyway ...
  317.  */
  318. static void r4k_flush_cache_sigtramp(unsigned long addr)
  319. {
  320. protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
  321. protected_flush_icache_line(addr & ~(ic_lsize - 1));
  322. }
  323. /* Detect and size the various r4k caches. */
  324. static void __init probe_icache(unsigned long config)
  325. {
  326. icache_size = 1 << (12 + ((config >> 9) & 7));
  327. ic_lsize = 16 << ((config >> 5) & 1);
  328. printk("Primary instruction cache %dkb, linesize %d bytes.n",
  329.        icache_size >> 10, ic_lsize);
  330. }
  331. static void __init probe_dcache(unsigned long config)
  332. {
  333. dcache_size = 1 << (12 + ((config >> 6) & 7));
  334. dc_lsize = 16 << ((config >> 4) & 1);
  335. printk("Primary data cache %dkb, linesize %d bytes.n",
  336.        dcache_size >> 10, dc_lsize);
  337. }
  338. int mips_configk0 = -1; /* board-specific setup routine can override this */
  339. void __init ld_mmu_tx49(void)
  340. {
  341. unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
  342. if (mips_configk0 != -1)
  343. change_cp0_config(CONF_CM_CMASK, mips_configk0);
  344. else
  345. change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
  346. probe_icache(config);
  347. probe_dcache(config);
  348. if (mips_cpu.icache.ways == 0)
  349. mips_cpu.icache.ways = 1;
  350. if (mips_cpu.dcache.ways == 0)
  351. mips_cpu.dcache.ways = 1;
  352. mips_cpu.icache.sets =
  353. icache_size / mips_cpu.icache.ways / mips_cpu.icache.linesz;
  354. mips_cpu.dcache.sets =
  355. dcache_size / mips_cpu.dcache.ways / mips_cpu.dcache.linesz;
  356. switch(dc_lsize) {
  357. case 16:
  358. _clear_page = r4k_clear_page_d16;
  359. _copy_page = r4k_copy_page_d16;
  360. _flush_page_to_ram = r4k_flush_page_to_ram_d16;
  361. _flush_cache_all = r49_flush_cache_all_d16i32;
  362. _flush_cache_mm = r49_flush_cache_mm_d16i32;
  363. _flush_cache_range = r49_flush_cache_range_d16i32;
  364. _flush_cache_page = r49_flush_cache_page_d16i32;
  365. break;
  366. case 32:
  367. _clear_page = r4k_clear_page_d32;
  368. _copy_page = r4k_copy_page_d32;
  369. _flush_page_to_ram = r4k_flush_page_to_ram_d32;
  370. _flush_cache_all = r49_flush_cache_all_d32i32;
  371. _flush_cache_mm = r49_flush_cache_mm_d32i32;
  372. _flush_cache_range = r49_flush_cache_range_d32i32;
  373. _flush_cache_page = r49_flush_cache_page_d32i32;
  374. break;
  375. }
  376. ___flush_cache_all = _flush_cache_all;
  377. _flush_icache_page = r4k_flush_icache_page;
  378. _dma_cache_wback_inv = r4k_dma_cache_wback_inv;
  379. _dma_cache_wback = r4k_dma_cache_wback;
  380. _dma_cache_inv = r4k_dma_cache_inv;
  381. _flush_cache_sigtramp = r4k_flush_cache_sigtramp;
  382. _flush_icache_range = r4k_flush_icache_range; /* Ouch */
  383. __flush_cache_all();
  384. }