diff options
author | David S. Miller <davem@davemloft.net> | 2006-01-31 21:33:25 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:11:24 -0500 |
commit | 3487d1d4414fbfab5d98ec559e6f84f55520cb15 (patch) | |
tree | b85ac7e9d8c07bd3c8a9d314d650b04cdf1ccc96 /arch/sparc64 | |
parent | 6b6d017235acad3ee1681140795593723bb9b9df (diff) |
[SPARC64]: Kill PROM locked TLB entry preservation code.
It is totally unnecessary complexity. After we take over
the trap table, we handle all PROM tlb misses fully.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64')
-rw-r--r-- | arch/sparc64/kernel/smp.c | 4 | ||||
-rw-r--r-- | arch/sparc64/kernel/tsb.S | 7 | ||||
-rw-r--r-- | arch/sparc64/mm/init.c | 295 |
3 files changed, 10 insertions, 296 deletions
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index d030c311cfee..0e7552546d36 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -116,14 +116,10 @@ static void smp_setup_percpu_timer(void); | |||
116 | 116 | ||
117 | static volatile unsigned long callin_flag = 0; | 117 | static volatile unsigned long callin_flag = 0; |
118 | 118 | ||
119 | extern void inherit_locked_prom_mappings(int save_p); | ||
120 | |||
121 | void __init smp_callin(void) | 119 | void __init smp_callin(void) |
122 | { | 120 | { |
123 | int cpuid = hard_smp_processor_id(); | 121 | int cpuid = hard_smp_processor_id(); |
124 | 122 | ||
125 | inherit_locked_prom_mappings(0); | ||
126 | |||
127 | __local_per_cpu_offset = __per_cpu_offset(cpuid); | 123 | __local_per_cpu_offset = __per_cpu_offset(cpuid); |
128 | 124 | ||
129 | __flush_tlb_all(); | 125 | __flush_tlb_all(); |
diff --git a/arch/sparc64/kernel/tsb.S b/arch/sparc64/kernel/tsb.S index c1532292a625..c4e7740d5e82 100644 --- a/arch/sparc64/kernel/tsb.S +++ b/arch/sparc64/kernel/tsb.S | |||
@@ -178,13 +178,6 @@ __tsb_context_switch: | |||
178 | brz %o2, 9f | 178 | brz %o2, 9f |
179 | nop | 179 | nop |
180 | 180 | ||
181 | /* We use entry 61 for this locked entry. This is the spitfire | ||
182 | * TLB entry number, and luckily cheetah masks the value with | ||
183 | * 15 ending us up with entry 13 which is what we want in that | ||
184 | * case too. | ||
185 | * | ||
186 | * XXX Interactions with prom_world()... | ||
187 | */ | ||
188 | sethi %hi(sparc64_highest_unlocked_tlb_ent), %o4 | 181 | sethi %hi(sparc64_highest_unlocked_tlb_ent), %o4 |
189 | mov TLB_TAG_ACCESS, %g1 | 182 | mov TLB_TAG_ACCESS, %g1 |
190 | lduw [%o4 + %lo(sparc64_highest_unlocked_tlb_ent)], %g2 | 183 | lduw [%o4 + %lo(sparc64_highest_unlocked_tlb_ent)], %g2 |
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 1e8a5a33639d..f4d22ccb4cf0 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c | |||
@@ -555,294 +555,12 @@ static void __init inherit_prom_mappings(void) | |||
555 | prom_printf("done.\n"); | 555 | prom_printf("done.\n"); |
556 | } | 556 | } |
557 | 557 | ||
558 | static int prom_ditlb_set; | ||
559 | struct prom_tlb_entry { | ||
560 | int tlb_ent; | ||
561 | unsigned long tlb_tag; | ||
562 | unsigned long tlb_data; | ||
563 | }; | ||
564 | struct prom_tlb_entry prom_itlb[16], prom_dtlb[16]; | ||
565 | |||
566 | void prom_world(int enter) | 558 | void prom_world(int enter) |
567 | { | 559 | { |
568 | unsigned long pstate; | ||
569 | int i; | ||
570 | |||
571 | if (!enter) | 560 | if (!enter) |
572 | set_fs((mm_segment_t) { get_thread_current_ds() }); | 561 | set_fs((mm_segment_t) { get_thread_current_ds() }); |
573 | 562 | ||
574 | if (!prom_ditlb_set) | 563 | __asm__ __volatile__("flushw"); |
575 | return; | ||
576 | |||
577 | /* Make sure the following runs atomically. */ | ||
578 | __asm__ __volatile__("flushw\n\t" | ||
579 | "rdpr %%pstate, %0\n\t" | ||
580 | "wrpr %0, %1, %%pstate" | ||
581 | : "=r" (pstate) | ||
582 | : "i" (PSTATE_IE)); | ||
583 | |||
584 | if (enter) { | ||
585 | /* Install PROM world. */ | ||
586 | for (i = 0; i < 16; i++) { | ||
587 | if (prom_dtlb[i].tlb_ent != -1) { | ||
588 | __asm__ __volatile__("stxa %0, [%1] %2\n\t" | ||
589 | "membar #Sync" | ||
590 | : : "r" (prom_dtlb[i].tlb_tag), "r" (TLB_TAG_ACCESS), | ||
591 | "i" (ASI_DMMU)); | ||
592 | if (tlb_type == spitfire) | ||
593 | spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent, | ||
594 | prom_dtlb[i].tlb_data); | ||
595 | else if (tlb_type == cheetah || tlb_type == cheetah_plus) | ||
596 | cheetah_put_ldtlb_data(prom_dtlb[i].tlb_ent, | ||
597 | prom_dtlb[i].tlb_data); | ||
598 | } | ||
599 | if (prom_itlb[i].tlb_ent != -1) { | ||
600 | __asm__ __volatile__("stxa %0, [%1] %2\n\t" | ||
601 | "membar #Sync" | ||
602 | : : "r" (prom_itlb[i].tlb_tag), | ||
603 | "r" (TLB_TAG_ACCESS), | ||
604 | "i" (ASI_IMMU)); | ||
605 | if (tlb_type == spitfire) | ||
606 | spitfire_put_itlb_data(prom_itlb[i].tlb_ent, | ||
607 | prom_itlb[i].tlb_data); | ||
608 | else if (tlb_type == cheetah || tlb_type == cheetah_plus) | ||
609 | cheetah_put_litlb_data(prom_itlb[i].tlb_ent, | ||
610 | prom_itlb[i].tlb_data); | ||
611 | } | ||
612 | } | ||
613 | } else { | ||
614 | for (i = 0; i < 16; i++) { | ||
615 | if (prom_dtlb[i].tlb_ent != -1) { | ||
616 | __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" | ||
617 | "membar #Sync" | ||
618 | : : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU)); | ||
619 | if (tlb_type == spitfire) | ||
620 | spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent, 0x0UL); | ||
621 | else | ||
622 | cheetah_put_ldtlb_data(prom_dtlb[i].tlb_ent, 0x0UL); | ||
623 | } | ||
624 | if (prom_itlb[i].tlb_ent != -1) { | ||
625 | __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" | ||
626 | "membar #Sync" | ||
627 | : : "r" (TLB_TAG_ACCESS), | ||
628 | "i" (ASI_IMMU)); | ||
629 | if (tlb_type == spitfire) | ||
630 | spitfire_put_itlb_data(prom_itlb[i].tlb_ent, 0x0UL); | ||
631 | else | ||
632 | cheetah_put_litlb_data(prom_itlb[i].tlb_ent, 0x0UL); | ||
633 | } | ||
634 | } | ||
635 | } | ||
636 | __asm__ __volatile__("wrpr %0, 0, %%pstate" | ||
637 | : : "r" (pstate)); | ||
638 | } | ||
639 | |||
640 | void inherit_locked_prom_mappings(int save_p) | ||
641 | { | ||
642 | int i; | ||
643 | int dtlb_seen = 0; | ||
644 | int itlb_seen = 0; | ||
645 | |||
646 | /* Fucking losing PROM has more mappings in the TLB, but | ||
647 | * it (conveniently) fails to mention any of these in the | ||
648 | * translations property. The only ones that matter are | ||
649 | * the locked PROM tlb entries, so we impose the following | ||
650 | * irrecovable rule on the PROM, it is allowed 8 locked | ||
651 | * entries in the ITLB and 8 in the DTLB. | ||
652 | * | ||
653 | * Supposedly the upper 16GB of the address space is | ||
654 | * reserved for OBP, BUT I WISH THIS WAS DOCUMENTED | ||
655 | * SOMEWHERE!!!!!!!!!!!!!!!!! Furthermore the entire interface | ||
656 | * used between the client program and the firmware on sun5 | ||
657 | * systems to coordinate mmu mappings is also COMPLETELY | ||
658 | * UNDOCUMENTED!!!!!! Thanks S(t)un! | ||
659 | */ | ||
660 | if (save_p) { | ||
661 | for (i = 0; i < 16; i++) { | ||
662 | prom_itlb[i].tlb_ent = -1; | ||
663 | prom_dtlb[i].tlb_ent = -1; | ||
664 | } | ||
665 | } | ||
666 | if (tlb_type == spitfire) { | ||
667 | int high = sparc64_highest_unlocked_tlb_ent; | ||
668 | for (i = 0; i <= high; i++) { | ||
669 | unsigned long data; | ||
670 | |||
671 | /* Spitfire Errata #32 workaround */ | ||
672 | /* NOTE: Always runs on spitfire, so no cheetah+ | ||
673 | * page size encodings. | ||
674 | */ | ||
675 | __asm__ __volatile__("stxa %0, [%1] %2\n\t" | ||
676 | "flush %%g6" | ||
677 | : /* No outputs */ | ||
678 | : "r" (0), | ||
679 | "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); | ||
680 | |||
681 | data = spitfire_get_dtlb_data(i); | ||
682 | if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) { | ||
683 | unsigned long tag; | ||
684 | |||
685 | /* Spitfire Errata #32 workaround */ | ||
686 | /* NOTE: Always runs on spitfire, so no | ||
687 | * cheetah+ page size encodings. | ||
688 | */ | ||
689 | __asm__ __volatile__("stxa %0, [%1] %2\n\t" | ||
690 | "flush %%g6" | ||
691 | : /* No outputs */ | ||
692 | : "r" (0), | ||
693 | "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); | ||
694 | |||
695 | tag = spitfire_get_dtlb_tag(i); | ||
696 | if (save_p) { | ||
697 | prom_dtlb[dtlb_seen].tlb_ent = i; | ||
698 | prom_dtlb[dtlb_seen].tlb_tag = tag; | ||
699 | prom_dtlb[dtlb_seen].tlb_data = data; | ||
700 | } | ||
701 | __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" | ||
702 | "membar #Sync" | ||
703 | : : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU)); | ||
704 | spitfire_put_dtlb_data(i, 0x0UL); | ||
705 | |||
706 | dtlb_seen++; | ||
707 | if (dtlb_seen > 15) | ||
708 | break; | ||
709 | } | ||
710 | } | ||
711 | |||
712 | for (i = 0; i < high; i++) { | ||
713 | unsigned long data; | ||
714 | |||
715 | /* Spitfire Errata #32 workaround */ | ||
716 | /* NOTE: Always runs on spitfire, so no | ||
717 | * cheetah+ page size encodings. | ||
718 | */ | ||
719 | __asm__ __volatile__("stxa %0, [%1] %2\n\t" | ||
720 | "flush %%g6" | ||
721 | : /* No outputs */ | ||
722 | : "r" (0), | ||
723 | "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); | ||
724 | |||
725 | data = spitfire_get_itlb_data(i); | ||
726 | if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) { | ||
727 | unsigned long tag; | ||
728 | |||
729 | /* Spitfire Errata #32 workaround */ | ||
730 | /* NOTE: Always runs on spitfire, so no | ||
731 | * cheetah+ page size encodings. | ||
732 | */ | ||
733 | __asm__ __volatile__("stxa %0, [%1] %2\n\t" | ||
734 | "flush %%g6" | ||
735 | : /* No outputs */ | ||
736 | : "r" (0), | ||
737 | "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); | ||
738 | |||
739 | tag = spitfire_get_itlb_tag(i); | ||
740 | if (save_p) { | ||
741 | prom_itlb[itlb_seen].tlb_ent = i; | ||
742 | prom_itlb[itlb_seen].tlb_tag = tag; | ||
743 | prom_itlb[itlb_seen].tlb_data = data; | ||
744 | } | ||
745 | __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" | ||
746 | "membar #Sync" | ||
747 | : : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU)); | ||
748 | spitfire_put_itlb_data(i, 0x0UL); | ||
749 | |||
750 | itlb_seen++; | ||
751 | if (itlb_seen > 15) | ||
752 | break; | ||
753 | } | ||
754 | } | ||
755 | } else if (tlb_type == cheetah || tlb_type == cheetah_plus) { | ||
756 | int high = sparc64_highest_unlocked_tlb_ent; | ||
757 | |||
758 | for (i = 0; i <= high; i++) { | ||
759 | unsigned long data; | ||
760 | |||
761 | data = cheetah_get_ldtlb_data(i); | ||
762 | if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) { | ||
763 | unsigned long tag; | ||
764 | |||
765 | tag = cheetah_get_ldtlb_tag(i); | ||
766 | if (save_p) { | ||
767 | prom_dtlb[dtlb_seen].tlb_ent = i; | ||
768 | prom_dtlb[dtlb_seen].tlb_tag = tag; | ||
769 | prom_dtlb[dtlb_seen].tlb_data = data; | ||
770 | } | ||
771 | __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" | ||
772 | "membar #Sync" | ||
773 | : : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU)); | ||
774 | cheetah_put_ldtlb_data(i, 0x0UL); | ||
775 | |||
776 | dtlb_seen++; | ||
777 | if (dtlb_seen > 15) | ||
778 | break; | ||
779 | } | ||
780 | } | ||
781 | |||
782 | for (i = 0; i < high; i++) { | ||
783 | unsigned long data; | ||
784 | |||
785 | data = cheetah_get_litlb_data(i); | ||
786 | if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) { | ||
787 | unsigned long tag; | ||
788 | |||
789 | tag = cheetah_get_litlb_tag(i); | ||
790 | if (save_p) { | ||
791 | prom_itlb[itlb_seen].tlb_ent = i; | ||
792 | prom_itlb[itlb_seen].tlb_tag = tag; | ||
793 | prom_itlb[itlb_seen].tlb_data = data; | ||
794 | } | ||
795 | __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" | ||
796 | "membar #Sync" | ||
797 | : : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU)); | ||
798 | cheetah_put_litlb_data(i, 0x0UL); | ||
799 | |||
800 | itlb_seen++; | ||
801 | if (itlb_seen > 15) | ||
802 | break; | ||
803 | } | ||
804 | } | ||
805 | } else { | ||
806 | /* Implement me :-) */ | ||
807 | BUG(); | ||
808 | } | ||
809 | if (save_p) | ||
810 | prom_ditlb_set = 1; | ||
811 | } | ||
812 | |||
813 | /* Give PROM back his world, done during reboots... */ | ||
814 | void prom_reload_locked(void) | ||
815 | { | ||
816 | int i; | ||
817 | |||
818 | for (i = 0; i < 16; i++) { | ||
819 | if (prom_dtlb[i].tlb_ent != -1) { | ||
820 | __asm__ __volatile__("stxa %0, [%1] %2\n\t" | ||
821 | "membar #Sync" | ||
822 | : : "r" (prom_dtlb[i].tlb_tag), "r" (TLB_TAG_ACCESS), | ||
823 | "i" (ASI_DMMU)); | ||
824 | if (tlb_type == spitfire) | ||
825 | spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent, | ||
826 | prom_dtlb[i].tlb_data); | ||
827 | else if (tlb_type == cheetah || tlb_type == cheetah_plus) | ||
828 | cheetah_put_ldtlb_data(prom_dtlb[i].tlb_ent, | ||
829 | prom_dtlb[i].tlb_data); | ||
830 | } | ||
831 | |||
832 | if (prom_itlb[i].tlb_ent != -1) { | ||
833 | __asm__ __volatile__("stxa %0, [%1] %2\n\t" | ||
834 | "membar #Sync" | ||
835 | : : "r" (prom_itlb[i].tlb_tag), | ||
836 | "r" (TLB_TAG_ACCESS), | ||
837 | "i" (ASI_IMMU)); | ||
838 | if (tlb_type == spitfire) | ||
839 | spitfire_put_itlb_data(prom_itlb[i].tlb_ent, | ||
840 | prom_itlb[i].tlb_data); | ||
841 | else | ||
842 | cheetah_put_litlb_data(prom_itlb[i].tlb_ent, | ||
843 | prom_itlb[i].tlb_data); | ||
844 | } | ||
845 | } | ||
846 | } | 564 | } |
847 | 565 | ||
848 | #ifdef DCACHE_ALIASING_POSSIBLE | 566 | #ifdef DCACHE_ALIASING_POSSIBLE |
@@ -1066,6 +784,15 @@ void sparc_ultra_dump_dtlb(void) | |||
1066 | } | 784 | } |
1067 | } | 785 | } |
1068 | 786 | ||
787 | static inline void spitfire_errata32(void) | ||
788 | { | ||
789 | __asm__ __volatile__("stxa %0, [%1] %2\n\t" | ||
790 | "flush %%g6" | ||
791 | : /* No outputs */ | ||
792 | : "r" (0), | ||
793 | "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); | ||
794 | } | ||
795 | |||
1069 | extern unsigned long cmdline_memory_size; | 796 | extern unsigned long cmdline_memory_size; |
1070 | 797 | ||
1071 | unsigned long __init bootmem_init(unsigned long *pages_avail) | 798 | unsigned long __init bootmem_init(unsigned long *pages_avail) |
@@ -1375,8 +1102,6 @@ void __init paging_init(void) | |||
1375 | setup_tba(this_is_starfire); | 1102 | setup_tba(this_is_starfire); |
1376 | } | 1103 | } |
1377 | 1104 | ||
1378 | inherit_locked_prom_mappings(1); | ||
1379 | |||
1380 | __flush_tlb_all(); | 1105 | __flush_tlb_all(); |
1381 | 1106 | ||
1382 | /* Setup bootmem... */ | 1107 | /* Setup bootmem... */ |