aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/tlbex.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/mm/tlbex.c')
-rw-r--r--arch/mips/mm/tlbex.c283
1 files changed, 245 insertions, 38 deletions
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 0615b62efd6d..9a17bf8395df 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -6,8 +6,9 @@
6 * Synthesize TLB refill handlers at runtime. 6 * Synthesize TLB refill handlers at runtime.
7 * 7 *
8 * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer 8 * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer
9 * Copyright (C) 2005, 2007 Maciej W. Rozycki 9 * Copyright (C) 2005, 2007, 2008, 2009 Maciej W. Rozycki
10 * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) 10 * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
11 * Copyright (C) 2008, 2009 Cavium Networks, Inc.
11 * 12 *
12 * ... and the days got worse and worse and now you see 13 * ... and the days got worse and worse and now you see
13 * I've gone completly out of my mind. 14 * I've gone completly out of my mind.
@@ -19,8 +20,10 @@
19 * (Condolences to Napoleon XIV) 20 * (Condolences to Napoleon XIV)
20 */ 21 */
21 22
23#include <linux/bug.h>
22#include <linux/kernel.h> 24#include <linux/kernel.h>
23#include <linux/types.h> 25#include <linux/types.h>
26#include <linux/smp.h>
24#include <linux/string.h> 27#include <linux/string.h>
25#include <linux/init.h> 28#include <linux/init.h>
26 29
@@ -82,6 +85,9 @@ enum label_id {
82 label_nopage_tlbm, 85 label_nopage_tlbm,
83 label_smp_pgtable_change, 86 label_smp_pgtable_change,
84 label_r3000_write_probe_fail, 87 label_r3000_write_probe_fail,
88#ifdef CONFIG_HUGETLB_PAGE
89 label_tlb_huge_update,
90#endif
85}; 91};
86 92
87UASM_L_LA(_second_part) 93UASM_L_LA(_second_part)
@@ -98,6 +104,9 @@ UASM_L_LA(_nopage_tlbs)
98UASM_L_LA(_nopage_tlbm) 104UASM_L_LA(_nopage_tlbm)
99UASM_L_LA(_smp_pgtable_change) 105UASM_L_LA(_smp_pgtable_change)
100UASM_L_LA(_r3000_write_probe_fail) 106UASM_L_LA(_r3000_write_probe_fail)
107#ifdef CONFIG_HUGETLB_PAGE
108UASM_L_LA(_tlb_huge_update)
109#endif
101 110
102/* 111/*
103 * For debug purposes. 112 * For debug purposes.
@@ -125,6 +134,7 @@ static inline void dump_handler(const u32 *handler, int count)
125#define C0_TCBIND 2, 2 134#define C0_TCBIND 2, 2
126#define C0_ENTRYLO1 3, 0 135#define C0_ENTRYLO1 3, 0
127#define C0_CONTEXT 4, 0 136#define C0_CONTEXT 4, 0
137#define C0_PAGEMASK 5, 0
128#define C0_BADVADDR 8, 0 138#define C0_BADVADDR 8, 0
129#define C0_ENTRYHI 10, 0 139#define C0_ENTRYHI 10, 0
130#define C0_EPC 14, 0 140#define C0_EPC 14, 0
@@ -258,7 +268,8 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
258 } 268 }
259 269
260 if (cpu_has_mips_r2) { 270 if (cpu_has_mips_r2) {
261 uasm_i_ehb(p); 271 if (cpu_has_mips_r2_exec_hazard)
272 uasm_i_ehb(p);
262 tlbw(p); 273 tlbw(p);
263 return; 274 return;
264 } 275 }
@@ -310,7 +321,6 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
310 case CPU_BCM3302: 321 case CPU_BCM3302:
311 case CPU_BCM4710: 322 case CPU_BCM4710:
312 case CPU_LOONGSON2: 323 case CPU_LOONGSON2:
313 case CPU_CAVIUM_OCTEON:
314 case CPU_R5500: 324 case CPU_R5500:
315 if (m4kc_tlbp_war()) 325 if (m4kc_tlbp_war())
316 uasm_i_nop(p); 326 uasm_i_nop(p);
@@ -382,6 +392,98 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
382 } 392 }
383} 393}
384 394
395#ifdef CONFIG_HUGETLB_PAGE
396static __cpuinit void build_huge_tlb_write_entry(u32 **p,
397 struct uasm_label **l,
398 struct uasm_reloc **r,
399 unsigned int tmp,
400 enum tlb_write_entry wmode)
401{
402 /* Set huge page tlb entry size */
403 uasm_i_lui(p, tmp, PM_HUGE_MASK >> 16);
404 uasm_i_ori(p, tmp, tmp, PM_HUGE_MASK & 0xffff);
405 uasm_i_mtc0(p, tmp, C0_PAGEMASK);
406
407 build_tlb_write_entry(p, l, r, wmode);
408
409 /* Reset default page size */
410 if (PM_DEFAULT_MASK >> 16) {
411 uasm_i_lui(p, tmp, PM_DEFAULT_MASK >> 16);
412 uasm_i_ori(p, tmp, tmp, PM_DEFAULT_MASK & 0xffff);
413 uasm_il_b(p, r, label_leave);
414 uasm_i_mtc0(p, tmp, C0_PAGEMASK);
415 } else if (PM_DEFAULT_MASK) {
416 uasm_i_ori(p, tmp, 0, PM_DEFAULT_MASK);
417 uasm_il_b(p, r, label_leave);
418 uasm_i_mtc0(p, tmp, C0_PAGEMASK);
419 } else {
420 uasm_il_b(p, r, label_leave);
421 uasm_i_mtc0(p, 0, C0_PAGEMASK);
422 }
423}
424
425/*
426 * Check if Huge PTE is present, if so then jump to LABEL.
427 */
428static void __cpuinit
429build_is_huge_pte(u32 **p, struct uasm_reloc **r, unsigned int tmp,
430 unsigned int pmd, int lid)
431{
432 UASM_i_LW(p, tmp, 0, pmd);
433 uasm_i_andi(p, tmp, tmp, _PAGE_HUGE);
434 uasm_il_bnez(p, r, tmp, lid);
435}
436
437static __cpuinit void build_huge_update_entries(u32 **p,
438 unsigned int pte,
439 unsigned int tmp)
440{
441 int small_sequence;
442
443 /*
444 * A huge PTE describes an area the size of the
445 * configured huge page size. This is twice the
446 * of the large TLB entry size we intend to use.
447 * A TLB entry half the size of the configured
448 * huge page size is configured into entrylo0
449 * and entrylo1 to cover the contiguous huge PTE
450 * address space.
451 */
452 small_sequence = (HPAGE_SIZE >> 7) < 0x10000;
453
454 /* We can clobber tmp. It isn't used after this.*/
455 if (!small_sequence)
456 uasm_i_lui(p, tmp, HPAGE_SIZE >> (7 + 16));
457
458 UASM_i_SRL(p, pte, pte, 6); /* convert to entrylo */
459 uasm_i_mtc0(p, pte, C0_ENTRYLO0); /* load it */
460 /* convert to entrylo1 */
461 if (small_sequence)
462 UASM_i_ADDIU(p, pte, pte, HPAGE_SIZE >> 7);
463 else
464 UASM_i_ADDU(p, pte, pte, tmp);
465
466 uasm_i_mtc0(p, pte, C0_ENTRYLO1); /* load it */
467}
468
469static __cpuinit void build_huge_handler_tail(u32 **p,
470 struct uasm_reloc **r,
471 struct uasm_label **l,
472 unsigned int pte,
473 unsigned int ptr)
474{
475#ifdef CONFIG_SMP
476 UASM_i_SC(p, pte, 0, ptr);
477 uasm_il_beqz(p, r, pte, label_tlb_huge_update);
478 UASM_i_LW(p, pte, 0, ptr); /* Needed because SC killed our PTE */
479#else
480 UASM_i_SW(p, pte, 0, ptr);
481#endif
482 build_huge_update_entries(p, pte, ptr);
483 build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed);
484}
485#endif /* CONFIG_HUGETLB_PAGE */
486
385#ifdef CONFIG_64BIT 487#ifdef CONFIG_64BIT
386/* 488/*
387 * TMP and PTR are scratch. 489 * TMP and PTR are scratch.
@@ -649,6 +751,14 @@ static void __cpuinit build_update_entries(u32 **p, unsigned int tmp,
649#endif 751#endif
650} 752}
651 753
754/*
755 * For a 64-bit kernel, we are using the 64-bit XTLB refill exception
756 * because EXL == 0. If we wrap, we can also use the 32 instruction
757 * slots before the XTLB refill exception handler which belong to the
758 * unused TLB refill exception.
759 */
760#define MIPS64_REFILL_INSNS 32
761
652static void __cpuinit build_r4000_tlb_refill_handler(void) 762static void __cpuinit build_r4000_tlb_refill_handler(void)
653{ 763{
654 u32 *p = tlb_handler; 764 u32 *p = tlb_handler;
@@ -680,12 +790,23 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
680 build_get_pgde32(&p, K0, K1); /* get pgd in K1 */ 790 build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
681#endif 791#endif
682 792
793#ifdef CONFIG_HUGETLB_PAGE
794 build_is_huge_pte(&p, &r, K0, K1, label_tlb_huge_update);
795#endif
796
683 build_get_ptep(&p, K0, K1); 797 build_get_ptep(&p, K0, K1);
684 build_update_entries(&p, K0, K1); 798 build_update_entries(&p, K0, K1);
685 build_tlb_write_entry(&p, &l, &r, tlb_random); 799 build_tlb_write_entry(&p, &l, &r, tlb_random);
686 uasm_l_leave(&l, p); 800 uasm_l_leave(&l, p);
687 uasm_i_eret(&p); /* return from trap */ 801 uasm_i_eret(&p); /* return from trap */
688 802
803#ifdef CONFIG_HUGETLB_PAGE
804 uasm_l_tlb_huge_update(&l, p);
805 UASM_i_LW(&p, K0, 0, K1);
806 build_huge_update_entries(&p, K0, K1);
807 build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random);
808#endif
809
689#ifdef CONFIG_64BIT 810#ifdef CONFIG_64BIT
690 build_get_pgd_vmalloc64(&p, &l, &r, K0, K1); 811 build_get_pgd_vmalloc64(&p, &l, &r, K0, K1);
691#endif 812#endif
@@ -702,9 +823,10 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
702 if ((p - tlb_handler) > 64) 823 if ((p - tlb_handler) > 64)
703 panic("TLB refill handler space exceeded"); 824 panic("TLB refill handler space exceeded");
704#else 825#else
705 if (((p - tlb_handler) > 63) 826 if (((p - tlb_handler) > (MIPS64_REFILL_INSNS * 2) - 1)
706 || (((p - tlb_handler) > 61) 827 || (((p - tlb_handler) > (MIPS64_REFILL_INSNS * 2) - 3)
707 && uasm_insn_has_bdelay(relocs, tlb_handler + 29))) 828 && uasm_insn_has_bdelay(relocs,
829 tlb_handler + MIPS64_REFILL_INSNS - 3)))
708 panic("TLB refill handler space exceeded"); 830 panic("TLB refill handler space exceeded");
709#endif 831#endif
710 832
@@ -717,39 +839,74 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
717 uasm_copy_handler(relocs, labels, tlb_handler, p, f); 839 uasm_copy_handler(relocs, labels, tlb_handler, p, f);
718 final_len = p - tlb_handler; 840 final_len = p - tlb_handler;
719#else /* CONFIG_64BIT */ 841#else /* CONFIG_64BIT */
720 f = final_handler + 32; 842 f = final_handler + MIPS64_REFILL_INSNS;
721 if ((p - tlb_handler) <= 32) { 843 if ((p - tlb_handler) <= MIPS64_REFILL_INSNS) {
722 /* Just copy the handler. */ 844 /* Just copy the handler. */
723 uasm_copy_handler(relocs, labels, tlb_handler, p, f); 845 uasm_copy_handler(relocs, labels, tlb_handler, p, f);
724 final_len = p - tlb_handler; 846 final_len = p - tlb_handler;
725 } else { 847 } else {
726 u32 *split = tlb_handler + 30; 848#if defined(CONFIG_HUGETLB_PAGE)
849 const enum label_id ls = label_tlb_huge_update;
850#elif defined(MODULE_START)
851 const enum label_id ls = label_module_alloc;
852#else
853 const enum label_id ls = label_vmalloc;
854#endif
855 u32 *split;
856 int ov = 0;
857 int i;
858
859 for (i = 0; i < ARRAY_SIZE(labels) && labels[i].lab != ls; i++)
860 ;
861 BUG_ON(i == ARRAY_SIZE(labels));
862 split = labels[i].addr;
727 863
728 /* 864 /*
729 * Find the split point. 865 * See if we have overflown one way or the other.
730 */ 866 */
731 if (uasm_insn_has_bdelay(relocs, split - 1)) 867 if (split > tlb_handler + MIPS64_REFILL_INSNS ||
732 split--; 868 split < p - MIPS64_REFILL_INSNS)
733 869 ov = 1;
870
871 if (ov) {
872 /*
873 * Split two instructions before the end. One
874 * for the branch and one for the instruction
875 * in the delay slot.
876 */
877 split = tlb_handler + MIPS64_REFILL_INSNS - 2;
878
879 /*
880 * If the branch would fall in a delay slot,
881 * we must back up an additional instruction
882 * so that it is no longer in a delay slot.
883 */
884 if (uasm_insn_has_bdelay(relocs, split - 1))
885 split--;
886 }
734 /* Copy first part of the handler. */ 887 /* Copy first part of the handler. */
735 uasm_copy_handler(relocs, labels, tlb_handler, split, f); 888 uasm_copy_handler(relocs, labels, tlb_handler, split, f);
736 f += split - tlb_handler; 889 f += split - tlb_handler;
737 890
738 /* Insert branch. */ 891 if (ov) {
739 uasm_l_split(&l, final_handler); 892 /* Insert branch. */
740 uasm_il_b(&f, &r, label_split); 893 uasm_l_split(&l, final_handler);
741 if (uasm_insn_has_bdelay(relocs, split)) 894 uasm_il_b(&f, &r, label_split);
742 uasm_i_nop(&f); 895 if (uasm_insn_has_bdelay(relocs, split))
743 else { 896 uasm_i_nop(&f);
744 uasm_copy_handler(relocs, labels, split, split + 1, f); 897 else {
745 uasm_move_labels(labels, f, f + 1, -1); 898 uasm_copy_handler(relocs, labels,
746 f++; 899 split, split + 1, f);
747 split++; 900 uasm_move_labels(labels, f, f + 1, -1);
901 f++;
902 split++;
903 }
748 } 904 }
749 905
750 /* Copy the rest of the handler. */ 906 /* Copy the rest of the handler. */
751 uasm_copy_handler(relocs, labels, split, p, final_handler); 907 uasm_copy_handler(relocs, labels, split, p, final_handler);
752 final_len = (f - (final_handler + 32)) + (p - split); 908 final_len = (f - (final_handler + MIPS64_REFILL_INSNS)) +
909 (p - split);
753 } 910 }
754#endif /* CONFIG_64BIT */ 911#endif /* CONFIG_64BIT */
755 912
@@ -782,7 +939,7 @@ u32 handle_tlbs[FASTPATH_SIZE] __cacheline_aligned;
782u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned; 939u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned;
783 940
784static void __cpuinit 941static void __cpuinit
785iPTE_LW(u32 **p, struct uasm_label **l, unsigned int pte, unsigned int ptr) 942iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr)
786{ 943{
787#ifdef CONFIG_SMP 944#ifdef CONFIG_SMP
788# ifdef CONFIG_64BIT_PHYS_ADDR 945# ifdef CONFIG_64BIT_PHYS_ADDR
@@ -862,13 +1019,13 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
862 * with it's original value. 1019 * with it's original value.
863 */ 1020 */
864static void __cpuinit 1021static void __cpuinit
865build_pte_present(u32 **p, struct uasm_label **l, struct uasm_reloc **r, 1022build_pte_present(u32 **p, struct uasm_reloc **r,
866 unsigned int pte, unsigned int ptr, enum label_id lid) 1023 unsigned int pte, unsigned int ptr, enum label_id lid)
867{ 1024{
868 uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ); 1025 uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
869 uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ); 1026 uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
870 uasm_il_bnez(p, r, pte, lid); 1027 uasm_il_bnez(p, r, pte, lid);
871 iPTE_LW(p, l, pte, ptr); 1028 iPTE_LW(p, pte, ptr);
872} 1029}
873 1030
874/* Make PTE valid, store result in PTR. */ 1031/* Make PTE valid, store result in PTR. */
@@ -886,13 +1043,13 @@ build_make_valid(u32 **p, struct uasm_reloc **r, unsigned int pte,
886 * restore PTE with value from PTR when done. 1043 * restore PTE with value from PTR when done.
887 */ 1044 */
888static void __cpuinit 1045static void __cpuinit
889build_pte_writable(u32 **p, struct uasm_label **l, struct uasm_reloc **r, 1046build_pte_writable(u32 **p, struct uasm_reloc **r,
890 unsigned int pte, unsigned int ptr, enum label_id lid) 1047 unsigned int pte, unsigned int ptr, enum label_id lid)
891{ 1048{
892 uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE); 1049 uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
893 uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE); 1050 uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
894 uasm_il_bnez(p, r, pte, lid); 1051 uasm_il_bnez(p, r, pte, lid);
895 iPTE_LW(p, l, pte, ptr); 1052 iPTE_LW(p, pte, ptr);
896} 1053}
897 1054
898/* Make PTE writable, update software status bits as well, then store 1055/* Make PTE writable, update software status bits as well, then store
@@ -913,12 +1070,12 @@ build_make_write(u32 **p, struct uasm_reloc **r, unsigned int pte,
913 * restore PTE with value from PTR when done. 1070 * restore PTE with value from PTR when done.
914 */ 1071 */
915static void __cpuinit 1072static void __cpuinit
916build_pte_modifiable(u32 **p, struct uasm_label **l, struct uasm_reloc **r, 1073build_pte_modifiable(u32 **p, struct uasm_reloc **r,
917 unsigned int pte, unsigned int ptr, enum label_id lid) 1074 unsigned int pte, unsigned int ptr, enum label_id lid)
918{ 1075{
919 uasm_i_andi(p, pte, pte, _PAGE_WRITE); 1076 uasm_i_andi(p, pte, pte, _PAGE_WRITE);
920 uasm_il_beqz(p, r, pte, lid); 1077 uasm_il_beqz(p, r, pte, lid);
921 iPTE_LW(p, l, pte, ptr); 1078 iPTE_LW(p, pte, ptr);
922} 1079}
923 1080
924/* 1081/*
@@ -994,7 +1151,7 @@ static void __cpuinit build_r3000_tlb_load_handler(void)
994 memset(relocs, 0, sizeof(relocs)); 1151 memset(relocs, 0, sizeof(relocs));
995 1152
996 build_r3000_tlbchange_handler_head(&p, K0, K1); 1153 build_r3000_tlbchange_handler_head(&p, K0, K1);
997 build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl); 1154 build_pte_present(&p, &r, K0, K1, label_nopage_tlbl);
998 uasm_i_nop(&p); /* load delay */ 1155 uasm_i_nop(&p); /* load delay */
999 build_make_valid(&p, &r, K0, K1); 1156 build_make_valid(&p, &r, K0, K1);
1000 build_r3000_tlb_reload_write(&p, &l, &r, K0, K1); 1157 build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
@@ -1024,7 +1181,7 @@ static void __cpuinit build_r3000_tlb_store_handler(void)
1024 memset(relocs, 0, sizeof(relocs)); 1181 memset(relocs, 0, sizeof(relocs));
1025 1182
1026 build_r3000_tlbchange_handler_head(&p, K0, K1); 1183 build_r3000_tlbchange_handler_head(&p, K0, K1);
1027 build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs); 1184 build_pte_writable(&p, &r, K0, K1, label_nopage_tlbs);
1028 uasm_i_nop(&p); /* load delay */ 1185 uasm_i_nop(&p); /* load delay */
1029 build_make_write(&p, &r, K0, K1); 1186 build_make_write(&p, &r, K0, K1);
1030 build_r3000_tlb_reload_write(&p, &l, &r, K0, K1); 1187 build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
@@ -1054,7 +1211,7 @@ static void __cpuinit build_r3000_tlb_modify_handler(void)
1054 memset(relocs, 0, sizeof(relocs)); 1211 memset(relocs, 0, sizeof(relocs));
1055 1212
1056 build_r3000_tlbchange_handler_head(&p, K0, K1); 1213 build_r3000_tlbchange_handler_head(&p, K0, K1);
1057 build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm); 1214 build_pte_modifiable(&p, &r, K0, K1, label_nopage_tlbm);
1058 uasm_i_nop(&p); /* load delay */ 1215 uasm_i_nop(&p); /* load delay */
1059 build_make_write(&p, &r, K0, K1); 1216 build_make_write(&p, &r, K0, K1);
1060 build_r3000_pte_reload_tlbwi(&p, K0, K1); 1217 build_r3000_pte_reload_tlbwi(&p, K0, K1);
@@ -1087,6 +1244,15 @@ build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l,
1087 build_get_pgde32(p, pte, ptr); /* get pgd in ptr */ 1244 build_get_pgde32(p, pte, ptr); /* get pgd in ptr */
1088#endif 1245#endif
1089 1246
1247#ifdef CONFIG_HUGETLB_PAGE
1248 /*
1249 * For huge tlb entries, pmd doesn't contain an address but
1250 * instead contains the tlb pte. Check the PAGE_HUGE bit and
1251 * see if we need to jump to huge tlb processing.
1252 */
1253 build_is_huge_pte(p, r, pte, ptr, label_tlb_huge_update);
1254#endif
1255
1090 UASM_i_MFC0(p, pte, C0_BADVADDR); 1256 UASM_i_MFC0(p, pte, C0_BADVADDR);
1091 UASM_i_LW(p, ptr, 0, ptr); 1257 UASM_i_LW(p, ptr, 0, ptr);
1092 UASM_i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2); 1258 UASM_i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2);
@@ -1096,7 +1262,7 @@ build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l,
1096#ifdef CONFIG_SMP 1262#ifdef CONFIG_SMP
1097 uasm_l_smp_pgtable_change(l, *p); 1263 uasm_l_smp_pgtable_change(l, *p);
1098#endif 1264#endif
1099 iPTE_LW(p, l, pte, ptr); /* get even pte */ 1265 iPTE_LW(p, pte, ptr); /* get even pte */
1100 if (!m4kc_tlbp_war()) 1266 if (!m4kc_tlbp_war())
1101 build_tlb_probe_entry(p); 1267 build_tlb_probe_entry(p);
1102} 1268}
@@ -1138,12 +1304,25 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
1138 } 1304 }
1139 1305
1140 build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); 1306 build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
1141 build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl); 1307 build_pte_present(&p, &r, K0, K1, label_nopage_tlbl);
1142 if (m4kc_tlbp_war()) 1308 if (m4kc_tlbp_war())
1143 build_tlb_probe_entry(&p); 1309 build_tlb_probe_entry(&p);
1144 build_make_valid(&p, &r, K0, K1); 1310 build_make_valid(&p, &r, K0, K1);
1145 build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); 1311 build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
1146 1312
1313#ifdef CONFIG_HUGETLB_PAGE
1314 /*
1315 * This is the entry point when build_r4000_tlbchange_handler_head
1316 * spots a huge page.
1317 */
1318 uasm_l_tlb_huge_update(&l, p);
1319 iPTE_LW(&p, K0, K1);
1320 build_pte_present(&p, &r, K0, K1, label_nopage_tlbl);
1321 build_tlb_probe_entry(&p);
1322 uasm_i_ori(&p, K0, K0, (_PAGE_ACCESSED | _PAGE_VALID));
1323 build_huge_handler_tail(&p, &r, &l, K0, K1);
1324#endif
1325
1147 uasm_l_nopage_tlbl(&l, p); 1326 uasm_l_nopage_tlbl(&l, p);
1148 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); 1327 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
1149 uasm_i_nop(&p); 1328 uasm_i_nop(&p);
@@ -1169,12 +1348,26 @@ static void __cpuinit build_r4000_tlb_store_handler(void)
1169 memset(relocs, 0, sizeof(relocs)); 1348 memset(relocs, 0, sizeof(relocs));
1170 1349
1171 build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); 1350 build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
1172 build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs); 1351 build_pte_writable(&p, &r, K0, K1, label_nopage_tlbs);
1173 if (m4kc_tlbp_war()) 1352 if (m4kc_tlbp_war())
1174 build_tlb_probe_entry(&p); 1353 build_tlb_probe_entry(&p);
1175 build_make_write(&p, &r, K0, K1); 1354 build_make_write(&p, &r, K0, K1);
1176 build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); 1355 build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
1177 1356
1357#ifdef CONFIG_HUGETLB_PAGE
1358 /*
1359 * This is the entry point when
1360 * build_r4000_tlbchange_handler_head spots a huge page.
1361 */
1362 uasm_l_tlb_huge_update(&l, p);
1363 iPTE_LW(&p, K0, K1);
1364 build_pte_writable(&p, &r, K0, K1, label_nopage_tlbs);
1365 build_tlb_probe_entry(&p);
1366 uasm_i_ori(&p, K0, K0,
1367 _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY);
1368 build_huge_handler_tail(&p, &r, &l, K0, K1);
1369#endif
1370
1178 uasm_l_nopage_tlbs(&l, p); 1371 uasm_l_nopage_tlbs(&l, p);
1179 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); 1372 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
1180 uasm_i_nop(&p); 1373 uasm_i_nop(&p);
@@ -1200,13 +1393,27 @@ static void __cpuinit build_r4000_tlb_modify_handler(void)
1200 memset(relocs, 0, sizeof(relocs)); 1393 memset(relocs, 0, sizeof(relocs));
1201 1394
1202 build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); 1395 build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
1203 build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm); 1396 build_pte_modifiable(&p, &r, K0, K1, label_nopage_tlbm);
1204 if (m4kc_tlbp_war()) 1397 if (m4kc_tlbp_war())
1205 build_tlb_probe_entry(&p); 1398 build_tlb_probe_entry(&p);
1206 /* Present and writable bits set, set accessed and dirty bits. */ 1399 /* Present and writable bits set, set accessed and dirty bits. */
1207 build_make_write(&p, &r, K0, K1); 1400 build_make_write(&p, &r, K0, K1);
1208 build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); 1401 build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
1209 1402
1403#ifdef CONFIG_HUGETLB_PAGE
1404 /*
1405 * This is the entry point when
1406 * build_r4000_tlbchange_handler_head spots a huge page.
1407 */
1408 uasm_l_tlb_huge_update(&l, p);
1409 iPTE_LW(&p, K0, K1);
1410 build_pte_modifiable(&p, &r, K0, K1, label_nopage_tlbm);
1411 build_tlb_probe_entry(&p);
1412 uasm_i_ori(&p, K0, K0,
1413 _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY);
1414 build_huge_handler_tail(&p, &r, &l, K0, K1);
1415#endif
1416
1210 uasm_l_nopage_tlbm(&l, p); 1417 uasm_l_nopage_tlbm(&l, p);
1211 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); 1418 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
1212 uasm_i_nop(&p); 1419 uasm_i_nop(&p);