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

嵌入式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.  * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
  7.  *
  8.  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  9.  * Copyright (C) 1997, 1998 Ralf Baechle ralf@gnu.org
  10.  *
  11.  * To do:
  12.  *
  13.  *  - this code is a overbloated pig
  14.  *  - many of the bug workarounds are not efficient at all, but at
  15.  *    least they are functional ...
  16.  */
  17. #include <linux/init.h>
  18. #include <linux/kernel.h>
  19. #include <linux/sched.h>
  20. #include <linux/mm.h>
  21. #include <asm/io.h>
  22. #include <asm/page.h>
  23. #include <asm/pgtable.h>
  24. #include <asm/system.h>
  25. #include <asm/bootinfo.h>
  26. #include <asm/mmu_context.h>
  27. /* CP0 hazard avoidance. */
  28. #define BARRIER __asm__ __volatile__(".set noreordernt" 
  29.      "nop; nop; nop; nop; nop; nop;nt" 
  30.      ".set reordernt")
  31. /* Primary cache parameters. */
  32. static int icache_size, dcache_size; /* Size in bytes */
  33. #define ic_lsize 32 /* Fixed to 32 byte on RM7000  */
  34. #define dc_lsize 32 /* Fixed to 32 byte on RM7000  */
  35. #define sc_lsize 32 /* Fixed to 32 byte on RM7000  */
  36. #define tc_pagesize (32*128)
  37. /* Secondary cache parameters. */
  38. #define scache_size (256*1024) /* Fixed to 256KiB on RM7000 */
  39. #include <asm/cacheops.h>
  40. #include <asm/r4kcache.h>
  41. int rm7k_tcache_enabled = 0;
  42. /*
  43.  * Not added to asm/r4kcache.h because it seems to be RM7000-specific.
  44.  */
  45. #define Page_Invalidate_T 0x16
  46. static inline void invalidate_tcache_page(unsigned long addr)
  47. {
  48. __asm__ __volatile__(
  49. ".settnoreorderttt# invalidate_tcache_pagent"
  50. ".settmips3nt"
  51. "cachet%1, (%0)nt"
  52. ".settmips0nt"
  53. ".settreorder"
  54. :
  55. : "r" (addr),
  56.   "i" (Page_Invalidate_T));
  57. }
  58. /*
  59.  * Zero an entire page.  Note that while the RM7000 has a second level cache
  60.  * it doesn't have a Create_Dirty_Excl_SD operation.
  61.  */
  62. static void rm7k_clear_page(void * page)
  63. {
  64. __asm__ __volatile__(
  65. ".settnoreordernt"
  66. ".settnoatnt"
  67. ".settmips3nt"
  68. "daddiut$1,%0,%2n"
  69. "1:tcachet%3,(%0)nt"
  70. "sdt$0,(%0)nt"
  71. "sdt$0,8(%0)nt"
  72. "sdt$0,16(%0)nt"
  73. "sdt$0,24(%0)nt"
  74. "daddiut%0,64nt"
  75. "cachet%3,-32(%0)nt"
  76. "sdt$0,-32(%0)nt"
  77. "sdt$0,-24(%0)nt"
  78. "sdt$0,-16(%0)nt"
  79. "bnet$1,%0,1bnt"
  80. "sdt$0,-8(%0)nt"
  81. ".settmips0nt"
  82. ".settatnt"
  83. ".settreorder"
  84. :"=r" (page)
  85. :"0" (page),
  86.  "I" (PAGE_SIZE),
  87.  "i" (Create_Dirty_Excl_D)
  88. :"$1","memory");
  89. }
  90. /*
  91.  * Copy an entire page.  Note that while the RM7000 has a second level cache
  92.  * it doesn't have a Create_Dirty_Excl_SD operation.
  93.  */
  94. static void rm7k_copy_page(void * to, void * from)
  95. {
  96. unsigned long dummy1, dummy2;
  97. unsigned long reg1, reg2, reg3, reg4;
  98. __asm__ __volatile__(
  99. ".settnoreordernt"
  100. ".settnoatnt"
  101. ".settmips3nt"
  102. "daddiut$1,%0,%8n"
  103. "1:tcachet%9,(%0)nt"
  104. "lwt%2,(%1)nt"
  105. "lwt%3,4(%1)nt"
  106. "lwt%4,8(%1)nt"
  107. "lwt%5,12(%1)nt"
  108. "swt%2,(%0)nt"
  109. "swt%3,4(%0)nt"
  110. "swt%4,8(%0)nt"
  111. "swt%5,12(%0)nt"
  112. "lwt%2,16(%1)nt"
  113. "lwt%3,20(%1)nt"
  114. "lwt%4,24(%1)nt"
  115. "lwt%5,28(%1)nt"
  116. "swt%2,16(%0)nt"
  117. "swt%3,20(%0)nt"
  118. "swt%4,24(%0)nt"
  119. "swt%5,28(%0)nt"
  120. "cachet%9,32(%0)nt"
  121. "daddiut%0,64nt"
  122. "daddiut%1,64nt"
  123. "lwt%2,-32(%1)nt"
  124. "lwt%3,-28(%1)nt"
  125. "lwt%4,-24(%1)nt"
  126. "lwt%5,-20(%1)nt"
  127. "swt%2,-32(%0)nt"
  128. "swt%3,-28(%0)nt"
  129. "swt%4,-24(%0)nt"
  130. "swt%5,-20(%0)nt"
  131. "lwt%2,-16(%1)nt"
  132. "lwt%3,-12(%1)nt"
  133. "lwt%4,-8(%1)nt"
  134. "lwt%5,-4(%1)nt"
  135. "swt%2,-16(%0)nt"
  136. "swt%3,-12(%0)nt"
  137. "swt%4,-8(%0)nt"
  138. "bnet$1,%0,1bnt"
  139. "swt%5,-4(%0)nt"
  140. ".settmips0nt"
  141. ".settatnt"
  142. ".settreorder"
  143. :"=r" (dummy1), "=r" (dummy2),
  144.  "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
  145. :"0" (to), "1" (from),
  146.  "I" (PAGE_SIZE),
  147.  "i" (Create_Dirty_Excl_D));
  148. }
  149. static void __flush_cache_all_d32i32(void)
  150. {
  151. blast_dcache32();
  152. blast_icache32();
  153. }
  154. static inline void rm7k_flush_cache_all_d32i32(void)
  155. {
  156. /* Yes! Caches that don't suck ...  */
  157. }
  158. static void rm7k_flush_cache_range_d32i32(struct mm_struct *mm,
  159.  unsigned long start,
  160.  unsigned long end)
  161. {
  162. /* RM7000 caches are sane ...  */
  163. }
  164. static void rm7k_flush_cache_mm_d32i32(struct mm_struct *mm)
  165. {
  166. /* RM7000 caches are sane ...  */
  167. }
  168. static void rm7k_flush_cache_page_d32i32(struct vm_area_struct *vma,
  169. unsigned long page)
  170. {
  171. /* RM7000 caches are sane ...  */
  172. }
  173. static void rm7k_flush_page_to_ram_d32i32(struct page * page)
  174. {
  175. /* Yes!  Caches that don't suck!  */
  176. }
  177. static void rm7k_flush_icache_range(unsigned long start, unsigned long end)
  178. {
  179. /*
  180.  * FIXME: This is overdoing things and harms performance.
  181.  */
  182. __flush_cache_all_d32i32();
  183. }
  184. static void rm7k_flush_icache_page(struct vm_area_struct *vma,
  185.                                    struct page *page)
  186. {
  187. /*
  188.  * FIXME: We should not flush the entire cache but establish some
  189.  * temporary mapping and use hit_invalidate operation to flush out
  190.  * the line from the cache.
  191.  */
  192. __flush_cache_all_d32i32();
  193. }
  194. /*
  195.  * Writeback and invalidate the primary cache dcache before DMA.
  196.  * (XXX These need to be fixed ...)
  197.  */
  198. static void
  199. rm7k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
  200. {
  201. unsigned long end, a;
  202. a = addr & ~(sc_lsize - 1);
  203. end = (addr + size) & ~(sc_lsize - 1);
  204. while (1) {
  205. flush_dcache_line(a); /* Hit_Writeback_Inv_D */
  206. flush_icache_line(a); /* Hit_Invalidate_I */
  207. flush_scache_line(a); /* Hit_Writeback_Inv_SD */
  208. if (a == end) break;
  209. a += sc_lsize;
  210. }
  211. if (!rm7k_tcache_enabled) 
  212. return;
  213. a = addr & ~(tc_pagesize - 1);
  214. end = (addr + size) & ~(tc_pagesize - 1);
  215. while(1) {
  216. invalidate_tcache_page(a); /* Page_Invalidate_T */
  217. if (a == end) break;
  218. a += tc_pagesize;
  219. }
  220. }
  221.        
  222. static void
  223. rm7k_dma_cache_inv(unsigned long addr, unsigned long size)
  224. {
  225. unsigned long end, a;
  226. a = addr & ~(sc_lsize - 1);
  227. end = (addr + size) & ~(sc_lsize - 1);
  228. while (1) {
  229. invalidate_dcache_line(a); /* Hit_Invalidate_D */
  230. flush_icache_line(a); /* Hit_Invalidate_I */
  231. invalidate_scache_line(a); /* Hit_Invalidate_SD */
  232. if (a == end) break;
  233. a += sc_lsize;
  234. }
  235. if (!rm7k_tcache_enabled) 
  236. return;
  237. a = addr & ~(tc_pagesize - 1);
  238. end = (addr + size) & ~(tc_pagesize - 1);
  239. while(1) {
  240. invalidate_tcache_page(a); /* Page_Invalidate_T */
  241. if (a == end) break;
  242. a += tc_pagesize;
  243. }
  244. }
  245. static void
  246. rm7k_dma_cache_wback(unsigned long addr, unsigned long size)
  247. {
  248. panic("rm7k_dma_cache_wback called - should not happen.n");
  249. }
  250. /*
  251.  * While we're protected against bad userland addresses we don't care
  252.  * very much about what happens in that case.  Usually a segmentation
  253.  * fault will dump the process later on anyway ...
  254.  */
  255. static void rm7k_flush_cache_sigtramp(unsigned long addr)
  256. {
  257. protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
  258. protected_flush_icache_line(addr & ~(ic_lsize - 1));
  259. }
  260. /*
  261.  * Undocumented RM7000:  Bit 29 in the info register of the RM7000 v2.0
  262.  * indicates if the TLB has 48 or 64 entries.
  263.  *
  264.  * 29      1 =>    64 entry JTLB
  265.  *         0 =>    48 entry JTLB
  266.  */
  267. static inline int __attribute__((const)) ntlb_entries(void)
  268. {
  269. if (get_info() & (1 << 29))
  270. return 64;
  271. return 48;
  272. }
  273. void flush_tlb_all(void)
  274. {
  275. unsigned long flags;
  276. unsigned long old_ctx;
  277. int entry;
  278. __save_and_cli(flags);
  279. /* Save old context and create impossible VPN2 value */
  280. old_ctx = get_entryhi() & 0xff;
  281. set_entryhi(KSEG0);
  282. set_entrylo0(0);
  283. set_entrylo1(0);
  284. BARRIER;
  285. entry = get_wired();
  286. /* Blast 'em all away. */
  287. while (entry < ntlb_entries()) {
  288. set_index(entry);
  289. BARRIER;
  290. tlb_write_indexed();
  291. BARRIER;
  292. entry++;
  293. }
  294. BARRIER;
  295. set_entryhi(old_ctx);
  296. __restore_flags(flags);
  297. }
  298. void flush_tlb_mm(struct mm_struct *mm)
  299. {
  300. if(mm->context != 0) {
  301. unsigned long flags;
  302. __save_and_cli(flags);
  303. get_new_mmu_context(mm, asid_cache);
  304. if (mm == current->mm)
  305. set_entryhi(mm->context & 0xff);
  306. __restore_flags(flags);
  307. }
  308. }
  309. void flush_tlb_range(struct mm_struct *mm, unsigned long start,
  310. unsigned long end)
  311. {
  312. if(mm->context != 0) {
  313. unsigned long flags;
  314. int size;
  315. __save_and_cli(flags);
  316. size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
  317. size = (size + 1) >> 1;
  318. if (size <= (ntlb_entries() / 2)) {
  319. int oldpid = (get_entryhi() & 0xff);
  320. int newpid = (mm->context & 0xff);
  321. start &= (PAGE_MASK << 1);
  322. end += ((PAGE_SIZE << 1) - 1);
  323. end &= (PAGE_MASK << 1);
  324. while(start < end) {
  325. int idx;
  326. set_entryhi(start | newpid);
  327. start += (PAGE_SIZE << 1);
  328. BARRIER;
  329. tlb_probe();
  330. BARRIER;
  331. idx = get_index();
  332. set_entrylo0(0);
  333. set_entrylo1(0);
  334. set_entryhi(KSEG0);
  335. BARRIER;
  336. if(idx < 0)
  337. continue;
  338. tlb_write_indexed();
  339. BARRIER;
  340. }
  341. set_entryhi(oldpid);
  342. } else {
  343. get_new_mmu_context(mm, asid_cache);
  344. if(mm == current->mm)
  345. set_entryhi(mm->context & 0xff);
  346. }
  347. __restore_flags(flags);
  348. }
  349. }
  350. void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
  351. {
  352. if(vma->vm_mm->context != 0) {
  353. unsigned long flags;
  354. int oldpid, newpid, idx;
  355. newpid = (vma->vm_mm->context & 0xff);
  356. page &= (PAGE_MASK << 1);
  357. __save_and_cli(flags);
  358. oldpid = (get_entryhi() & 0xff);
  359. set_entryhi(page | newpid);
  360. BARRIER;
  361. tlb_probe();
  362. BARRIER;
  363. idx = get_index();
  364. set_entrylo0(0);
  365. set_entrylo1(0);
  366. set_entryhi(KSEG0);
  367. if(idx < 0)
  368. goto finish;
  369. BARRIER;
  370. tlb_write_indexed();
  371. finish:
  372. BARRIER;
  373. set_entryhi(oldpid);
  374. __restore_flags(flags);
  375. }
  376. }
  377. void pgd_init(unsigned long page)
  378. {
  379. unsigned long *p = (unsigned long *) page;
  380. int i;
  381. for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
  382. p[i + 0] = (unsigned long) invalid_pte_table;
  383. p[i + 1] = (unsigned long) invalid_pte_table;
  384. p[i + 2] = (unsigned long) invalid_pte_table;
  385. p[i + 3] = (unsigned long) invalid_pte_table;
  386. p[i + 4] = (unsigned long) invalid_pte_table;
  387. p[i + 5] = (unsigned long) invalid_pte_table;
  388. p[i + 6] = (unsigned long) invalid_pte_table;
  389. p[i + 7] = (unsigned long) invalid_pte_table;
  390. }
  391. }
  392. /*
  393.  * We will need multiple versions of update_mmu_cache(), one that just
  394.  * updates the TLB with the new pte(s), and another which also checks
  395.  * for the R4k "end of page" hardware bug and does the needy.
  396.  */
  397. void update_mmu_cache(struct vm_area_struct * vma,
  398.  unsigned long address, pte_t pte)
  399. {
  400. unsigned long flags;
  401. pgd_t *pgdp;
  402. pmd_t *pmdp;
  403. pte_t *ptep;
  404. int idx, pid;
  405. /*
  406.  * Handle debugger faulting in for debugee.
  407.  */
  408. if (current->active_mm != vma->vm_mm)
  409. return;
  410. pid = get_entryhi() & 0xff;
  411. __save_and_cli(flags);
  412. address &= (PAGE_MASK << 1);
  413. set_entryhi(address | (pid));
  414. pgdp = pgd_offset(vma->vm_mm, address);
  415. BARRIER;
  416. tlb_probe();
  417. BARRIER;
  418. pmdp = pmd_offset(pgdp, address);
  419. idx = get_index();
  420. ptep = pte_offset(pmdp, address);
  421. BARRIER;
  422. set_entrylo0(pte_val(*ptep++) >> 6);
  423. set_entrylo1(pte_val(*ptep) >> 6);
  424. set_entryhi(address | (pid));
  425. BARRIER;
  426. if (idx < 0) {
  427. tlb_write_random();
  428. } else {
  429. tlb_write_indexed();
  430. }
  431. BARRIER;
  432. set_entryhi(pid);
  433. BARRIER;
  434. __restore_flags(flags);
  435. }
  436. void show_regs(struct pt_regs * regs)
  437. {
  438. /* Saved main processor registers. */
  439. printk(KERN_INFO "$0 : %08lx %08lx %08lx %08lxn",
  440.        0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
  441. printk(KERN_INFO "$4 : %08lx %08lx %08lx %08lxn",
  442.                regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
  443. printk(KERN_INFO "$8 : %08lx %08lx %08lx %08lxn",
  444.        regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
  445. printk(KERN_INFO "$12: %08lx %08lx %08lx %08lxn",
  446.                regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
  447. printk(KERN_INFO "$16: %08lx %08lx %08lx %08lxn",
  448.        regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
  449. printk(KERN_INFO "$20: %08lx %08lx %08lx %08lxn",
  450.                regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
  451. printk(KERN_INFO "$24: %08lx %08lxn",
  452.        regs->regs[24], regs->regs[25]);
  453. printk(KERN_INFO "$28: %08lx %08lx %08lx %08lxn",
  454.        regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
  455. /* Saved cp0 registers. */
  456. printk(KERN_INFO "epc   : %08lx    %snStatus: %08lxnCause : %08lxn",
  457.        regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause);
  458. }
  459. void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
  460.                      unsigned long entryhi, unsigned long pagemask)
  461. {
  462.         unsigned long flags;
  463.         unsigned long wired;
  464.         unsigned long old_pagemask;
  465.         unsigned long old_ctx;
  466.         __save_and_cli(flags);
  467.         /* Save old context and create impossible VPN2 value */
  468.         old_ctx = (get_entryhi() & 0xff);
  469.         old_pagemask = get_pagemask();
  470.         wired = get_wired();
  471.         set_wired (wired + 1);
  472.         set_index (wired);
  473.         BARRIER;    
  474.         set_pagemask (pagemask);
  475.         set_entryhi(entryhi);
  476.         set_entrylo0(entrylo0);
  477.         set_entrylo1(entrylo1);
  478.         BARRIER;    
  479.         tlb_write_indexed();
  480.         BARRIER;    
  481.     
  482.         set_entryhi(old_ctx);
  483.         BARRIER;    
  484.         set_pagemask (old_pagemask);
  485.         flush_tlb_all();    
  486.         __restore_flags(flags);
  487. }
  488. /* Used for loading TLB entries before trap_init() has started, when we
  489.    don't actually want to add a wired entry which remains throughout the
  490.    lifetime of the system */
  491. static int temp_tlb_entry __initdata;
  492. __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
  493.                                unsigned long entryhi, unsigned long pagemask)
  494. {
  495. int ret = 0;
  496.         unsigned long flags;
  497.         unsigned long wired;
  498.         unsigned long old_pagemask;
  499.         unsigned long old_ctx;
  500.         __save_and_cli(flags);
  501.         /* Save old context and create impossible VPN2 value */
  502.         old_ctx = (get_entryhi() & 0xff);
  503.         old_pagemask = get_pagemask();
  504.         wired = get_wired();
  505.         if (--temp_tlb_entry < wired) {
  506. printk(KERN_WARNING "No TLB space left for add_temporary_entryn");
  507. ret = -ENOSPC;
  508. goto out;
  509. }
  510.         set_index (temp_tlb_entry);
  511.         BARRIER;    
  512.         set_pagemask (pagemask);
  513.         set_entryhi(entryhi);
  514.         set_entrylo0(entrylo0);
  515.         set_entrylo1(entrylo1);
  516.         BARRIER;    
  517.         tlb_write_indexed();
  518.         BARRIER;    
  519.     
  520.         set_entryhi(old_ctx);
  521.         BARRIER;    
  522.         set_pagemask (old_pagemask);
  523.  out:
  524.         __restore_flags(flags);
  525. return ret;
  526. }
  527. /* Detect and size the caches. */
  528. static inline void probe_icache(unsigned long config)
  529. {
  530. icache_size = 1 << (12 + ((config >> 9) & 7));
  531. printk(KERN_INFO "Primary instruction cache %dKiB.n", icache_size >> 10);
  532. }
  533. static inline void probe_dcache(unsigned long config)
  534. {
  535. dcache_size = 1 << (12 + ((config >> 6) & 7));
  536. printk(KERN_INFO "Primary data cache %dKiB.n", dcache_size >> 10);
  537. }
  538. /* 
  539.  * This function is executed in the uncached segment KSEG1.
  540.  * It must not touch the stack, because the stack pointer still points
  541.  * into KSEG0. 
  542.  *
  543.  * Three options:
  544.  * - Write it in assembly and guarantee that we don't use the stack.
  545.  * - Disable caching for KSEG0 before calling it.
  546.  * - Pray that GCC doesn't randomly start using the stack.
  547.  *
  548.  * This being Linux, we obviously take the least sane of those options -
  549.  * following DaveM's lead in r4xx0.c
  550.  *
  551.  * It seems we get our kicks from relying on unguaranteed behaviour in GCC
  552.  */
  553. static __init void setup_scache(void)
  554. {
  555. int register i;
  556. set_cp0_config(1<<3 /* CONF_SE */);
  557. set_taglo(0);
  558. set_taghi(0);
  559. for (i=0; i<scache_size; i+=sc_lsize) {
  560. __asm__ __volatile__ (
  561.       ".set noreordernt"
  562.       ".set mips3nt"
  563.       "cache %1, (%0)nt"
  564.       ".set mips0nt"
  565.       ".set reorder"
  566.       :
  567.       : "r" (KSEG0ADDR(i)),
  568.         "i" (Index_Store_Tag_SD));
  569. }
  570. }
  571. static inline void probe_scache(unsigned long config)
  572. {
  573. void (*func)(void) = KSEG1ADDR(&setup_scache);
  574. if ((config >> 31) & 1)
  575. return;
  576. printk(KERN_INFO "Secondary cache %dKiB, linesize %d bytes.n",
  577.        (scache_size >> 10), sc_lsize);
  578. if ((config >> 3) & 1)
  579. return;
  580. printk(KERN_INFO "Enabling secondary cache...");
  581. func();
  582. printk("Donen");
  583. }
  584.  
  585. static inline void probe_tcache(unsigned long config)
  586. {
  587. if ((config >> 17) & 1)
  588. return;
  589. /* We can't enable the L3 cache yet. There may be board-specific
  590.  * magic necessary to turn it on, and blindly asking the CPU to
  591.  * start using it would may give cache errors.
  592.  *
  593.  * Also, board-specific knowledge may allow us to use the 
  594.  * CACHE Flash_Invalidate_T instruction if the tag RAM supports
  595.  * it, and may specify the size of the L3 cache so we don't have
  596.  * to probe it. 
  597.  */
  598. printk(KERN_INFO "Tertiary cache present, %s enabledn",
  599.        config&(1<<12) ? "already" : "not (yet)");
  600. if ((config >> 12) & 1)
  601. rm7k_tcache_enabled = 1;
  602. }
  603. void __init ld_mmu_rm7k(void)
  604. {
  605. unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
  606. unsigned long addr;
  607. printk("CPU revision is: %08xn", read_32bit_cp0_register(CP0_PRID));
  608.         change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
  609. /* RM7000 erratum #31. The icache is screwed at startup. */
  610. set_taglo(0);
  611. set_taghi(0);
  612. for (addr = KSEG0; addr <= KSEG0 + 4096; addr += ic_lsize) {
  613. __asm__ __volatile__ (
  614. ".set noreordernt"
  615. ".set mips3nt"
  616. "cachet%1, 0(%0)nt"
  617. "cachet%1, 0x1000(%0)nt"
  618. "cachet%1, 0x2000(%0)nt"
  619. "cachet%1, 0x3000(%0)nt"
  620. "cachet%2, 0(%0)nt"
  621. "cachet%2, 0x1000(%0)nt"
  622. "cachet%2, 0x2000(%0)nt"
  623. "cachet%2, 0x3000(%0)nt"
  624. "cachet%1, 0(%0)nt"
  625. "cachet%1, 0x1000(%0)nt"
  626. "cachet%1, 0x2000(%0)nt"
  627. "cachet%1, 0x3000(%0)nt"
  628. ".settmips0nt"
  629. ".settreordernt"
  630. :
  631. : "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill));
  632. }
  633. #ifndef CONFIG_MIPS_UNCACHED
  634. change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
  635. #endif
  636. probe_icache(config);
  637. probe_dcache(config);
  638. probe_scache(config);
  639. probe_tcache(config);
  640. printk("TLB has %d entries.n", ntlb_entries());
  641. _clear_page = rm7k_clear_page;
  642. _copy_page = rm7k_copy_page;
  643. _flush_cache_all = rm7k_flush_cache_all_d32i32;
  644. ___flush_cache_all = __flush_cache_all_d32i32;
  645. _flush_cache_mm = rm7k_flush_cache_mm_d32i32;
  646. _flush_cache_range = rm7k_flush_cache_range_d32i32;
  647. _flush_cache_page = rm7k_flush_cache_page_d32i32;
  648. _flush_page_to_ram = rm7k_flush_page_to_ram_d32i32;
  649. _flush_cache_sigtramp = rm7k_flush_cache_sigtramp;
  650. _flush_icache_range = rm7k_flush_icache_range;
  651. _flush_icache_page = rm7k_flush_icache_page;
  652. _dma_cache_wback_inv = rm7k_dma_cache_wback_inv;
  653. _dma_cache_wback = rm7k_dma_cache_wback;
  654. _dma_cache_inv = rm7k_dma_cache_inv;
  655. __flush_cache_all_d32i32();
  656. write_32bit_cp0_register(CP0_WIRED, 0);
  657. temp_tlb_entry = ntlb_entries() - 1;
  658. write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
  659. flush_tlb_all();
  660. }