aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm/srmmu.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-05-15 01:02:08 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-15 13:22:00 -0400
commitc7020eb4661eaf568a277056258a387ef88a9349 (patch)
tree4875adf04fa47e5da1a2cc7c2376ce876b784c09 /arch/sparc/mm/srmmu.c
parent834b97f15455097ccad36e098950b8ad2435f611 (diff)
sparc32: Remove cypress cpu support.
It's the one aberration in v8, the only cpu that didn't actually have hardware multiply and divide instructions. Signed-off-by: David S. Miller <davem@davemloft.net> Acked-by: Sam Ravnborg <sam@ravnborg.org>
Diffstat (limited to 'arch/sparc/mm/srmmu.c')
-rw-r--r--arch/sparc/mm/srmmu.c333
1 files changed, 2 insertions, 331 deletions
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 765b1a5ab5e0..4875fcd8fd7a 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -577,244 +577,6 @@ void swift_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
577 * with respect to cache coherency. 577 * with respect to cache coherency.
578 */ 578 */
579 579
580/* Cypress flushes. */
581static void cypress_flush_cache_all(void)
582{
583 volatile unsigned long cypress_sucks;
584 unsigned long faddr, tagval;
585
586 flush_user_windows();
587 for(faddr = 0; faddr < 0x10000; faddr += 0x20) {
588 __asm__ __volatile__("lda [%1 + %2] %3, %0\n\t" :
589 "=r" (tagval) :
590 "r" (faddr), "r" (0x40000),
591 "i" (ASI_M_DATAC_TAG));
592
593 /* If modified and valid, kick it. */
594 if((tagval & 0x60) == 0x60)
595 cypress_sucks = *(unsigned long *)(0xf0020000 + faddr);
596 }
597}
598
599static void cypress_flush_cache_mm(struct mm_struct *mm)
600{
601 register unsigned long a, b, c, d, e, f, g;
602 unsigned long flags, faddr;
603 int octx;
604
605 FLUSH_BEGIN(mm)
606 flush_user_windows();
607 local_irq_save(flags);
608 octx = srmmu_get_context();
609 srmmu_set_context(mm->context);
610 a = 0x20; b = 0x40; c = 0x60;
611 d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
612
613 faddr = (0x10000 - 0x100);
614 goto inside;
615 do {
616 faddr -= 0x100;
617 inside:
618 __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
619 "sta %%g0, [%0 + %2] %1\n\t"
620 "sta %%g0, [%0 + %3] %1\n\t"
621 "sta %%g0, [%0 + %4] %1\n\t"
622 "sta %%g0, [%0 + %5] %1\n\t"
623 "sta %%g0, [%0 + %6] %1\n\t"
624 "sta %%g0, [%0 + %7] %1\n\t"
625 "sta %%g0, [%0 + %8] %1\n\t" : :
626 "r" (faddr), "i" (ASI_M_FLUSH_CTX),
627 "r" (a), "r" (b), "r" (c), "r" (d),
628 "r" (e), "r" (f), "r" (g));
629 } while(faddr);
630 srmmu_set_context(octx);
631 local_irq_restore(flags);
632 FLUSH_END
633}
634
635static void cypress_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
636{
637 struct mm_struct *mm = vma->vm_mm;
638 register unsigned long a, b, c, d, e, f, g;
639 unsigned long flags, faddr;
640 int octx;
641
642 FLUSH_BEGIN(mm)
643 flush_user_windows();
644 local_irq_save(flags);
645 octx = srmmu_get_context();
646 srmmu_set_context(mm->context);
647 a = 0x20; b = 0x40; c = 0x60;
648 d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
649
650 start &= SRMMU_REAL_PMD_MASK;
651 while(start < end) {
652 faddr = (start + (0x10000 - 0x100));
653 goto inside;
654 do {
655 faddr -= 0x100;
656 inside:
657 __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
658 "sta %%g0, [%0 + %2] %1\n\t"
659 "sta %%g0, [%0 + %3] %1\n\t"
660 "sta %%g0, [%0 + %4] %1\n\t"
661 "sta %%g0, [%0 + %5] %1\n\t"
662 "sta %%g0, [%0 + %6] %1\n\t"
663 "sta %%g0, [%0 + %7] %1\n\t"
664 "sta %%g0, [%0 + %8] %1\n\t" : :
665 "r" (faddr),
666 "i" (ASI_M_FLUSH_SEG),
667 "r" (a), "r" (b), "r" (c), "r" (d),
668 "r" (e), "r" (f), "r" (g));
669 } while (faddr != start);
670 start += SRMMU_REAL_PMD_SIZE;
671 }
672 srmmu_set_context(octx);
673 local_irq_restore(flags);
674 FLUSH_END
675}
676
677static void cypress_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
678{
679 register unsigned long a, b, c, d, e, f, g;
680 struct mm_struct *mm = vma->vm_mm;
681 unsigned long flags, line;
682 int octx;
683
684 FLUSH_BEGIN(mm)
685 flush_user_windows();
686 local_irq_save(flags);
687 octx = srmmu_get_context();
688 srmmu_set_context(mm->context);
689 a = 0x20; b = 0x40; c = 0x60;
690 d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
691
692 page &= PAGE_MASK;
693 line = (page + PAGE_SIZE) - 0x100;
694 goto inside;
695 do {
696 line -= 0x100;
697 inside:
698 __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
699 "sta %%g0, [%0 + %2] %1\n\t"
700 "sta %%g0, [%0 + %3] %1\n\t"
701 "sta %%g0, [%0 + %4] %1\n\t"
702 "sta %%g0, [%0 + %5] %1\n\t"
703 "sta %%g0, [%0 + %6] %1\n\t"
704 "sta %%g0, [%0 + %7] %1\n\t"
705 "sta %%g0, [%0 + %8] %1\n\t" : :
706 "r" (line),
707 "i" (ASI_M_FLUSH_PAGE),
708 "r" (a), "r" (b), "r" (c), "r" (d),
709 "r" (e), "r" (f), "r" (g));
710 } while(line != page);
711 srmmu_set_context(octx);
712 local_irq_restore(flags);
713 FLUSH_END
714}
715
716/* Cypress is copy-back, at least that is how we configure it. */
717static void cypress_flush_page_to_ram(unsigned long page)
718{
719 register unsigned long a, b, c, d, e, f, g;
720 unsigned long line;
721
722 a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
723 page &= PAGE_MASK;
724 line = (page + PAGE_SIZE) - 0x100;
725 goto inside;
726 do {
727 line -= 0x100;
728 inside:
729 __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
730 "sta %%g0, [%0 + %2] %1\n\t"
731 "sta %%g0, [%0 + %3] %1\n\t"
732 "sta %%g0, [%0 + %4] %1\n\t"
733 "sta %%g0, [%0 + %5] %1\n\t"
734 "sta %%g0, [%0 + %6] %1\n\t"
735 "sta %%g0, [%0 + %7] %1\n\t"
736 "sta %%g0, [%0 + %8] %1\n\t" : :
737 "r" (line),
738 "i" (ASI_M_FLUSH_PAGE),
739 "r" (a), "r" (b), "r" (c), "r" (d),
740 "r" (e), "r" (f), "r" (g));
741 } while(line != page);
742}
743
744/* Cypress is also IO cache coherent. */
745static void cypress_flush_page_for_dma(unsigned long page)
746{
747}
748
749/* Cypress has unified L2 VIPT, from which both instructions and data
750 * are stored. It does not have an onboard icache of any sort, therefore
751 * no flush is necessary.
752 */
753static void cypress_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
754{
755}
756
757static void cypress_flush_tlb_all(void)
758{
759 srmmu_flush_whole_tlb();
760}
761
762static void cypress_flush_tlb_mm(struct mm_struct *mm)
763{
764 FLUSH_BEGIN(mm)
765 __asm__ __volatile__(
766 "lda [%0] %3, %%g5\n\t"
767 "sta %2, [%0] %3\n\t"
768 "sta %%g0, [%1] %4\n\t"
769 "sta %%g5, [%0] %3\n"
770 : /* no outputs */
771 : "r" (SRMMU_CTX_REG), "r" (0x300), "r" (mm->context),
772 "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE)
773 : "g5");
774 FLUSH_END
775}
776
777static void cypress_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
778{
779 struct mm_struct *mm = vma->vm_mm;
780 unsigned long size;
781
782 FLUSH_BEGIN(mm)
783 start &= SRMMU_PGDIR_MASK;
784 size = SRMMU_PGDIR_ALIGN(end) - start;
785 __asm__ __volatile__(
786 "lda [%0] %5, %%g5\n\t"
787 "sta %1, [%0] %5\n"
788 "1:\n\t"
789 "subcc %3, %4, %3\n\t"
790 "bne 1b\n\t"
791 " sta %%g0, [%2 + %3] %6\n\t"
792 "sta %%g5, [%0] %5\n"
793 : /* no outputs */
794 : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (start | 0x200),
795 "r" (size), "r" (SRMMU_PGDIR_SIZE), "i" (ASI_M_MMUREGS),
796 "i" (ASI_M_FLUSH_PROBE)
797 : "g5", "cc");
798 FLUSH_END
799}
800
801static void cypress_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
802{
803 struct mm_struct *mm = vma->vm_mm;
804
805 FLUSH_BEGIN(mm)
806 __asm__ __volatile__(
807 "lda [%0] %3, %%g5\n\t"
808 "sta %1, [%0] %3\n\t"
809 "sta %%g0, [%2] %4\n\t"
810 "sta %%g5, [%0] %3\n"
811 : /* no outputs */
812 : "r" (SRMMU_CTX_REG), "r" (mm->context), "r" (page & PAGE_MASK),
813 "i" (ASI_M_MMUREGS), "i" (ASI_M_FLUSH_PROBE)
814 : "g5");
815 FLUSH_END
816}
817
818/* viking.S */ 580/* viking.S */
819extern void viking_flush_cache_all(void); 581extern void viking_flush_cache_all(void);
820extern void viking_flush_cache_mm(struct mm_struct *mm); 582extern void viking_flush_cache_mm(struct mm_struct *mm);
@@ -1307,90 +1069,6 @@ static void __init init_hypersparc(void)
1307 hypersparc_setup_blockops(); 1069 hypersparc_setup_blockops();
1308} 1070}
1309 1071
1310static void __cpuinit poke_cypress(void)
1311{
1312 unsigned long mreg = srmmu_get_mmureg();
1313 unsigned long faddr, tagval;
1314 volatile unsigned long cypress_sucks;
1315 volatile unsigned long clear;
1316
1317 clear = srmmu_get_faddr();
1318 clear = srmmu_get_fstatus();
1319
1320 if (!(mreg & CYPRESS_CENABLE)) {
1321 for(faddr = 0x0; faddr < 0x10000; faddr += 20) {
1322 __asm__ __volatile__("sta %%g0, [%0 + %1] %2\n\t"
1323 "sta %%g0, [%0] %2\n\t" : :
1324 "r" (faddr), "r" (0x40000),
1325 "i" (ASI_M_DATAC_TAG));
1326 }
1327 } else {
1328 for(faddr = 0; faddr < 0x10000; faddr += 0x20) {
1329 __asm__ __volatile__("lda [%1 + %2] %3, %0\n\t" :
1330 "=r" (tagval) :
1331 "r" (faddr), "r" (0x40000),
1332 "i" (ASI_M_DATAC_TAG));
1333
1334 /* If modified and valid, kick it. */
1335 if((tagval & 0x60) == 0x60)
1336 cypress_sucks = *(unsigned long *)
1337 (0xf0020000 + faddr);
1338 }
1339 }
1340
1341 /* And one more, for our good neighbor, Mr. Broken Cypress. */
1342 clear = srmmu_get_faddr();
1343 clear = srmmu_get_fstatus();
1344
1345 mreg |= (CYPRESS_CENABLE | CYPRESS_CMODE);
1346 srmmu_set_mmureg(mreg);
1347}
1348
1349static const struct sparc32_cachetlb_ops cypress_ops = {
1350 .cache_all = cypress_flush_cache_all,
1351 .cache_mm = cypress_flush_cache_mm,
1352 .cache_page = cypress_flush_cache_page,
1353 .cache_range = cypress_flush_cache_range,
1354 .tlb_all = cypress_flush_tlb_all,
1355 .tlb_mm = cypress_flush_tlb_mm,
1356 .tlb_page = cypress_flush_tlb_page,
1357 .tlb_range = cypress_flush_tlb_range,
1358 .page_to_ram = cypress_flush_page_to_ram,
1359 .sig_insns = cypress_flush_sig_insns,
1360 .page_for_dma = cypress_flush_page_for_dma,
1361};
1362
1363static void __init init_cypress_common(void)
1364{
1365 init_vac_layout();
1366 sparc32_cachetlb_ops = &cypress_ops;
1367 poke_srmmu = poke_cypress;
1368}
1369
1370static void __init init_cypress_604(void)
1371{
1372 srmmu_name = "ROSS Cypress-604(UP)";
1373 srmmu_modtype = Cypress;
1374 init_cypress_common();
1375}
1376
1377static void __init init_cypress_605(unsigned long mrev)
1378{
1379 srmmu_name = "ROSS Cypress-605(MP)";
1380 if(mrev == 0xe) {
1381 srmmu_modtype = Cypress_vE;
1382 hwbug_bitmask |= HWBUG_COPYBACK_BROKEN;
1383 } else {
1384 if(mrev == 0xd) {
1385 srmmu_modtype = Cypress_vD;
1386 hwbug_bitmask |= HWBUG_ASIFLUSH_BROKEN;
1387 } else {
1388 srmmu_modtype = Cypress;
1389 }
1390 }
1391 init_cypress_common();
1392}
1393
1394static void __cpuinit poke_swift(void) 1072static void __cpuinit poke_swift(void)
1395{ 1073{
1396 unsigned long mreg; 1074 unsigned long mreg;
@@ -1912,22 +1590,15 @@ static void __init get_srmmu_type(void)
1912 break; 1590 break;
1913 case 0: 1591 case 0:
1914 case 2: 1592 case 2:
1915 /* Uniprocessor Cypress */
1916 init_cypress_604();
1917 break;
1918 case 10: 1593 case 10:
1919 case 11: 1594 case 11:
1920 case 12: 1595 case 12:
1921 /* _REALLY OLD_ Cypress MP chips... */
1922 case 13: 1596 case 13:
1923 case 14: 1597 case 14:
1924 case 15: 1598 case 15:
1925 /* MP Cypress mmu/cache-controller */
1926 init_cypress_605(mod_rev);
1927 break;
1928 default: 1599 default:
1929 /* Some other Cypress revision, assume a 605. */ 1600 prom_printf("Sparc-Linux Cypress support does not longer exit.\n");
1930 init_cypress_605(mod_rev); 1601 prom_halt();
1931 break; 1602 break;
1932 } 1603 }
1933 return; 1604 return;