aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2006-01-31 21:33:25 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:11:24 -0500
commit3487d1d4414fbfab5d98ec559e6f84f55520cb15 (patch)
treeb85ac7e9d8c07bd3c8a9d314d650b04cdf1ccc96 /arch/sparc64
parent6b6d017235acad3ee1681140795593723bb9b9df (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.c4
-rw-r--r--arch/sparc64/kernel/tsb.S7
-rw-r--r--arch/sparc64/mm/init.c295
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
117static volatile unsigned long callin_flag = 0; 117static volatile unsigned long callin_flag = 0;
118 118
119extern void inherit_locked_prom_mappings(int save_p);
120
121void __init smp_callin(void) 119void __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
558static int prom_ditlb_set;
559struct prom_tlb_entry {
560 int tlb_ent;
561 unsigned long tlb_tag;
562 unsigned long tlb_data;
563};
564struct prom_tlb_entry prom_itlb[16], prom_dtlb[16];
565
566void prom_world(int enter) 558void 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
640void 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... */
814void 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
787static 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
1069extern unsigned long cmdline_memory_size; 796extern unsigned long cmdline_memory_size;
1070 797
1071unsigned long __init bootmem_init(unsigned long *pages_avail) 798unsigned 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... */