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

嵌入式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.  * r5432.c: NEC Vr5432 processor.  We cannot use r4xx0.c because of
  7.  *      its unique way-selection method for indexed operations.
  8.  *
  9.  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  10.  * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle (ralf@gnu.org)
  11.  * Copyright (C) 2000 Jun Sun (jsun@mvista.com)
  12.  *
  13.  */
  14. /*
  15.  * [jsun]
  16.  * In a sense, this is really silly.  We cannot re-use r4xx0.c because
  17.  * the lowest-level indexed cache operation does not take way-selection
  18.  * into account.  So all what I am doing here is to copy all the funcs
  19.  * and macros (in r4kcache.h) relavent to R5432 to this file, and then
  20.  * modify a few indexed cache operations.  *sigh*
  21.  */
  22. #include <linux/init.h>
  23. #include <linux/kernel.h>
  24. #include <linux/sched.h>
  25. #include <linux/mm.h>
  26. #include <asm/bcache.h>
  27. #include <asm/io.h>
  28. #include <asm/page.h>
  29. #include <asm/pgtable.h>
  30. #include <asm/system.h>
  31. #include <asm/bootinfo.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. #include <asm/asm.h>
  38. #include <asm/cacheops.h>
  39. #undef DEBUG_CACHE
  40. /* Primary cache parameters. */
  41. static int icache_size, dcache_size; /* Size in bytes */
  42. static int ic_lsize, dc_lsize;       /* LineSize in bytes */
  43. /* -------------------------------------------------------------------- */
  44. /* #include <asm/r4kcache.h> */
  45. extern inline void flush_icache_line_indexed(unsigned long addr)
  46. {
  47. __asm__ __volatile__(
  48. ".set noreordernt"
  49. ".set mips3nt"
  50. "cache %1, (%0)nt"
  51. "cache %1, 1(%0)nt"
  52. ".set mips0nt"
  53. ".set reorder"
  54. :
  55. : "r" (addr),
  56.   "i" (Index_Invalidate_I));
  57. }
  58. extern inline void flush_dcache_line_indexed(unsigned long addr)
  59. {
  60. __asm__ __volatile__(
  61. ".set noreordernt"
  62. ".set mips3nt"
  63. "cache %1, (%0)nt"
  64. "cache %1, 1(%0)nt"
  65. ".set mips0nt"
  66. ".set reorder"
  67. :
  68. : "r" (addr),
  69.   "i" (Index_Writeback_Inv_D));
  70. }
  71. extern inline void flush_icache_line(unsigned long addr)
  72. {
  73. __asm__ __volatile__(
  74. ".set noreordernt"
  75. ".set mips3nt"
  76. "cache %1, (%0)nt"
  77. ".set mips0nt"
  78. ".set reorder"
  79. :
  80. : "r" (addr),
  81.   "i" (Hit_Invalidate_I));
  82. }
  83. extern inline void flush_dcache_line(unsigned long addr)
  84. {
  85. __asm__ __volatile__(
  86. ".set noreordernt"
  87. ".set mips3nt"
  88. "cache %1, (%0)nt"
  89. ".set mips0nt"
  90. ".set reorder"
  91. :
  92. : "r" (addr),
  93.   "i" (Hit_Writeback_Inv_D));
  94. }
  95. extern inline void invalidate_dcache_line(unsigned long addr)
  96. {
  97. __asm__ __volatile__(
  98. ".set noreordernt"
  99. ".set mips3nt"
  100. "cache %1, (%0)nt"
  101. ".set mips0nt"
  102. ".set reorder"
  103. :
  104. : "r" (addr),
  105.   "i" (Hit_Invalidate_D));
  106. }
  107. /*
  108.  * The next two are for badland addresses like signal trampolines.
  109.  */
  110. extern inline void protected_flush_icache_line(unsigned long addr)
  111. {
  112. __asm__ __volatile__(
  113. ".set noreordernt"
  114. ".set mips3n"
  115. "1:tcache %1,(%0)n"
  116. "2:t.set mips0nt"
  117. ".set reordernt"
  118. ".sectiont__ex_table,"a"nt"
  119. STR(PTR)"t1b,2bnt"
  120. ".previous"
  121. :
  122. : "r" (addr),
  123.   "i" (Hit_Invalidate_I));
  124. }
  125. extern inline void protected_writeback_dcache_line(unsigned long addr)
  126. {
  127. __asm__ __volatile__(
  128. ".set noreordernt"
  129. ".set mips3n"
  130. "1:tcache %1,(%0)n"
  131. "2:t.set mips0nt"
  132. ".set reordernt"
  133. ".sectiont__ex_table,"a"nt"
  134. STR(PTR)"t1b,2bnt"
  135. ".previous"
  136. :
  137. : "r" (addr),
  138.   "i" (Hit_Writeback_D));
  139. }
  140. #define cache32_unroll32(base,op)
  141. __asm__ __volatile__("
  142. .set noreorder;
  143. .set mips3;
  144. cache %1, 0x000(%0); cache %1, 0x020(%0);
  145. cache %1, 0x040(%0); cache %1, 0x060(%0);
  146. cache %1, 0x080(%0); cache %1, 0x0a0(%0);
  147. cache %1, 0x0c0(%0); cache %1, 0x0e0(%0);
  148. cache %1, 0x100(%0); cache %1, 0x120(%0);
  149. cache %1, 0x140(%0); cache %1, 0x160(%0);
  150. cache %1, 0x180(%0); cache %1, 0x1a0(%0);
  151. cache %1, 0x1c0(%0); cache %1, 0x1e0(%0);
  152. cache %1, 0x200(%0); cache %1, 0x220(%0);
  153. cache %1, 0x240(%0); cache %1, 0x260(%0);
  154. cache %1, 0x280(%0); cache %1, 0x2a0(%0);
  155. cache %1, 0x2c0(%0); cache %1, 0x2e0(%0);
  156. cache %1, 0x300(%0); cache %1, 0x320(%0);
  157. cache %1, 0x340(%0); cache %1, 0x360(%0);
  158. cache %1, 0x380(%0); cache %1, 0x3a0(%0);
  159. cache %1, 0x3c0(%0); cache %1, 0x3e0(%0);
  160. .set mips0;
  161. .set reorder"
  162. :
  163. : "r" (base),
  164.   "i" (op));
  165. extern inline void blast_dcache32(void)
  166. {
  167. unsigned long start = KSEG0;
  168. unsigned long end = (start + dcache_size/2);
  169. while(start < end) {
  170. cache32_unroll32(start,Index_Writeback_Inv_D);
  171. cache32_unroll32(start+1,Index_Writeback_Inv_D);
  172. start += 0x400;
  173. }
  174. }
  175. extern inline void blast_dcache32_page(unsigned long page)
  176. {
  177. unsigned long start = page;
  178. unsigned long end = (start + PAGE_SIZE);
  179. while(start < end) {
  180. cache32_unroll32(start,Hit_Writeback_Inv_D);
  181. start += 0x400;
  182. }
  183. }
  184. extern inline void blast_dcache32_page_indexed(unsigned long page)
  185. {
  186. unsigned long start = page;
  187. unsigned long end = (start + PAGE_SIZE);
  188. while(start < end) {
  189. cache32_unroll32(start,Index_Writeback_Inv_D);
  190. cache32_unroll32(start+1,Index_Writeback_Inv_D);
  191. start += 0x400;
  192. }
  193. }
  194. extern inline void blast_icache32(void)
  195. {
  196. unsigned long start = KSEG0;
  197. unsigned long end = (start + icache_size/2);
  198. while(start < end) {
  199. cache32_unroll32(start,Index_Invalidate_I);
  200. cache32_unroll32(start+1,Index_Invalidate_I);
  201. start += 0x400;
  202. }
  203. }
  204. extern inline void blast_icache32_page(unsigned long page)
  205. {
  206. unsigned long start = page;
  207. unsigned long end = (start + PAGE_SIZE);
  208. while(start < end) {
  209. cache32_unroll32(start,Hit_Invalidate_I);
  210. start += 0x400;
  211. }
  212. }
  213. extern inline void blast_icache32_page_indexed(unsigned long page)
  214. {
  215. unsigned long start = page;
  216. unsigned long end = (start + PAGE_SIZE);
  217. while(start < end) {
  218. cache32_unroll32(start,Index_Invalidate_I);
  219. cache32_unroll32(start+1,Index_Invalidate_I);
  220. start += 0x400;
  221. }
  222. }
  223. /* -------------------------------------------------------------------- */
  224. static void r5432_clear_page_d32(void * page)
  225. {
  226. __asm__ __volatile__(
  227. ".settnoreordernt"
  228. ".settnoatnt"
  229. ".settmips3nt"
  230. "daddiut$1,%0,%2n"
  231. "1:tcachet%3,(%0)nt"
  232. "sdt$0,(%0)nt"
  233. "sdt$0,8(%0)nt"
  234. "sdt$0,16(%0)nt"
  235. "sdt$0,24(%0)nt"
  236. "daddiut%0,64nt"
  237. "cachet%3,-32(%0)nt"
  238. "sdt$0,-32(%0)nt"
  239. "sdt$0,-24(%0)nt"
  240. "sdt$0,-16(%0)nt"
  241. "bnet$1,%0,1bnt"
  242. "sdt$0,-8(%0)nt"
  243. ".settmips0nt"
  244. ".settatnt"
  245. ".settreorder"
  246. :"=r" (page)
  247. :"0" (page),
  248.  "I" (PAGE_SIZE),
  249.  "i" (Create_Dirty_Excl_D)
  250. :"$1","memory");
  251. }
  252. /*
  253.  * This is still inefficient.  We only can do better if we know the
  254.  * virtual address where the copy will be accessed.
  255.  */
  256. static void r5432_copy_page_d32(void * to, void * from)
  257. {
  258. unsigned long dummy1, dummy2;
  259. unsigned long reg1, reg2, reg3, reg4;
  260. __asm__ __volatile__(
  261. ".settnoreordernt"
  262. ".settnoatnt"
  263. ".settmips3nt"
  264. "daddiut$1,%0,%8n"
  265. "1:tcachet%9,(%0)nt"
  266. "lwt%2,(%1)nt"
  267. "lwt%3,4(%1)nt"
  268. "lwt%4,8(%1)nt"
  269. "lwt%5,12(%1)nt"
  270. "swt%2,(%0)nt"
  271. "swt%3,4(%0)nt"
  272. "swt%4,8(%0)nt"
  273. "swt%5,12(%0)nt"
  274. "lwt%2,16(%1)nt"
  275. "lwt%3,20(%1)nt"
  276. "lwt%4,24(%1)nt"
  277. "lwt%5,28(%1)nt"
  278. "swt%2,16(%0)nt"
  279. "swt%3,20(%0)nt"
  280. "swt%4,24(%0)nt"
  281. "swt%5,28(%0)nt"
  282. "cachet%9,32(%0)nt"
  283. "daddiut%0,64nt"
  284. "daddiut%1,64nt"
  285. "lwt%2,-32(%1)nt"
  286. "lwt%3,-28(%1)nt"
  287. "lwt%4,-24(%1)nt"
  288. "lwt%5,-20(%1)nt"
  289. "swt%2,-32(%0)nt"
  290. "swt%3,-28(%0)nt"
  291. "swt%4,-24(%0)nt"
  292. "swt%5,-20(%0)nt"
  293. "lwt%2,-16(%1)nt"
  294. "lwt%3,-12(%1)nt"
  295. "lwt%4,-8(%1)nt"
  296. "lwt%5,-4(%1)nt"
  297. "swt%2,-16(%0)nt"
  298. "swt%3,-12(%0)nt"
  299. "swt%4,-8(%0)nt"
  300. "bnet$1,%0,1bnt"
  301. "swt%5,-4(%0)nt"
  302. ".settmips0nt"
  303. ".settatnt"
  304. ".settreorder"
  305. :"=r" (dummy1), "=r" (dummy2),
  306.  "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
  307. :"0" (to), "1" (from),
  308.  "I" (PAGE_SIZE),
  309.  "i" (Create_Dirty_Excl_D));
  310. }
  311. /*
  312.  * If you think for one second that this stuff coming up is a lot
  313.  * of bulky code eating too many kernel cache lines.  Think _again_.
  314.  *
  315.  * Consider:
  316.  * 1) Taken branches have a 3 cycle penalty on R4k
  317.  * 2) The branch itself is a real dead cycle on even R4600/R5000.
  318.  * 3) Only one of the following variants of each type is even used by
  319.  *    the kernel based upon the cache parameters we detect at boot time.
  320.  *
  321.  * QED.
  322.  */
  323. static inline void r5432_flush_cache_all_d32i32(void)
  324. {
  325. blast_dcache32(); blast_icache32();
  326. }
  327. static void r5432_flush_cache_range_d32i32(struct mm_struct *mm,
  328.  unsigned long start,
  329.  unsigned long end)
  330. {
  331. if (mm->context != 0) {
  332. #ifdef DEBUG_CACHE
  333. printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
  334. #endif
  335. blast_dcache32(); blast_icache32();
  336. }
  337. }
  338. /*
  339.  * On architectures like the Sparc, we could get rid of lines in
  340.  * the cache created only by a certain context, but on the MIPS
  341.  * (and actually certain Sparc's) we cannot.
  342.  */
  343. static void r5432_flush_cache_mm_d32i32(struct mm_struct *mm)
  344. {
  345. if (mm->context != 0) {
  346. #ifdef DEBUG_CACHE
  347. printk("cmm[%d]", (int)mm->context);
  348. #endif
  349. r5432_flush_cache_all_d32i32();
  350. }
  351. }
  352. static void r5432_flush_cache_page_d32i32(struct vm_area_struct *vma,
  353. unsigned long page)
  354. {
  355. struct mm_struct *mm = vma->vm_mm;
  356. pgd_t *pgdp;
  357. pmd_t *pmdp;
  358. pte_t *ptep;
  359. /*
  360.  * If ownes no valid ASID yet, cannot possibly have gotten
  361.  * this page into the cache.
  362.  */
  363. if (mm->context == 0)
  364. return;
  365. #ifdef DEBUG_CACHE
  366. printk("cpage[%d,%08lx]", (int)mm->context, page);
  367. #endif
  368. page &= PAGE_MASK;
  369. pgdp = pgd_offset(mm, page);
  370. pmdp = pmd_offset(pgdp, page);
  371. ptep = pte_offset(pmdp, page);
  372. /*
  373.  * If the page isn't marked valid, the page cannot possibly be
  374.  * in the cache.
  375.  */
  376. if (!(pte_val(*ptep) & _PAGE_PRESENT))
  377. return;
  378. /*
  379.  * Doing flushes for another ASID than the current one is
  380.  * too difficult since stupid R4k caches do a TLB translation
  381.  * for every cache flush operation.  So we do indexed flushes
  382.  * in that case, which doesn't overly flush the cache too much.
  383.  */
  384. if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
  385. blast_dcache32_page(page);
  386. } else {
  387. /*
  388.  * Do indexed flush, too much work to get the (possible)
  389.  * tlb refills to work correctly.
  390.  */
  391. page = (KSEG0 + (page & (dcache_size - 1)));
  392. blast_dcache32_page_indexed(page);
  393. }
  394. }
  395. /* If the addresses passed to these routines are valid, they are
  396.  * either:
  397.  *
  398.  * 1) In KSEG0, so we can do a direct flush of the page.
  399.  * 2) In KSEG2, and since every process can translate those
  400.  *    addresses all the time in kernel mode we can do a direct
  401.  *    flush.
  402.  * 3) In KSEG1, no flush necessary.
  403.  */
  404. static void r5432_flush_page_to_ram_d32(struct page *page)
  405. {
  406. blast_dcache32_page((unsigned long)page_address(page));
  407. }
  408. static void 
  409. r5432_flush_icache_range(unsigned long start, unsigned long end)
  410. {
  411. r5432_flush_cache_all_d32i32();
  412. }
  413. /*
  414.  * Ok, this seriously sucks.  We use them to flush a user page but don't
  415.  * know the virtual address, so we have to blast away the whole icache
  416.  * which is significantly more expensive than the real thing.
  417.  */
  418. static void
  419. r5432_flush_icache_page_i32(struct vm_area_struct *vma, struct page *page)
  420. {
  421. if (!(vma->vm_flags & VM_EXEC))
  422. return;
  423. r5432_flush_cache_all_d32i32();
  424. }
  425. /*
  426.  * Writeback and invalidate the primary cache dcache before DMA.
  427.  */
  428. static void
  429. r5432_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
  430. {
  431. unsigned long end, a;
  432. if (size >= dcache_size) {
  433. flush_cache_all();
  434. } else {
  435. a = addr & ~(dc_lsize - 1);
  436. end = (addr + size) & ~(dc_lsize - 1);
  437. while (1) {
  438. flush_dcache_line(a); /* Hit_Writeback_Inv_D */
  439. if (a == end) break;
  440. a += dc_lsize;
  441. }
  442. }
  443. bc_wback_inv(addr, size);
  444. }
  445. static void
  446. r5432_dma_cache_inv_pc(unsigned long addr, unsigned long size)
  447. {
  448. unsigned long end, a;
  449. if (size >= dcache_size) {
  450. flush_cache_all();
  451. } else {
  452. a = addr & ~(dc_lsize - 1);
  453. end = (addr + size) & ~(dc_lsize - 1);
  454. while (1) {
  455. flush_dcache_line(a); /* Hit_Writeback_Inv_D */
  456. if (a == end) break;
  457. a += dc_lsize;
  458. }
  459. }
  460. bc_inv(addr, size);
  461. }
  462. static void
  463. r5432_dma_cache_wback(unsigned long addr, unsigned long size)
  464. {
  465. panic("r5432_dma_cache called - should not happen.n");
  466. }
  467. /*
  468.  * While we're protected against bad userland addresses we don't care
  469.  * very much about what happens in that case.  Usually a segmentation
  470.  * fault will dump the process later on anyway ...
  471.  */
  472. static void r5432_flush_cache_sigtramp(unsigned long addr)
  473. {
  474. protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
  475. protected_flush_icache_line(addr & ~(ic_lsize - 1));
  476. }
  477. #undef DEBUG_TLB
  478. #undef DEBUG_TLBUPDATE
  479. #define NTLB_ENTRIES       48  /* Fixed on all R4XX0 variants... */
  480. #define NTLB_ENTRIES_HALF  24  /* Fixed on all R4XX0 variants... */
  481. void flush_tlb_all(void)
  482. {
  483. unsigned long old_ctx;
  484. int entry;
  485. unsigned long flags;
  486. #ifdef DEBUG_TLB
  487. printk("[tlball]");
  488. #endif
  489. __save_and_cli(flags);
  490. /* Save old context and create impossible VPN2 value */
  491. old_ctx = (get_entryhi() & 0xff);
  492. set_entryhi(KSEG0);
  493. set_entrylo0(0);
  494. set_entrylo1(0);
  495. BARRIER;
  496. entry = get_wired();
  497. /* Blast 'em all away. */
  498. while(entry < NTLB_ENTRIES) {
  499. set_index(entry);
  500. BARRIER;
  501. tlb_write_indexed();
  502. BARRIER;
  503. entry++;
  504. }
  505. BARRIER;
  506. set_entryhi(old_ctx);
  507. __restore_flags(flags);
  508. }
  509. void flush_tlb_mm(struct mm_struct *mm)
  510. {
  511. if (mm->context != 0) {
  512. unsigned long flags;
  513. #ifdef DEBUG_TLB
  514. printk("[tlbmm<%d>]", mm->context);
  515. #endif
  516. __save_and_cli(flags);
  517. get_new_mmu_context(mm, asid_cache);
  518. if (mm == current->active_mm)
  519. set_entryhi(mm->context & 0xff);
  520. __restore_flags(flags);
  521. }
  522. }
  523. void flush_tlb_range(struct mm_struct *mm, unsigned long start,
  524. unsigned long end)
  525. {
  526. if(mm->context != 0) {
  527. unsigned long flags;
  528. int size;
  529. #ifdef DEBUG_TLB
  530. printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
  531.        start, end);
  532. #endif
  533. __save_and_cli(flags);
  534. size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
  535. size = (size + 1) >> 1;
  536. if(size <= NTLB_ENTRIES_HALF) {
  537. int oldpid = (get_entryhi() & 0xff);
  538. int newpid = (mm->context & 0xff);
  539. start &= (PAGE_MASK << 1);
  540. end += ((PAGE_SIZE << 1) - 1);
  541. end &= (PAGE_MASK << 1);
  542. while(start < end) {
  543. int idx;
  544. set_entryhi(start | newpid);
  545. start += (PAGE_SIZE << 1);
  546. BARRIER;
  547. tlb_probe();
  548. BARRIER;
  549. idx = get_index();
  550. set_entrylo0(0);
  551. set_entrylo1(0);
  552. set_entryhi(KSEG0);
  553. BARRIER;
  554. if(idx < 0)
  555. continue;
  556. tlb_write_indexed();
  557. BARRIER;
  558. }
  559. set_entryhi(oldpid);
  560. } else {
  561. get_new_mmu_context(mm, asid_cache);
  562. if (mm == current->active_mm)
  563. set_entryhi(mm->context & 0xff);
  564. }
  565. __restore_flags(flags);
  566. }
  567. }
  568. void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
  569. {
  570. if (vma->vm_mm->context != 0) {
  571. unsigned long flags;
  572. int oldpid, newpid, idx;
  573. #ifdef DEBUG_TLB
  574. printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
  575. #endif
  576. newpid = (vma->vm_mm->context & 0xff);
  577. page &= (PAGE_MASK << 1);
  578. __save_and_cli(flags);
  579. oldpid = (get_entryhi() & 0xff);
  580. set_entryhi(page | newpid);
  581. BARRIER;
  582. tlb_probe();
  583. BARRIER;
  584. idx = get_index();
  585. set_entrylo0(0);
  586. set_entrylo1(0);
  587. set_entryhi(KSEG0);
  588. if(idx < 0)
  589. goto finish;
  590. BARRIER;
  591. tlb_write_indexed();
  592. finish:
  593. BARRIER;
  594. set_entryhi(oldpid);
  595. __restore_flags(flags);
  596. }
  597. }
  598. void pgd_init(unsigned long page)
  599. {
  600. unsigned long *p = (unsigned long *) page;
  601. int i;
  602. for(i = 0; i < USER_PTRS_PER_PGD; i+=8) {
  603. p[i + 0] = (unsigned long) invalid_pte_table;
  604. p[i + 1] = (unsigned long) invalid_pte_table;
  605. p[i + 2] = (unsigned long) invalid_pte_table;
  606. p[i + 3] = (unsigned long) invalid_pte_table;
  607. p[i + 4] = (unsigned long) invalid_pte_table;
  608. p[i + 5] = (unsigned long) invalid_pte_table;
  609. p[i + 6] = (unsigned long) invalid_pte_table;
  610. p[i + 7] = (unsigned long) invalid_pte_table;
  611. }
  612. }
  613. /* We will need multiple versions of update_mmu_cache(), one that just
  614.  * updates the TLB with the new pte(s), and another which also checks
  615.  * for the R4k "end of page" hardware bug and does the needy.
  616.  */
  617. void update_mmu_cache(struct vm_area_struct * vma,
  618.  unsigned long address, pte_t pte)
  619. {
  620. unsigned long flags;
  621. pgd_t *pgdp;
  622. pmd_t *pmdp;
  623. pte_t *ptep;
  624. int idx, pid;
  625. /*
  626.  * Handle debugger faulting in for debugee.
  627.  */
  628. if (current->active_mm != vma->vm_mm)
  629. return;
  630. pid = get_entryhi() & 0xff;
  631. #ifdef DEBUG_TLB
  632. if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) {
  633. printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%dn",
  634.        (int) (vma->vm_mm->context & 0xff), pid);
  635. }
  636. #endif
  637. __save_and_cli(flags);
  638. address &= (PAGE_MASK << 1);
  639. set_entryhi(address | (pid));
  640. pgdp = pgd_offset(vma->vm_mm, address);
  641. BARRIER;
  642. tlb_probe();
  643. BARRIER;
  644. pmdp = pmd_offset(pgdp, address);
  645. idx = get_index();
  646. ptep = pte_offset(pmdp, address);
  647. BARRIER;
  648. set_entrylo0(pte_val(*ptep++) >> 6);
  649. set_entrylo1(pte_val(*ptep) >> 6);
  650. set_entryhi(address | (pid));
  651. BARRIER;
  652. if(idx < 0) {
  653. tlb_write_random();
  654. } else {
  655. tlb_write_indexed();
  656. }
  657. BARRIER;
  658. set_entryhi(pid);
  659. BARRIER;
  660. __restore_flags(flags);
  661. }
  662. void show_regs(struct pt_regs * regs)
  663. {
  664. /* Saved main processor registers. */
  665. printk("$0 : %08lx %08lx %08lx %08lxn",
  666.        0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
  667. printk("$4 : %08lx %08lx %08lx %08lxn",
  668.                regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
  669. printk("$8 : %08lx %08lx %08lx %08lxn",
  670.        regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
  671. printk("$12: %08lx %08lx %08lx %08lxn",
  672.                regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
  673. printk("$16: %08lx %08lx %08lx %08lxn",
  674.        regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
  675. printk("$20: %08lx %08lx %08lx %08lxn",
  676.                regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
  677. printk("$24: %08lx %08lxn",
  678.        regs->regs[24], regs->regs[25]);
  679. printk("$28: %08lx %08lx %08lx %08lxn",
  680.        regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
  681. /* Saved cp0 registers. */
  682. printk("epc   : %08lx    %snStatus: %08lxnCause : %08lxn",
  683.        regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause);
  684. }
  685. void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
  686.      unsigned long entryhi, unsigned long pagemask)
  687. {
  688.         unsigned long flags;
  689.         unsigned long wired;
  690.         unsigned long old_pagemask;
  691.         unsigned long old_ctx;
  692.         __save_and_cli(flags);
  693.         /* Save old context and create impossible VPN2 value */
  694.         old_ctx = (get_entryhi() & 0xff);
  695.         old_pagemask = get_pagemask();
  696.         wired = get_wired();
  697.         set_wired (wired + 1);
  698.         set_index (wired);
  699.         BARRIER;    
  700.         set_pagemask (pagemask);
  701.         set_entryhi(entryhi);
  702.         set_entrylo0(entrylo0);
  703.         set_entrylo1(entrylo1);
  704.         BARRIER;    
  705.         tlb_write_indexed();
  706.         BARRIER;    
  707.     
  708.         set_entryhi(old_ctx);
  709.         BARRIER;    
  710.         set_pagemask (old_pagemask);
  711.         flush_tlb_all();    
  712.         __restore_flags(flags);
  713. }
  714. /* Detect and size the various r4k caches. */
  715. static void __init probe_icache(unsigned long config)
  716. {
  717. icache_size = 1 << (12 + ((config >> 9) & 7));
  718. ic_lsize = 16 << ((config >> 5) & 1);
  719. printk("Primary instruction cache %dkb, linesize %d bytes.n",
  720.        icache_size >> 10, ic_lsize);
  721. }
  722. static void __init probe_dcache(unsigned long config)
  723. {
  724. dcache_size = 1 << (12 + ((config >> 6) & 7));
  725. dc_lsize = 16 << ((config >> 4) & 1);
  726. printk("Primary data cache %dkb, linesize %d bytes.n",
  727.        dcache_size >> 10, dc_lsize);
  728. }
  729. void __init ld_mmu_r5432(void)
  730. {
  731. unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
  732. printk("CPU revision is: %08xn", read_32bit_cp0_register(CP0_PRID));
  733. change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
  734. probe_icache(config);
  735. probe_dcache(config);
  736. _clear_page = r5432_clear_page_d32;
  737. _copy_page = r5432_copy_page_d32;
  738. _flush_cache_all = r5432_flush_cache_all_d32i32;
  739. ___flush_cache_all = r5432_flush_cache_all_d32i32;
  740. _flush_page_to_ram = r5432_flush_page_to_ram_d32;
  741. _flush_cache_mm = r5432_flush_cache_mm_d32i32;
  742. _flush_cache_range = r5432_flush_cache_range_d32i32;
  743. _flush_cache_page = r5432_flush_cache_page_d32i32;
  744. _flush_icache_page = r5432_flush_icache_page_i32;
  745. _dma_cache_wback_inv = r5432_dma_cache_wback_inv_pc;
  746. _dma_cache_wback = r5432_dma_cache_wback;
  747. _dma_cache_inv = r5432_dma_cache_inv_pc;
  748. _flush_cache_sigtramp = r5432_flush_cache_sigtramp;
  749. _flush_icache_range = r5432_flush_icache_range; /* Ouch */
  750. __flush_cache_all();
  751. write_32bit_cp0_register(CP0_WIRED, 0);
  752. /*
  753.  * You should never change this register:
  754.  *   - On R4600 1.7 the tlbp never hits for pages smaller than
  755.  *     the value in the c0_pagemask register.
  756.  *   - The entire mm handling assumes the c0_pagemask register to
  757.  *     be set for 4kb pages.
  758.  */
  759. write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
  760. flush_tlb_all();
  761. }