diff options
author | David S. Miller <davem@davemloft.net> | 2012-05-15 01:02:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-05-15 13:22:00 -0400 |
commit | c7020eb4661eaf568a277056258a387ef88a9349 (patch) | |
tree | 4875adf04fa47e5da1a2cc7c2376ce876b784c09 /arch/sparc/mm/srmmu.c | |
parent | 834b97f15455097ccad36e098950b8ad2435f611 (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.c | 333 |
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. */ | ||
581 | static 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 | |||
599 | static 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 | |||
635 | static 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 | |||
677 | static 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. */ | ||
717 | static 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. */ | ||
745 | static 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 | */ | ||
753 | static void cypress_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) | ||
754 | { | ||
755 | } | ||
756 | |||
757 | static void cypress_flush_tlb_all(void) | ||
758 | { | ||
759 | srmmu_flush_whole_tlb(); | ||
760 | } | ||
761 | |||
762 | static 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 | |||
777 | static 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 | |||
801 | static 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 */ |
819 | extern void viking_flush_cache_all(void); | 581 | extern void viking_flush_cache_all(void); |
820 | extern void viking_flush_cache_mm(struct mm_struct *mm); | 582 | extern 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 | ||
1310 | static 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 | |||
1349 | static 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 | |||
1363 | static void __init init_cypress_common(void) | ||
1364 | { | ||
1365 | init_vac_layout(); | ||
1366 | sparc32_cachetlb_ops = &cypress_ops; | ||
1367 | poke_srmmu = poke_cypress; | ||
1368 | } | ||
1369 | |||
1370 | static void __init init_cypress_604(void) | ||
1371 | { | ||
1372 | srmmu_name = "ROSS Cypress-604(UP)"; | ||
1373 | srmmu_modtype = Cypress; | ||
1374 | init_cypress_common(); | ||
1375 | } | ||
1376 | |||
1377 | static 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 | |||
1394 | static void __cpuinit poke_swift(void) | 1072 | static 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; |