1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/init.h>
21#include <linux/kernel.h>
22#include <linux/sched.h>
23#include <linux/mm.h>
24
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
34
35#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
36 "nop; nop; nop; nop; nop; nop;\n\t" \
37 ".set reorder\n\t")
38
39
40static int icache_size, dcache_size;
41static int ic_lsize, dc_lsize;
42
43
44static unsigned int scache_size, sc_lsize;
45
46#include <asm/cacheops.h>
47#include <asm/mips32_cache.h>
48
49#undef DEBUG_CACHE
50
51
52
53
54static void no_sc_noop(void) {}
55
56static struct bcache_ops no_sc_ops = {
57 (void *)no_sc_noop, (void *)no_sc_noop,
58 (void *)no_sc_noop, (void *)no_sc_noop
59};
60
61struct bcache_ops *bcops = &no_sc_ops;
62
63
64
65
66
67
68static void mips32_clear_page_dc(unsigned long page)
69{
70 unsigned long i;
71
72 if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
73 for (i=page; i<page+PAGE_SIZE; i+=dc_lsize) {
74 __asm__ __volatile__(
75 ".set\tnoreorder\n\t"
76 ".set\tnoat\n\t"
77 ".set\tmips3\n\t"
78 "cache\t%2,(%0)\n\t"
79 ".set\tmips0\n\t"
80 ".set\tat\n\t"
81 ".set\treorder"
82 :"=r" (i)
83 :"0" (i),
84 "I" (Create_Dirty_Excl_D));
85 }
86 }
87 for (i=page; i<page+PAGE_SIZE; i+=4)
88 *(unsigned long *)(i) = 0;
89}
90
91static void mips32_clear_page_sc(unsigned long page)
92{
93 unsigned long i;
94
95 if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
96 for (i=page; i<page+PAGE_SIZE; i+=sc_lsize) {
97 __asm__ __volatile__(
98 ".set\tnoreorder\n\t"
99 ".set\tnoat\n\t"
100 ".set\tmips3\n\t"
101 "cache\t%2,(%0)\n\t"
102 ".set\tmips0\n\t"
103 ".set\tat\n\t"
104 ".set\treorder"
105 :"=r" (i)
106 :"0" (i),
107 "I" (Create_Dirty_Excl_SD));
108 }
109 }
110 for (i=page; i<page+PAGE_SIZE; i+=4)
111 *(unsigned long *)(i) = 0;
112}
113
114static void mips32_copy_page_dc(unsigned long to, unsigned long from)
115{
116 unsigned long i;
117
118 if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
119 for (i=to; i<to+PAGE_SIZE; i+=dc_lsize) {
120 __asm__ __volatile__(
121 ".set\tnoreorder\n\t"
122 ".set\tnoat\n\t"
123 ".set\tmips3\n\t"
124 "cache\t%2,(%0)\n\t"
125 ".set\tmips0\n\t"
126 ".set\tat\n\t"
127 ".set\treorder"
128 :"=r" (i)
129 :"0" (i),
130 "I" (Create_Dirty_Excl_D));
131 }
132 }
133 for (i=0; i<PAGE_SIZE; i+=4)
134 *(unsigned long *)(to+i) = *(unsigned long *)(from+i);
135}
136
137static void mips32_copy_page_sc(unsigned long to, unsigned long from)
138{
139 unsigned long i;
140
141 if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) {
142 for (i=to; i<to+PAGE_SIZE; i+=sc_lsize) {
143 __asm__ __volatile__(
144 ".set\tnoreorder\n\t"
145 ".set\tnoat\n\t"
146 ".set\tmips3\n\t"
147 "cache\t%2,(%0)\n\t"
148 ".set\tmips0\n\t"
149 ".set\tat\n\t"
150 ".set\treorder"
151 :"=r" (i)
152 :"0" (i),
153 "I" (Create_Dirty_Excl_SD));
154 }
155 }
156 for (i=0; i<PAGE_SIZE; i+=4)
157 *(unsigned long *)(to+i) = *(unsigned long *)(from+i);
158}
159
160static inline void mips32_flush_cache_all_sc(void)
161{
162 unsigned long flags;
163
164 local_irq_save(flags);
165 blast_dcache(); blast_icache(); blast_scache();
166 local_irq_restore(flags);
167}
168
169static inline void mips32_flush_cache_all_pc(void)
170{
171 unsigned long flags;
172
173 local_irq_save(flags);
174 blast_dcache(); blast_icache();
175 local_irq_restore(flags);
176}
177
178static void
179mips32_flush_cache_range_sc(struct vm_area_struct *vma,
180 unsigned long start,
181 unsigned long end)
182{
183 struct mm_struct *mm = vma->vm_mm;
184 unsigned long flags;
185
186 if(mm->context == 0)
187 return;
188
189 start &= PAGE_MASK;
190#ifdef DEBUG_CACHE
191 printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
192#endif
193 if (vma) {
194 if(mm->context != current->mm->context) {
195 mips32_flush_cache_all_sc();
196 } else {
197 pgd_t *pgd;
198 pmd_t *pmd;
199 pte_t *pte;
200
201 local_irq_save(flags);
202 while(start < end) {
203 pgd = pgd_offset(mm, start);
204 pmd = pmd_offset(pgd, start);
205 pte = pte_offset(pmd, start);
206
207 if(pte_val(*pte) & _PAGE_VALID)
208 blast_scache_page(start);
209 start += PAGE_SIZE;
210 }
211 local_irq_restore(flags);
212 }
213 }
214}
215
216static void mips32_flush_cache_range_pc(struct vm_area_struct *vma,
217 unsigned long start,
218 unsigned long end)
219{
220 struct mm_struct *mm = vma->vm_mm;
221
222 if(mm->context != 0) {
223 unsigned long flags;
224
225#ifdef DEBUG_CACHE
226 printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
227#endif
228 local_irq_save(flags);
229 blast_dcache(); blast_icache();
230 local_irq_restore(flags);
231 }
232}
233
234
235
236
237
238
239static void mips32_flush_cache_mm_sc(struct mm_struct *mm)
240{
241 if(mm->context != 0) {
242#ifdef DEBUG_CACHE
243 printk("cmm[%d]", (int)mm->context);
244#endif
245 mips32_flush_cache_all_sc();
246 }
247}
248
249static void mips32_flush_cache_mm_pc(struct mm_struct *mm)
250{
251 if(mm->context != 0) {
252#ifdef DEBUG_CACHE
253 printk("cmm[%d]", (int)mm->context);
254#endif
255 mips32_flush_cache_all_pc();
256 }
257}
258
259
260
261
262
263static void mips32_flush_cache_page_sc(struct vm_area_struct *vma,
264 unsigned long page)
265{
266 struct mm_struct *mm = vma->vm_mm;
267 unsigned long flags;
268 pgd_t *pgdp;
269 pmd_t *pmdp;
270 pte_t *ptep;
271
272
273
274
275
276 if (mm->context == 0)
277 return;
278
279#ifdef DEBUG_CACHE
280 printk("cpage[%d,%08lx]", (int)mm->context, page);
281#endif
282 local_irq_save(flags);
283 page &= PAGE_MASK;
284 pgdp = pgd_offset(mm, page);
285 pmdp = pmd_offset(pgdp, page);
286 ptep = pte_offset(pmdp, page);
287
288
289
290
291
292 if (!(pte_val(*ptep) & _PAGE_VALID))
293 goto out;
294
295
296
297
298
299
300
301 if (mm->context != current->active_mm->context) {
302
303
304
305
306 page = (KSEG0 + (page & (scache_size - 1)));
307 blast_dcache_page_indexed(page);
308 blast_scache_page_indexed(page);
309 } else
310 blast_scache_page(page);
311out:
312 local_irq_restore(flags);
313}
314
315static void mips32_flush_cache_page_pc(struct vm_area_struct *vma,
316 unsigned long page)
317{
318 struct mm_struct *mm = vma->vm_mm;
319 unsigned long flags;
320 pgd_t *pgdp;
321 pmd_t *pmdp;
322 pte_t *ptep;
323
324
325
326
327
328 if (mm->context == 0)
329 return;
330
331#ifdef DEBUG_CACHE
332 printk("cpage[%d,%08lx]", (int)mm->context, page);
333#endif
334 local_irq_save(flags);
335 page &= PAGE_MASK;
336 pgdp = pgd_offset(mm, page);
337 pmdp = pmd_offset(pgdp, page);
338 ptep = pte_offset(pmdp, page);
339
340
341
342
343
344 if (!(pte_val(*ptep) & _PAGE_VALID))
345 goto out;
346
347
348
349
350
351
352
353 if (mm == current->active_mm) {
354 blast_dcache_page(page);
355 } else {
356
357
358
359 page = (KSEG0 + (page & (dcache_size - 1)));
360 blast_dcache_page_indexed(page);
361 }
362out:
363 local_irq_restore(flags);
364}
365
366
367
368
369
370
371
372
373
374
375static void mips32_flush_page_to_ram_sc(struct page *page)
376{
377 blast_scache_page((unsigned long)page_address(page));
378}
379
380static void mips32_flush_page_to_ram_pc(struct page *page)
381{
382 blast_dcache_page((unsigned long)page_address(page));
383}
384
385static void
386mips32_flush_icache_page_s(struct vm_area_struct *vma, struct page *page)
387{
388
389
390
391}
392
393static void
394mips32_flush_icache_range(unsigned long start, unsigned long end)
395{
396 flush_cache_all();
397}
398
399static void
400mips32_flush_icache_page(struct vm_area_struct *vma, struct page *page)
401{
402 int address;
403
404 if (!(vma->vm_flags & VM_EXEC))
405 return;
406
407 address = KSEG0 + ((unsigned long)page_address(page) & PAGE_MASK & (dcache_size - 1));
408 blast_icache_page_indexed(address);
409}
410
411
412
413
414static void
415mips32_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
416{
417 unsigned long end, a;
418 unsigned int flags;
419
420 if (size >= dcache_size) {
421 flush_cache_all();
422 } else {
423 local_irq_save(flags);
424 a = addr & ~(dc_lsize - 1);
425 end = (addr + size) & ~(dc_lsize - 1);
426 while (1) {
427 flush_dcache_line(a);
428 if (a == end) break;
429 a += dc_lsize;
430 }
431 local_irq_restore(flags);
432 }
433 bc_wback_inv(addr, size);
434}
435
436static void
437mips32_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
438{
439 unsigned long end, a;
440
441 if (size >= scache_size) {
442 flush_cache_all();
443 return;
444 }
445
446 a = addr & ~(sc_lsize - 1);
447 end = (addr + size) & ~(sc_lsize - 1);
448 while (1) {
449 flush_scache_line(a);
450 if (a == end) break;
451 a += sc_lsize;
452 }
453}
454
455static void
456mips32_dma_cache_inv_pc(unsigned long addr, unsigned long size)
457{
458 unsigned long end, a;
459 unsigned int flags;
460
461 if (size >= dcache_size) {
462 flush_cache_all();
463 } else {
464 local_irq_save(flags);
465 a = addr & ~(dc_lsize - 1);
466 end = (addr + size) & ~(dc_lsize - 1);
467 while (1) {
468 flush_dcache_line(a);
469 if (a == end) break;
470 a += dc_lsize;
471 }
472 local_irq_restore(flags);
473 }
474
475 bc_inv(addr, size);
476}
477
478static void
479mips32_dma_cache_inv_sc(unsigned long addr, unsigned long size)
480{
481 unsigned long end, a;
482
483 if (size >= scache_size) {
484 flush_cache_all();
485 return;
486 }
487
488 a = addr & ~(sc_lsize - 1);
489 end = (addr + size) & ~(sc_lsize - 1);
490 while (1) {
491 flush_scache_line(a);
492 if (a == end) break;
493 a += sc_lsize;
494 }
495}
496
497static void
498mips32_dma_cache_wback(unsigned long addr, unsigned long size)
499{
500 panic("mips32_dma_cache called - should not happen.\n");
501}
502
503
504
505
506
507
508static void mips32_flush_cache_sigtramp(unsigned long addr)
509{
510 protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
511 protected_flush_icache_line(addr & ~(ic_lsize - 1));
512}
513
514#undef DEBUG_TLB
515#undef DEBUG_TLBUPDATE
516
517void flush_tlb_all(void)
518{
519 unsigned long flags;
520 unsigned long old_ctx;
521 int entry;
522
523#ifdef DEBUG_TLB
524 printk("[tlball]");
525#endif
526
527 local_irq_save(flags);
528
529 old_ctx = (get_entryhi() & 0xff);
530 set_entryhi(KSEG0);
531 set_entrylo0(0);
532 set_entrylo1(0);
533 BARRIER;
534
535 entry = get_wired();
536
537
538 while(entry < mips_cpu.tlbsize) {
539
540 set_entryhi(KSEG0+entry*0x2000);
541 set_index(entry);
542 BARRIER;
543 tlb_write_indexed();
544 BARRIER;
545 entry++;
546 }
547 BARRIER;
548 set_entryhi(old_ctx);
549 local_irq_restore(flags);
550}
551
552void flush_tlb_mm(struct mm_struct *mm)
553{
554 if (mm->context != 0) {
555 unsigned long flags;
556
557#ifdef DEBUG_TLB
558 printk("[tlbmm<%d>]", mm->context);
559#endif
560 local_irq_save(flags);
561 get_new_mmu_context(mm, asid_cache);
562 if (mm == current->active_mm)
563 set_entryhi(mm->context & 0xff);
564 local_irq_restore(flags);
565 }
566}
567
568void flush_tlb_range(struct mm_struct *mm, unsigned long start,
569 unsigned long end)
570{
571 if(mm->context != 0) {
572 unsigned long flags;
573 int size;
574
575#ifdef DEBUG_TLB
576 printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
577 start, end);
578#endif
579 local_irq_save(flags);
580 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
581 size = (size + 1) >> 1;
582 if(size <= mips_cpu.tlbsize/2) {
583 int oldpid = (get_entryhi() & 0xff);
584 int newpid = (mm->context & 0xff);
585
586 start &= (PAGE_MASK << 1);
587 end += ((PAGE_SIZE << 1) - 1);
588 end &= (PAGE_MASK << 1);
589 while(start < end) {
590 int idx;
591
592 set_entryhi(start | newpid);
593 start += (PAGE_SIZE << 1);
594 BARRIER;
595 tlb_probe();
596 BARRIER;
597 idx = get_index();
598 set_entrylo0(0);
599 set_entrylo1(0);
600 if(idx < 0)
601 continue;
602
603 set_entryhi(KSEG0+idx*0x2000);
604 BARRIER;
605 tlb_write_indexed();
606 BARRIER;
607 }
608 set_entryhi(oldpid);
609 } else {
610 get_new_mmu_context(mm, asid_cache);
611 if (mm == current->active_mm)
612 set_entryhi(mm->context & 0xff);
613 }
614 local_irq_restore(flags);
615 }
616}
617
618void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
619{
620 if (vma->vm_mm->context != 0) {
621 unsigned long flags;
622 int oldpid, newpid, idx;
623
624#ifdef DEBUG_TLB
625 printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
626#endif
627 newpid = (vma->vm_mm->context & 0xff);
628 page &= (PAGE_MASK << 1);
629 local_irq_save(flags);
630 oldpid = (get_entryhi() & 0xff);
631 set_entryhi(page | newpid);
632 BARRIER;
633 tlb_probe();
634 BARRIER;
635 idx = get_index();
636 set_entrylo0(0);
637 set_entrylo1(0);
638 if(idx < 0)
639 goto finish;
640
641 set_entryhi(KSEG0+idx*0x2000);
642 BARRIER;
643 tlb_write_indexed();
644
645 finish:
646 BARRIER;
647 set_entryhi(oldpid);
648 local_irq_restore(flags);
649 }
650}
651
652void pgd_init(unsigned long page)
653{
654 unsigned long *p = (unsigned long *) page;
655 int i;
656
657 for(i = 0; i < USER_PTRS_PER_PGD; i+=8) {
658 p[i + 0] = (unsigned long) invalid_pte_table;
659 p[i + 1] = (unsigned long) invalid_pte_table;
660 p[i + 2] = (unsigned long) invalid_pte_table;
661 p[i + 3] = (unsigned long) invalid_pte_table;
662 p[i + 4] = (unsigned long) invalid_pte_table;
663 p[i + 5] = (unsigned long) invalid_pte_table;
664 p[i + 6] = (unsigned long) invalid_pte_table;
665 p[i + 7] = (unsigned long) invalid_pte_table;
666 }
667}
668
669
670
671
672void update_mmu_cache(struct vm_area_struct * vma,
673 unsigned long address, pte_t pte)
674{
675 unsigned long flags;
676 pgd_t *pgdp;
677 pmd_t *pmdp;
678 pte_t *ptep;
679 int idx, pid;
680
681
682
683
684 if (current->active_mm != vma->vm_mm)
685 return;
686
687 pid = get_entryhi() & 0xff;
688
689#ifdef DEBUG_TLB
690 if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) {
691 printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
692 (int) (vma->vm_mm->context & 0xff), pid);
693 }
694#endif
695
696 local_irq_save(flags);
697 address &= (PAGE_MASK << 1);
698 set_entryhi(address | (pid));
699 pgdp = pgd_offset(vma->vm_mm, address);
700 BARRIER;
701 tlb_probe();
702 BARRIER;
703 pmdp = pmd_offset(pgdp, address);
704 idx = get_index();
705 ptep = pte_offset(pmdp, address);
706 BARRIER;
707 set_entrylo0(pte_val(*ptep++) >> 6);
708 set_entrylo1(pte_val(*ptep) >> 6);
709 set_entryhi(address | (pid));
710 BARRIER;
711 if(idx < 0) {
712 tlb_write_random();
713 } else {
714 tlb_write_indexed();
715 }
716 BARRIER;
717 set_entryhi(pid);
718 BARRIER;
719 local_irq_restore(flags);
720}
721
722void show_regs(struct pt_regs * regs)
723{
724
725 printk("$0 : %08lx %08lx %08lx %08lx\n",
726 0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
727 printk("$4 : %08lx %08lx %08lx %08lx\n",
728 regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
729 printk("$8 : %08lx %08lx %08lx %08lx\n",
730 regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
731 printk("$12: %08lx %08lx %08lx %08lx\n",
732 regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
733 printk("$16: %08lx %08lx %08lx %08lx\n",
734 regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
735 printk("$20: %08lx %08lx %08lx %08lx\n",
736 regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
737 printk("$24: %08lx %08lx\n",
738 regs->regs[24], regs->regs[25]);
739 printk("$28: %08lx %08lx %08lx %08lx\n",
740 regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
741
742
743 printk("epc : %08lx %s\nStatus: %08lx\nCause : %08lx\n",
744 regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause);
745}
746
747void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
748 unsigned long entryhi, unsigned long pagemask)
749{
750 unsigned long flags;
751 unsigned long wired;
752 unsigned long old_pagemask;
753 unsigned long old_ctx;
754
755 local_irq_save(flags);
756
757 old_ctx = (get_entryhi() & 0xff);
758 old_pagemask = get_pagemask();
759 wired = get_wired();
760 set_wired (wired + 1);
761 set_index (wired);
762 BARRIER;
763 set_pagemask (pagemask);
764 set_entryhi(entryhi);
765 set_entrylo0(entrylo0);
766 set_entrylo1(entrylo1);
767 BARRIER;
768 tlb_write_indexed();
769 BARRIER;
770
771 set_entryhi(old_ctx);
772 BARRIER;
773 set_pagemask (old_pagemask);
774 flush_tlb_all();
775 local_irq_restore(flags);
776}
777
778
779static void __init probe_icache(unsigned long config)
780{
781 unsigned long config1;
782 unsigned int lsize;
783
784 if (!(config & (1 << 31))) {
785
786
787
788
789 icache_size = 1 << (12 + ((config >> 9) & 7));
790 ic_lsize = 16 << ((config >> 5) & 1);
791 mips_cpu.icache.linesz = ic_lsize;
792
793
794
795
796
797 if(!mips_cpu.icache.ways) mips_cpu.icache.ways = 1;
798 mips_cpu.icache.sets =
799 (icache_size / ic_lsize) / mips_cpu.icache.ways;
800 } else {
801 config1 = read_mips32_cp0_config1();
802
803 if ((lsize = ((config1 >> 19) & 7)))
804 mips_cpu.icache.linesz = 2 << lsize;
805 else
806 mips_cpu.icache.linesz = lsize;
807 mips_cpu.icache.sets = 64 << ((config1 >> 22) & 7);
808 mips_cpu.icache.ways = 1 + ((config1 >> 16) & 7);
809
810 ic_lsize = mips_cpu.icache.linesz;
811 icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways *
812 ic_lsize;
813 }
814 printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n",
815 icache_size >> 10, ic_lsize, mips_cpu.icache.ways);
816}
817
818static void __init probe_dcache(unsigned long config)
819{
820 unsigned long config1;
821 unsigned int lsize;
822
823 if (!(config & (1 << 31))) {
824
825
826
827
828 dcache_size = 1 << (12 + ((config >> 6) & 7));
829 dc_lsize = 16 << ((config >> 4) & 1);
830 mips_cpu.dcache.linesz = dc_lsize;
831
832
833
834
835 if(!mips_cpu.dcache.ways) mips_cpu.dcache.ways = 1;
836 mips_cpu.dcache.sets =
837 (dcache_size / dc_lsize) / mips_cpu.dcache.ways;
838 } else {
839 config1 = read_mips32_cp0_config1();
840
841 if ((lsize = ((config1 >> 10) & 7)))
842 mips_cpu.dcache.linesz = 2 << lsize;
843 else
844 mips_cpu.dcache.linesz= lsize;
845 mips_cpu.dcache.sets = 64 << ((config1 >> 13) & 7);
846 mips_cpu.dcache.ways = 1 + ((config1 >> 7) & 7);
847
848 dc_lsize = mips_cpu.dcache.linesz;
849 dcache_size =
850 mips_cpu.dcache.sets * mips_cpu.dcache.ways
851 * dc_lsize;
852 }
853 printk("Primary data cache %dkb, linesize %d bytes (%d ways)\n",
854 dcache_size >> 10, dc_lsize, mips_cpu.dcache.ways);
855}
856
857
858
859
860
861
862
863static int __init probe_scache(unsigned long config)
864{
865 extern unsigned long stext;
866 unsigned long flags, addr, begin, end, pow2;
867 int tmp;
868
869 if (mips_cpu.scache.flags == MIPS_CACHE_NOT_PRESENT)
870 return 0;
871
872 tmp = ((config >> 17) & 1);
873 if(tmp)
874 return 0;
875 tmp = ((config >> 22) & 3);
876 switch(tmp) {
877 case 0:
878 sc_lsize = 16;
879 break;
880 case 1:
881 sc_lsize = 32;
882 break;
883 case 2:
884 sc_lsize = 64;
885 break;
886 case 3:
887 sc_lsize = 128;
888 break;
889 }
890
891 begin = (unsigned long) &stext;
892 begin &= ~((4 * 1024 * 1024) - 1);
893 end = begin + (4 * 1024 * 1024);
894
895
896
897
898 local_irq_save(flags);
899
900
901 pow2 = (64 * 1024);
902 for(addr = begin; addr < end; addr = (begin + pow2)) {
903 unsigned long *p = (unsigned long *) addr;
904 __asm__ __volatile__("nop" : : "r" (*p));
905 pow2 <<= 1;
906 }
907
908
909 set_taglo(0);
910 set_taghi(0);
911 __asm__ __volatile__("nop; nop; nop; nop;");
912 __asm__ __volatile__("\n\t.set noreorder\n\t"
913 ".set mips3\n\t"
914 "cache 8, (%0)\n\t"
915 ".set mips0\n\t"
916 ".set reorder\n\t" : : "r" (begin));
917 __asm__ __volatile__("\n\t.set noreorder\n\t"
918 ".set mips3\n\t"
919 "cache 9, (%0)\n\t"
920 ".set mips0\n\t"
921 ".set reorder\n\t" : : "r" (begin));
922 __asm__ __volatile__("\n\t.set noreorder\n\t"
923 ".set mips3\n\t"
924 "cache 11, (%0)\n\t"
925 ".set mips0\n\t"
926 ".set reorder\n\t" : : "r" (begin));
927
928
929 pow2 = (128 * 1024);
930 tmp = 0;
931 for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) {
932 __asm__ __volatile__("\n\t.set noreorder\n\t"
933 ".set mips3\n\t"
934 "cache 7, (%0)\n\t"
935 ".set mips0\n\t"
936 ".set reorder\n\t" : : "r" (addr));
937 __asm__ __volatile__("nop; nop; nop; nop;");
938 if(!get_taglo())
939 break;
940 pow2 <<= 1;
941 }
942 local_irq_restore(flags);
943 addr -= begin;
944 printk("Secondary cache sized at %dK linesize %d bytes.\n",
945 (int) (addr >> 10), sc_lsize);
946 scache_size = addr;
947 return 1;
948}
949
950static void __init setup_noscache_funcs(void)
951{
952 _clear_page = (void *)mips32_clear_page_dc;
953 _copy_page = (void *)mips32_copy_page_dc;
954 _flush_cache_all = mips32_flush_cache_all_pc;
955 ___flush_cache_all = mips32_flush_cache_all_pc;
956 _flush_cache_mm = mips32_flush_cache_mm_pc;
957 _flush_cache_range = mips32_flush_cache_range_pc;
958 _flush_cache_page = mips32_flush_cache_page_pc;
959 _flush_page_to_ram = mips32_flush_page_to_ram_pc;
960
961 _flush_icache_page = mips32_flush_icache_page;
962
963 _dma_cache_wback_inv = mips32_dma_cache_wback_inv_pc;
964 _dma_cache_wback = mips32_dma_cache_wback;
965 _dma_cache_inv = mips32_dma_cache_inv_pc;
966}
967
968static void __init setup_scache_funcs(void)
969{
970 _flush_cache_all = mips32_flush_cache_all_sc;
971 ___flush_cache_all = mips32_flush_cache_all_sc;
972 _flush_cache_mm = mips32_flush_cache_mm_sc;
973 _flush_cache_range = mips32_flush_cache_range_sc;
974 _flush_cache_page = mips32_flush_cache_page_sc;
975 _flush_page_to_ram = mips32_flush_page_to_ram_sc;
976 _clear_page = (void *)mips32_clear_page_sc;
977 _copy_page = (void *)mips32_copy_page_sc;
978
979 _flush_icache_page = mips32_flush_icache_page_s;
980
981 _dma_cache_wback_inv = mips32_dma_cache_wback_inv_sc;
982 _dma_cache_wback = mips32_dma_cache_wback;
983 _dma_cache_inv = mips32_dma_cache_inv_sc;
984}
985
986typedef int (*probe_func_t)(unsigned long);
987
988static inline void __init setup_scache(unsigned int config)
989{
990 probe_func_t probe_scache_kseg1;
991 int sc_present = 0;
992
993
994 probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
995 sc_present = probe_scache_kseg1(config);
996
997 if (sc_present) {
998 mips_cpu.scache.linesz = sc_lsize;
999
1000
1001
1002
1003 if(!mips_cpu.scache.ways) mips_cpu.scache.ways = 1;
1004 mips_cpu.scache.sets =
1005 (scache_size / sc_lsize) / mips_cpu.scache.ways;
1006
1007 setup_scache_funcs();
1008 return;
1009 }
1010
1011 setup_noscache_funcs();
1012}
1013
1014static void __init probe_tlb(unsigned long config)
1015{
1016 unsigned long config1;
1017
1018 if (!(config & (1 << 31))) {
1019
1020
1021
1022
1023 mips_cpu.tlbsize = 48;
1024 } else {
1025 config1 = read_mips32_cp0_config1();
1026 if (!((config >> 7) & 3))
1027 panic("No MMU present");
1028 else
1029 mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1;
1030 }
1031
1032 printk("Number of TLB entries %d.\n", mips_cpu.tlbsize);
1033}
1034
1035void __init ld_mmu_mips32(void)
1036{
1037 unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
1038
1039 printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
1040
1041#ifdef CONFIG_MIPS_UNCACHED
1042 change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
1043#else
1044 change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
1045#endif
1046
1047 probe_icache(config);
1048 probe_dcache(config);
1049 setup_scache(config);
1050 probe_tlb(config);
1051
1052 _flush_cache_sigtramp = mips32_flush_cache_sigtramp;
1053 _flush_icache_range = mips32_flush_icache_range;
1054
1055 __flush_cache_all();
1056 write_32bit_cp0_register(CP0_WIRED, 0);
1057
1058
1059
1060
1061
1062
1063 write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
1064 flush_tlb_all();
1065}
1066