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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  3.  * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
  4.  *
  5.  * This program is free software; you can distribute it and/or modify it
  6.  * under the terms of the GNU General Public License (Version 2) as
  7.  * published by the Free Software Foundation.
  8.  *
  9.  * This program is distributed in the hope it will be useful, but WITHOUT
  10.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12.  * for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License along
  15.  * with this program; if not, write to the Free Software Foundation, Inc.,
  16.  * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  17.  *
  18.  * MIPS32 CPU variant specific MMU/Cache routines.
  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/bcache.h>
  28. #include <asm/io.h>
  29. #include <asm/page.h>
  30. #include <asm/pgtable.h>
  31. #include <asm/system.h>
  32. #include <asm/mmu_context.h>
  33. /* CP0 hazard avoidance. */
  34. #define BARRIER __asm__ __volatile__(".set noreordernt" 
  35.      "nop; nop; nop; nop; nop; nop;nt" 
  36.      ".set reordernt")
  37. /* Primary cache parameters. */
  38. int icache_size, dcache_size;  /* Size in bytes */
  39. int ic_lsize, dc_lsize; /* LineSize in bytes */
  40. /* Secondary cache (if present) parameters. */
  41. unsigned int scache_size, sc_lsize; /* Again, in bytes */
  42. #include <asm/cacheops.h>
  43. #include <asm/mips32_cache.h>
  44. #undef DEBUG_CACHE
  45. /*
  46.  * Dummy cache handling routines for machines without boardcaches
  47.  */
  48. static void no_sc_noop(void) {}
  49. static struct bcache_ops no_sc_ops = {
  50. (void *)no_sc_noop, (void *)no_sc_noop,
  51. (void *)no_sc_noop, (void *)no_sc_noop
  52. };
  53. struct bcache_ops *bcops = &no_sc_ops;
  54. static inline void mips32_flush_cache_all_sc(void)
  55. {
  56. unsigned long flags;
  57. __save_and_cli(flags);
  58. blast_dcache(); blast_icache(); blast_scache();
  59. __restore_flags(flags);
  60. }
  61. static inline void mips32_flush_cache_all_pc(void)
  62. {
  63. unsigned long flags;
  64. __save_and_cli(flags);
  65. blast_dcache(); blast_icache();
  66. __restore_flags(flags);
  67. }
  68. static void
  69. mips32_flush_cache_range_sc(struct mm_struct *mm,
  70.  unsigned long start,
  71.  unsigned long end)
  72. {
  73. struct vm_area_struct *vma;
  74. unsigned long flags;
  75. if(mm->context == 0)
  76. return;
  77. start &= PAGE_MASK;
  78. #ifdef DEBUG_CACHE
  79. printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
  80. #endif
  81. vma = find_vma(mm, start);
  82. if(vma) {
  83. if(mm->context != current->mm->context) {
  84. mips32_flush_cache_all_sc();
  85. } else {
  86. pgd_t *pgd;
  87. pmd_t *pmd;
  88. pte_t *pte;
  89. __save_and_cli(flags);
  90. while(start < end) {
  91. pgd = pgd_offset(mm, start);
  92. pmd = pmd_offset(pgd, start);
  93. pte = pte_offset(pmd, start);
  94. if(pte_val(*pte) & _PAGE_VALID)
  95. blast_scache_page(start);
  96. start += PAGE_SIZE;
  97. }
  98. __restore_flags(flags);
  99. }
  100. }
  101. }
  102. static void mips32_flush_cache_range_pc(struct mm_struct *mm,
  103.      unsigned long start,
  104.      unsigned long end)
  105. {
  106. if(mm->context != 0) {
  107. unsigned long flags;
  108. #ifdef DEBUG_CACHE
  109. printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
  110. #endif
  111. __save_and_cli(flags);
  112. blast_dcache(); blast_icache();
  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 mips32_flush_cache_mm_sc(struct mm_struct *mm)
  122. {
  123. if(mm->context != 0) {
  124. #ifdef DEBUG_CACHE
  125. printk("cmm[%d]", (int)mm->context);
  126. #endif
  127. mips32_flush_cache_all_sc();
  128. }
  129. }
  130. static void mips32_flush_cache_mm_pc(struct mm_struct *mm)
  131. {
  132. if(mm->context != 0) {
  133. #ifdef DEBUG_CACHE
  134. printk("cmm[%d]", (int)mm->context);
  135. #endif
  136. mips32_flush_cache_all_pc();
  137. }
  138. }
  139. static void mips32_flush_cache_page_sc(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_VALID))
  166. goto out;
  167. /*
  168.  * Doing flushes for another ASID than the current one is
  169.  * too difficult since 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->context != current->active_mm->context) {
  174. /*
  175.  * Do indexed flush, too much work to get the (possible)
  176.  * tlb refills to work correctly.
  177.  */
  178. page = (KSEG0 + (page & (scache_size - 1)));
  179. blast_dcache_page_indexed(page);
  180. blast_scache_page_indexed(page);
  181. } else
  182. blast_scache_page(page);
  183. out:
  184. __restore_flags(flags);
  185. }
  186. static void mips32_flush_cache_page_pc(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_VALID))
  213. goto out;
  214. /*
  215.  * Doing flushes for another ASID than the current one is
  216.  * too difficult since Mips32 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) {
  221. blast_dcache_page(page);
  222. } else {
  223. /* Do indexed flush, too much work to get the (possible)
  224.  * tlb refills to work correctly.
  225.  */
  226. page = (KSEG0 + (page & (dcache_size - 1)));
  227. blast_dcache_page_indexed(page);
  228. }
  229. out:
  230. __restore_flags(flags);
  231. }
  232. /* If the addresses passed to these routines are valid, they are
  233.  * either:
  234.  *
  235.  * 1) In KSEG0, so we can do a direct flush of the page.
  236.  * 2) In KSEG2, and since every process can translate those
  237.  *    addresses all the time in kernel mode we can do a direct
  238.  *    flush.
  239.  * 3) In KSEG1, no flush necessary.
  240.  */
  241. static void mips32_flush_page_to_ram_sc(struct page *page)
  242. {
  243. blast_scache_page((unsigned long)page_address(page));
  244. }
  245. static void mips32_flush_page_to_ram_pc(struct page *page)
  246. {
  247. blast_dcache_page((unsigned long)page_address(page));
  248. }
  249. static void
  250. mips32_flush_icache_page_s(struct vm_area_struct *vma, struct page *page)
  251. {
  252. /*
  253.  * We did an scache flush therefore PI is already clean.
  254.  */
  255. }
  256. static void
  257. mips32_flush_icache_range(unsigned long start, unsigned long end)
  258. {
  259. flush_cache_all();
  260. }
  261. static void
  262. mips32_flush_icache_page(struct vm_area_struct *vma, struct page *page)
  263. {
  264. int address;
  265. if (!(vma->vm_flags & VM_EXEC))
  266. return;
  267. address = KSEG0 + ((unsigned long)page_address(page) & PAGE_MASK & (dcache_size - 1));
  268. blast_icache_page_indexed(address);
  269. }
  270. /*
  271.  * Writeback and invalidate the primary cache dcache before DMA.
  272.  */
  273. static void
  274. mips32_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
  275. {
  276. unsigned long end, a;
  277. unsigned int flags;
  278. if (size >= dcache_size) {
  279. flush_cache_all();
  280. } else {
  281.         __save_and_cli(flags);
  282. a = addr & ~(dc_lsize - 1);
  283. end = (addr + size) & ~(dc_lsize - 1);
  284. while (1) {
  285. flush_dcache_line(a); /* Hit_Writeback_Inv_D */
  286. if (a == end) break;
  287. a += dc_lsize;
  288. }
  289. __restore_flags(flags);
  290. }
  291. bc_wback_inv(addr, size);
  292. }
  293. static void
  294. mips32_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
  295. {
  296. unsigned long end, a;
  297. if (size >= scache_size) {
  298. flush_cache_all();
  299. return;
  300. }
  301. a = addr & ~(sc_lsize - 1);
  302. end = (addr + size) & ~(sc_lsize - 1);
  303. while (1) {
  304. flush_scache_line(a); /* Hit_Writeback_Inv_SD */
  305. if (a == end) break;
  306. a += sc_lsize;
  307. }
  308. }
  309. static void
  310. mips32_dma_cache_inv_pc(unsigned long addr, unsigned long size)
  311. {
  312. unsigned long end, a;
  313. unsigned int flags;
  314. if (size >= dcache_size) {
  315. flush_cache_all();
  316. } else {
  317.         __save_and_cli(flags);
  318. a = addr & ~(dc_lsize - 1);
  319. end = (addr + size) & ~(dc_lsize - 1);
  320. while (1) {
  321. flush_dcache_line(a); /* Hit_Writeback_Inv_D */
  322. if (a == end) break;
  323. a += dc_lsize;
  324. }
  325. __restore_flags(flags);
  326. }
  327. bc_inv(addr, size);
  328. }
  329. static void
  330. mips32_dma_cache_inv_sc(unsigned long addr, unsigned long size)
  331. {
  332. unsigned long end, a;
  333. if (size >= scache_size) {
  334. flush_cache_all();
  335. return;
  336. }
  337. a = addr & ~(sc_lsize - 1);
  338. end = (addr + size) & ~(sc_lsize - 1);
  339. while (1) {
  340. flush_scache_line(a); /* Hit_Writeback_Inv_SD */
  341. if (a == end) break;
  342. a += sc_lsize;
  343. }
  344. }
  345. static void
  346. mips32_dma_cache_wback(unsigned long addr, unsigned long size)
  347. {
  348. panic("mips32_dma_cache called - should not happen.");
  349. }
  350. /*
  351.  * While we're protected against bad userland addresses we don't care
  352.  * very much about what happens in that case.  Usually a segmentation
  353.  * fault will dump the process later on anyway ...
  354.  */
  355. static void mips32_flush_cache_sigtramp(unsigned long addr)
  356. {
  357. protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
  358. protected_flush_icache_line(addr & ~(ic_lsize - 1));
  359. }
  360. static void mips32_flush_icache_all(void)
  361. {
  362. if (mips_cpu.cputype == CPU_20KC) {
  363. blast_icache();
  364. }
  365. }
  366. /* Detect and size the various caches. */
  367. static void __init probe_icache(unsigned long config)
  368. {
  369.         unsigned long config1;
  370. unsigned int lsize;
  371.         if (!(config & (1 << 31))) {
  372.         /*
  373.  * Not a MIPS32 complainant CPU.
  374.  * Config 1 register not supported, we assume R4k style.
  375.  */
  376.         icache_size = 1 << (12 + ((config >> 9) & 7));
  377. ic_lsize = 16 << ((config >> 5) & 1);
  378. mips_cpu.icache.linesz = ic_lsize;
  379. /*
  380.  * We cannot infer associativity - assume direct map
  381.  * unless probe template indicates otherwise
  382.  */
  383. if(!mips_cpu.icache.ways) mips_cpu.icache.ways = 1;
  384. mips_cpu.icache.sets =
  385. (icache_size / ic_lsize) / mips_cpu.icache.ways;
  386. } else {
  387.        config1 = read_mips32_cp0_config1();
  388.        if ((lsize = ((config1 >> 19) & 7)))
  389.        mips_cpu.icache.linesz = 2 << lsize;
  390.        else
  391.        mips_cpu.icache.linesz = lsize;
  392.        mips_cpu.icache.sets = 64 << ((config1 >> 22) & 7);
  393.        mips_cpu.icache.ways = 1 + ((config1 >> 16) & 7);
  394.        ic_lsize = mips_cpu.icache.linesz;
  395.        icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways *
  396.              ic_lsize;
  397. }
  398. printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)n",
  399.        icache_size >> 10, ic_lsize, mips_cpu.icache.ways);
  400. }
  401. static void __init probe_dcache(unsigned long config)
  402. {
  403.         unsigned long config1;
  404. unsigned int lsize;
  405.         if (!(config & (1 << 31))) {
  406.         /*
  407.  * Not a MIPS32 complainant CPU.
  408.  * Config 1 register not supported, we assume R4k style.
  409.  */
  410. dcache_size = 1 << (12 + ((config >> 6) & 7));
  411. dc_lsize = 16 << ((config >> 4) & 1);
  412. mips_cpu.dcache.linesz = dc_lsize;
  413. /*
  414.  * We cannot infer associativity - assume direct map
  415.  * unless probe template indicates otherwise
  416.  */
  417. if(!mips_cpu.dcache.ways) mips_cpu.dcache.ways = 1;
  418. mips_cpu.dcache.sets =
  419. (dcache_size / dc_lsize) / mips_cpu.dcache.ways;
  420. } else {
  421.         config1 = read_mips32_cp0_config1();
  422. if ((lsize = ((config1 >> 10) & 7)))
  423.         mips_cpu.dcache.linesz = 2 << lsize;
  424. else
  425.         mips_cpu.dcache.linesz= lsize;
  426. mips_cpu.dcache.sets = 64 << ((config1 >> 13) & 7);
  427. mips_cpu.dcache.ways = 1 + ((config1 >> 7) & 7);
  428. dc_lsize = mips_cpu.dcache.linesz;
  429. dcache_size =
  430. mips_cpu.dcache.sets * mips_cpu.dcache.ways
  431. * dc_lsize;
  432. }
  433. printk("Primary data cache %dkb, linesize %d bytes (%d ways)n",
  434.        dcache_size >> 10, dc_lsize, mips_cpu.dcache.ways);
  435. }
  436. /* If you even _breathe_ on this function, look at the gcc output
  437.  * and make sure it does not pop things on and off the stack for
  438.  * the cache sizing loop that executes in KSEG1 space or else
  439.  * you will crash and burn badly.  You have been warned.
  440.  */
  441. static int __init probe_scache(unsigned long config)
  442. {
  443. extern unsigned long stext;
  444. unsigned long flags, addr, begin, end, pow2;
  445. int tmp;
  446. if (mips_cpu.scache.flags == MIPS_CACHE_NOT_PRESENT)
  447. return 0;
  448. tmp = ((config >> 17) & 1);
  449. if(tmp)
  450. return 0;
  451. tmp = ((config >> 22) & 3);
  452. switch(tmp) {
  453. case 0:
  454. sc_lsize = 16;
  455. break;
  456. case 1:
  457. sc_lsize = 32;
  458. break;
  459. case 2:
  460. sc_lsize = 64;
  461. break;
  462. case 3:
  463. sc_lsize = 128;
  464. break;
  465. }
  466. begin = (unsigned long) &stext;
  467. begin &= ~((4 * 1024 * 1024) - 1);
  468. end = begin + (4 * 1024 * 1024);
  469. /* This is such a bitch, you'd think they would make it
  470.  * easy to do this.  Away you daemons of stupidity!
  471.  */
  472. __save_and_cli(flags);
  473. /* Fill each size-multiple cache line with a valid tag. */
  474. pow2 = (64 * 1024);
  475. for(addr = begin; addr < end; addr = (begin + pow2)) {
  476. unsigned long *p = (unsigned long *) addr;
  477. __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */
  478. pow2 <<= 1;
  479. }
  480. /* Load first line with zero (therefore invalid) tag. */
  481. set_taglo(0);
  482. set_taghi(0);
  483. __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
  484. __asm__ __volatile__("nt.set noreordernt"
  485.      ".set mips3nt"
  486.      "cache 8, (%0)nt"
  487.      ".set mips0nt"
  488.      ".set reordernt" : : "r" (begin));
  489. __asm__ __volatile__("nt.set noreordernt"
  490.      ".set mips3nt"
  491.      "cache 9, (%0)nt"
  492.      ".set mips0nt"
  493.      ".set reordernt" : : "r" (begin));
  494. __asm__ __volatile__("nt.set noreordernt"
  495.      ".set mips3nt"
  496.      "cache 11, (%0)nt"
  497.      ".set mips0nt"
  498.      ".set reordernt" : : "r" (begin));
  499. /* Now search for the wrap around point. */
  500. pow2 = (128 * 1024);
  501. tmp = 0;
  502. for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) {
  503. __asm__ __volatile__("nt.set noreordernt"
  504.      ".set mips3nt"
  505.      "cache 7, (%0)nt"
  506.      ".set mips0nt"
  507.      ".set reordernt" : : "r" (addr));
  508. __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */
  509. if(!get_taglo())
  510. break;
  511. pow2 <<= 1;
  512. }
  513. __restore_flags(flags);
  514. addr -= begin;
  515. printk("Secondary cache sized at %dK linesize %d bytes.n",
  516.        (int) (addr >> 10), sc_lsize);
  517. scache_size = addr;
  518. return 1;
  519. }
  520. static void __init setup_noscache_funcs(void)
  521. {
  522. _clear_page = (void *)mips32_clear_page_dc;
  523. _copy_page = (void *)mips32_copy_page_dc;
  524. _flush_cache_all = mips32_flush_cache_all_pc;
  525. ___flush_cache_all = mips32_flush_cache_all_pc;
  526. _flush_cache_mm = mips32_flush_cache_mm_pc;
  527. _flush_cache_range = mips32_flush_cache_range_pc;
  528. _flush_cache_page = mips32_flush_cache_page_pc;
  529. _flush_page_to_ram = mips32_flush_page_to_ram_pc;
  530. _flush_icache_page = mips32_flush_icache_page;
  531. _dma_cache_wback_inv = mips32_dma_cache_wback_inv_pc;
  532. _dma_cache_wback = mips32_dma_cache_wback;
  533. _dma_cache_inv = mips32_dma_cache_inv_pc;
  534. }
  535. static void __init setup_scache_funcs(void)
  536. {
  537.         _flush_cache_all = mips32_flush_cache_all_sc;
  538.         ___flush_cache_all = mips32_flush_cache_all_sc;
  539. _flush_cache_mm = mips32_flush_cache_mm_sc;
  540. _flush_cache_range = mips32_flush_cache_range_sc;
  541. _flush_cache_page = mips32_flush_cache_page_sc;
  542. _flush_page_to_ram = mips32_flush_page_to_ram_sc;
  543. _clear_page = (void *)mips32_clear_page_sc;
  544. _copy_page = (void *)mips32_copy_page_sc;
  545. _flush_icache_page = mips32_flush_icache_page_s;
  546. _dma_cache_wback_inv = mips32_dma_cache_wback_inv_sc;
  547. _dma_cache_wback = mips32_dma_cache_wback;
  548. _dma_cache_inv = mips32_dma_cache_inv_sc;
  549. }
  550. typedef int (*probe_func_t)(unsigned long);
  551. static inline void __init setup_scache(unsigned int config)
  552. {
  553. probe_func_t probe_scache_kseg1;
  554. int sc_present = 0;
  555. /* Maybe the cpu knows about a l2 cache? */
  556. probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
  557. sc_present = probe_scache_kseg1(config);
  558. if (sc_present) {
  559.    mips_cpu.scache.linesz = sc_lsize;
  560. /*
  561.  * We cannot infer associativity - assume direct map
  562.  * unless probe template indicates otherwise
  563.  */
  564. if(!mips_cpu.scache.ways) mips_cpu.scache.ways = 1;
  565. mips_cpu.scache.sets =
  566.   (scache_size / sc_lsize) / mips_cpu.scache.ways;
  567. setup_scache_funcs();
  568. return;
  569. }
  570. setup_noscache_funcs();
  571. }
  572. void __init ld_mmu_mips32(void)
  573. {
  574. unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
  575. change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
  576. probe_icache(config);
  577. probe_dcache(config);
  578. setup_scache(config);
  579. _flush_cache_sigtramp = mips32_flush_cache_sigtramp;
  580. _flush_icache_range = mips32_flush_icache_range; /* Ouch */
  581. _flush_icache_all = mips32_flush_icache_all;
  582. __flush_cache_all();
  583. }