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.c183
1 files changed, 113 insertions, 70 deletions
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index afeef93f81a7..9ab0f907a52c 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -305,6 +305,17 @@ static int check_for_high_segbits __cpuinitdata;
305 305
306static unsigned int kscratch_used_mask __cpuinitdata; 306static unsigned int kscratch_used_mask __cpuinitdata;
307 307
308static inline int __maybe_unused c0_kscratch(void)
309{
310 switch (current_cpu_type()) {
311 case CPU_XLP:
312 case CPU_XLR:
313 return 22;
314 default:
315 return 31;
316 }
317}
318
308static int __cpuinit allocate_kscratch(void) 319static int __cpuinit allocate_kscratch(void)
309{ 320{
310 int r; 321 int r;
@@ -334,9 +345,9 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p)
334 int smp_processor_id_sel; 345 int smp_processor_id_sel;
335 int smp_processor_id_shift; 346 int smp_processor_id_shift;
336 347
337 if (scratch_reg > 0) { 348 if (scratch_reg >= 0) {
338 /* Save in CPU local C0_KScratch? */ 349 /* Save in CPU local C0_KScratch? */
339 UASM_i_MTC0(p, 1, 31, scratch_reg); 350 UASM_i_MTC0(p, 1, c0_kscratch(), scratch_reg);
340 r.r1 = K0; 351 r.r1 = K0;
341 r.r2 = K1; 352 r.r2 = K1;
342 r.r3 = 1; 353 r.r3 = 1;
@@ -384,8 +395,8 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p)
384 395
385static void __cpuinit build_restore_work_registers(u32 **p) 396static void __cpuinit build_restore_work_registers(u32 **p)
386{ 397{
387 if (scratch_reg > 0) { 398 if (scratch_reg >= 0) {
388 UASM_i_MFC0(p, 1, 31, scratch_reg); 399 UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
389 return; 400 return;
390 } 401 }
391 /* K0 already points to save area, restore $1 and $2 */ 402 /* K0 already points to save area, restore $1 and $2 */
@@ -673,8 +684,8 @@ static __cpuinit void build_restore_pagemask(u32 **p,
673 uasm_i_mtc0(p, 0, C0_PAGEMASK); 684 uasm_i_mtc0(p, 0, C0_PAGEMASK);
674 uasm_il_b(p, r, lid); 685 uasm_il_b(p, r, lid);
675 } 686 }
676 if (scratch_reg > 0) 687 if (scratch_reg >= 0)
677 UASM_i_MFC0(p, 1, 31, scratch_reg); 688 UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
678 else 689 else
679 UASM_i_LW(p, 1, scratchpad_offset(0), 0); 690 UASM_i_LW(p, 1, scratchpad_offset(0), 0);
680 } else { 691 } else {
@@ -817,7 +828,7 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
817#ifdef CONFIG_MIPS_PGD_C0_CONTEXT 828#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
818 if (pgd_reg != -1) { 829 if (pgd_reg != -1) {
819 /* pgd is in pgd_reg */ 830 /* pgd is in pgd_reg */
820 UASM_i_MFC0(p, ptr, 31, pgd_reg); 831 UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg);
821 } else { 832 } else {
822 /* 833 /*
823 * &pgd << 11 stored in CONTEXT [23..63]. 834 * &pgd << 11 stored in CONTEXT [23..63].
@@ -929,8 +940,8 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
929 uasm_i_jr(p, ptr); 940 uasm_i_jr(p, ptr);
930 941
931 if (mode == refill_scratch) { 942 if (mode == refill_scratch) {
932 if (scratch_reg > 0) 943 if (scratch_reg >= 0)
933 UASM_i_MFC0(p, 1, 31, scratch_reg); 944 UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
934 else 945 else
935 UASM_i_LW(p, 1, scratchpad_offset(0), 0); 946 UASM_i_LW(p, 1, scratchpad_offset(0), 0);
936 } else { 947 } else {
@@ -961,7 +972,7 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
961 uasm_i_srl(p, ptr, ptr, 19); 972 uasm_i_srl(p, ptr, ptr, 19);
962#else 973#else
963 /* 974 /*
964 * smp_processor_id() << 3 is stored in CONTEXT. 975 * smp_processor_id() << 2 is stored in CONTEXT.
965 */ 976 */
966 uasm_i_mfc0(p, ptr, C0_CONTEXT); 977 uasm_i_mfc0(p, ptr, C0_CONTEXT);
967 UASM_i_LA_mostly(p, tmp, pgdc); 978 UASM_i_LA_mostly(p, tmp, pgdc);
@@ -1096,7 +1107,7 @@ struct mips_huge_tlb_info {
1096static struct mips_huge_tlb_info __cpuinit 1107static struct mips_huge_tlb_info __cpuinit
1097build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l, 1108build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
1098 struct uasm_reloc **r, unsigned int tmp, 1109 struct uasm_reloc **r, unsigned int tmp,
1099 unsigned int ptr, int c0_scratch) 1110 unsigned int ptr, int c0_scratch_reg)
1100{ 1111{
1101 struct mips_huge_tlb_info rv; 1112 struct mips_huge_tlb_info rv;
1102 unsigned int even, odd; 1113 unsigned int even, odd;
@@ -1110,12 +1121,12 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
1110 UASM_i_MFC0(p, tmp, C0_BADVADDR); 1121 UASM_i_MFC0(p, tmp, C0_BADVADDR);
1111 1122
1112 if (pgd_reg != -1) 1123 if (pgd_reg != -1)
1113 UASM_i_MFC0(p, ptr, 31, pgd_reg); 1124 UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg);
1114 else 1125 else
1115 UASM_i_MFC0(p, ptr, C0_CONTEXT); 1126 UASM_i_MFC0(p, ptr, C0_CONTEXT);
1116 1127
1117 if (c0_scratch >= 0) 1128 if (c0_scratch_reg >= 0)
1118 UASM_i_MTC0(p, scratch, 31, c0_scratch); 1129 UASM_i_MTC0(p, scratch, c0_kscratch(), c0_scratch_reg);
1119 else 1130 else
1120 UASM_i_SW(p, scratch, scratchpad_offset(0), 0); 1131 UASM_i_SW(p, scratch, scratchpad_offset(0), 0);
1121 1132
@@ -1130,14 +1141,14 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
1130 } 1141 }
1131 } else { 1142 } else {
1132 if (pgd_reg != -1) 1143 if (pgd_reg != -1)
1133 UASM_i_MFC0(p, ptr, 31, pgd_reg); 1144 UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg);
1134 else 1145 else
1135 UASM_i_MFC0(p, ptr, C0_CONTEXT); 1146 UASM_i_MFC0(p, ptr, C0_CONTEXT);
1136 1147
1137 UASM_i_MFC0(p, tmp, C0_BADVADDR); 1148 UASM_i_MFC0(p, tmp, C0_BADVADDR);
1138 1149
1139 if (c0_scratch >= 0) 1150 if (c0_scratch_reg >= 0)
1140 UASM_i_MTC0(p, scratch, 31, c0_scratch); 1151 UASM_i_MTC0(p, scratch, c0_kscratch(), c0_scratch_reg);
1141 else 1152 else
1142 UASM_i_SW(p, scratch, scratchpad_offset(0), 0); 1153 UASM_i_SW(p, scratch, scratchpad_offset(0), 0);
1143 1154
@@ -1242,8 +1253,8 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
1242 } 1253 }
1243 UASM_i_MTC0(p, odd, C0_ENTRYLO1); /* load it */ 1254 UASM_i_MTC0(p, odd, C0_ENTRYLO1); /* load it */
1244 1255
1245 if (c0_scratch >= 0) { 1256 if (c0_scratch_reg >= 0) {
1246 UASM_i_MFC0(p, scratch, 31, c0_scratch); 1257 UASM_i_MFC0(p, scratch, c0_kscratch(), c0_scratch_reg);
1247 build_tlb_write_entry(p, l, r, tlb_random); 1258 build_tlb_write_entry(p, l, r, tlb_random);
1248 uasm_l_leave(l, *p); 1259 uasm_l_leave(l, *p);
1249 rv.restore_scratch = 1; 1260 rv.restore_scratch = 1;
@@ -1286,7 +1297,7 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
1286 memset(relocs, 0, sizeof(relocs)); 1297 memset(relocs, 0, sizeof(relocs));
1287 memset(final_handler, 0, sizeof(final_handler)); 1298 memset(final_handler, 0, sizeof(final_handler));
1288 1299
1289 if ((scratch_reg > 0 || scratchpad_available()) && use_bbit_insns()) { 1300 if ((scratch_reg >= 0 || scratchpad_available()) && use_bbit_insns()) {
1290 htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1, 1301 htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1,
1291 scratch_reg); 1302 scratch_reg);
1292 vmalloc_mode = refill_scratch; 1303 vmalloc_mode = refill_scratch;
@@ -1444,27 +1455,25 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
1444 dump_handler("r4000_tlb_refill", (u32 *)ebase, 64); 1455 dump_handler("r4000_tlb_refill", (u32 *)ebase, 64);
1445} 1456}
1446 1457
1447/* 1458extern u32 handle_tlbl[], handle_tlbl_end[];
1448 * 128 instructions for the fastpath handler is generous and should 1459extern u32 handle_tlbs[], handle_tlbs_end[];
1449 * never be exceeded. 1460extern u32 handle_tlbm[], handle_tlbm_end[];
1450 */
1451#define FASTPATH_SIZE 128
1452 1461
1453u32 handle_tlbl[FASTPATH_SIZE] __cacheline_aligned;
1454u32 handle_tlbs[FASTPATH_SIZE] __cacheline_aligned;
1455u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned;
1456#ifdef CONFIG_MIPS_PGD_C0_CONTEXT 1462#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
1457u32 tlbmiss_handler_setup_pgd_array[16] __cacheline_aligned; 1463extern u32 tlbmiss_handler_setup_pgd[], tlbmiss_handler_setup_pgd_end[];
1458 1464
1459static void __cpuinit build_r4000_setup_pgd(void) 1465static void __cpuinit build_r4000_setup_pgd(void)
1460{ 1466{
1461 const int a0 = 4; 1467 const int a0 = 4;
1462 const int a1 = 5; 1468 const int a1 = 5;
1463 u32 *p = tlbmiss_handler_setup_pgd_array; 1469 u32 *p = tlbmiss_handler_setup_pgd_array;
1470 const int tlbmiss_handler_setup_pgd_size =
1471 tlbmiss_handler_setup_pgd_end - tlbmiss_handler_setup_pgd;
1464 struct uasm_label *l = labels; 1472 struct uasm_label *l = labels;
1465 struct uasm_reloc *r = relocs; 1473 struct uasm_reloc *r = relocs;
1466 1474
1467 memset(tlbmiss_handler_setup_pgd_array, 0, sizeof(tlbmiss_handler_setup_pgd_array)); 1475 memset(tlbmiss_handler_setup_pgd, 0, tlbmiss_handler_setup_pgd_size *
1476 sizeof(tlbmiss_handler_setup_pgd[0]));
1468 memset(labels, 0, sizeof(labels)); 1477 memset(labels, 0, sizeof(labels));
1469 memset(relocs, 0, sizeof(relocs)); 1478 memset(relocs, 0, sizeof(relocs));
1470 1479
@@ -1490,17 +1499,17 @@ static void __cpuinit build_r4000_setup_pgd(void)
1490 } else { 1499 } else {
1491 /* PGD in c0_KScratch */ 1500 /* PGD in c0_KScratch */
1492 uasm_i_jr(&p, 31); 1501 uasm_i_jr(&p, 31);
1493 UASM_i_MTC0(&p, a0, 31, pgd_reg); 1502 UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg);
1494 } 1503 }
1495 if (p - tlbmiss_handler_setup_pgd_array > ARRAY_SIZE(tlbmiss_handler_setup_pgd_array)) 1504 if (p >= tlbmiss_handler_setup_pgd_end)
1496 panic("tlbmiss_handler_setup_pgd_array space exceeded"); 1505 panic("tlbmiss_handler_setup_pgd space exceeded");
1506
1497 uasm_resolve_relocs(relocs, labels); 1507 uasm_resolve_relocs(relocs, labels);
1498 pr_debug("Wrote tlbmiss_handler_setup_pgd_array (%u instructions).\n", 1508 pr_debug("Wrote tlbmiss_handler_setup_pgd (%u instructions).\n",
1499 (unsigned int)(p - tlbmiss_handler_setup_pgd_array)); 1509 (unsigned int)(p - tlbmiss_handler_setup_pgd));
1500 1510
1501 dump_handler("tlbmiss_handler", 1511 dump_handler("tlbmiss_handler", tlbmiss_handler_setup_pgd,
1502 tlbmiss_handler_setup_pgd_array, 1512 tlbmiss_handler_setup_pgd_size);
1503 ARRAY_SIZE(tlbmiss_handler_setup_pgd_array));
1504} 1513}
1505#endif 1514#endif
1506 1515
@@ -1745,10 +1754,11 @@ build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte,
1745static void __cpuinit build_r3000_tlb_load_handler(void) 1754static void __cpuinit build_r3000_tlb_load_handler(void)
1746{ 1755{
1747 u32 *p = handle_tlbl; 1756 u32 *p = handle_tlbl;
1757 const int handle_tlbl_size = handle_tlbl_end - handle_tlbl;
1748 struct uasm_label *l = labels; 1758 struct uasm_label *l = labels;
1749 struct uasm_reloc *r = relocs; 1759 struct uasm_reloc *r = relocs;
1750 1760
1751 memset(handle_tlbl, 0, sizeof(handle_tlbl)); 1761 memset(handle_tlbl, 0, handle_tlbl_size * sizeof(handle_tlbl[0]));
1752 memset(labels, 0, sizeof(labels)); 1762 memset(labels, 0, sizeof(labels));
1753 memset(relocs, 0, sizeof(relocs)); 1763 memset(relocs, 0, sizeof(relocs));
1754 1764
@@ -1762,23 +1772,24 @@ static void __cpuinit build_r3000_tlb_load_handler(void)
1762 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); 1772 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
1763 uasm_i_nop(&p); 1773 uasm_i_nop(&p);
1764 1774
1765 if ((p - handle_tlbl) > FASTPATH_SIZE) 1775 if (p >= handle_tlbl_end)
1766 panic("TLB load handler fastpath space exceeded"); 1776 panic("TLB load handler fastpath space exceeded");
1767 1777
1768 uasm_resolve_relocs(relocs, labels); 1778 uasm_resolve_relocs(relocs, labels);
1769 pr_debug("Wrote TLB load handler fastpath (%u instructions).\n", 1779 pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
1770 (unsigned int)(p - handle_tlbl)); 1780 (unsigned int)(p - handle_tlbl));
1771 1781
1772 dump_handler("r3000_tlb_load", handle_tlbl, ARRAY_SIZE(handle_tlbl)); 1782 dump_handler("r3000_tlb_load", handle_tlbl, handle_tlbl_size);
1773} 1783}
1774 1784
1775static void __cpuinit build_r3000_tlb_store_handler(void) 1785static void __cpuinit build_r3000_tlb_store_handler(void)
1776{ 1786{
1777 u32 *p = handle_tlbs; 1787 u32 *p = handle_tlbs;
1788 const int handle_tlbs_size = handle_tlbs_end - handle_tlbs;
1778 struct uasm_label *l = labels; 1789 struct uasm_label *l = labels;
1779 struct uasm_reloc *r = relocs; 1790 struct uasm_reloc *r = relocs;
1780 1791
1781 memset(handle_tlbs, 0, sizeof(handle_tlbs)); 1792 memset(handle_tlbs, 0, handle_tlbs_size * sizeof(handle_tlbs[0]));
1782 memset(labels, 0, sizeof(labels)); 1793 memset(labels, 0, sizeof(labels));
1783 memset(relocs, 0, sizeof(relocs)); 1794 memset(relocs, 0, sizeof(relocs));
1784 1795
@@ -1792,23 +1803,24 @@ static void __cpuinit build_r3000_tlb_store_handler(void)
1792 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); 1803 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
1793 uasm_i_nop(&p); 1804 uasm_i_nop(&p);
1794 1805
1795 if ((p - handle_tlbs) > FASTPATH_SIZE) 1806 if (p >= handle_tlbs)
1796 panic("TLB store handler fastpath space exceeded"); 1807 panic("TLB store handler fastpath space exceeded");
1797 1808
1798 uasm_resolve_relocs(relocs, labels); 1809 uasm_resolve_relocs(relocs, labels);
1799 pr_debug("Wrote TLB store handler fastpath (%u instructions).\n", 1810 pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
1800 (unsigned int)(p - handle_tlbs)); 1811 (unsigned int)(p - handle_tlbs));
1801 1812
1802 dump_handler("r3000_tlb_store", handle_tlbs, ARRAY_SIZE(handle_tlbs)); 1813 dump_handler("r3000_tlb_store", handle_tlbs, handle_tlbs_size);
1803} 1814}
1804 1815
1805static void __cpuinit build_r3000_tlb_modify_handler(void) 1816static void __cpuinit build_r3000_tlb_modify_handler(void)
1806{ 1817{
1807 u32 *p = handle_tlbm; 1818 u32 *p = handle_tlbm;
1819 const int handle_tlbm_size = handle_tlbm_end - handle_tlbm;
1808 struct uasm_label *l = labels; 1820 struct uasm_label *l = labels;
1809 struct uasm_reloc *r = relocs; 1821 struct uasm_reloc *r = relocs;
1810 1822
1811 memset(handle_tlbm, 0, sizeof(handle_tlbm)); 1823 memset(handle_tlbm, 0, handle_tlbm_size * sizeof(handle_tlbm[0]));
1812 memset(labels, 0, sizeof(labels)); 1824 memset(labels, 0, sizeof(labels));
1813 memset(relocs, 0, sizeof(relocs)); 1825 memset(relocs, 0, sizeof(relocs));
1814 1826
@@ -1822,14 +1834,14 @@ static void __cpuinit build_r3000_tlb_modify_handler(void)
1822 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); 1834 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
1823 uasm_i_nop(&p); 1835 uasm_i_nop(&p);
1824 1836
1825 if ((p - handle_tlbm) > FASTPATH_SIZE) 1837 if (p >= handle_tlbm_end)
1826 panic("TLB modify handler fastpath space exceeded"); 1838 panic("TLB modify handler fastpath space exceeded");
1827 1839
1828 uasm_resolve_relocs(relocs, labels); 1840 uasm_resolve_relocs(relocs, labels);
1829 pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n", 1841 pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
1830 (unsigned int)(p - handle_tlbm)); 1842 (unsigned int)(p - handle_tlbm));
1831 1843
1832 dump_handler("r3000_tlb_modify", handle_tlbm, ARRAY_SIZE(handle_tlbm)); 1844 dump_handler("r3000_tlb_modify", handle_tlbm, handle_tlbm_size);
1833} 1845}
1834#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */ 1846#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
1835 1847
@@ -1893,11 +1905,12 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l,
1893static void __cpuinit build_r4000_tlb_load_handler(void) 1905static void __cpuinit build_r4000_tlb_load_handler(void)
1894{ 1906{
1895 u32 *p = handle_tlbl; 1907 u32 *p = handle_tlbl;
1908 const int handle_tlbl_size = handle_tlbl_end - handle_tlbl;
1896 struct uasm_label *l = labels; 1909 struct uasm_label *l = labels;
1897 struct uasm_reloc *r = relocs; 1910 struct uasm_reloc *r = relocs;
1898 struct work_registers wr; 1911 struct work_registers wr;
1899 1912
1900 memset(handle_tlbl, 0, sizeof(handle_tlbl)); 1913 memset(handle_tlbl, 0, handle_tlbl_size * sizeof(handle_tlbl[0]));
1901 memset(labels, 0, sizeof(labels)); 1914 memset(labels, 0, sizeof(labels));
1902 memset(relocs, 0, sizeof(relocs)); 1915 memset(relocs, 0, sizeof(relocs));
1903 1916
@@ -1935,6 +1948,19 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
1935 uasm_i_nop(&p); 1948 uasm_i_nop(&p);
1936 1949
1937 uasm_i_tlbr(&p); 1950 uasm_i_tlbr(&p);
1951
1952 switch (current_cpu_type()) {
1953 default:
1954 if (cpu_has_mips_r2) {
1955 uasm_i_ehb(&p);
1956
1957 case CPU_CAVIUM_OCTEON:
1958 case CPU_CAVIUM_OCTEON_PLUS:
1959 case CPU_CAVIUM_OCTEON2:
1960 break;
1961 }
1962 }
1963
1938 /* Examine entrylo 0 or 1 based on ptr. */ 1964 /* Examine entrylo 0 or 1 based on ptr. */
1939 if (use_bbit_insns()) { 1965 if (use_bbit_insns()) {
1940 uasm_i_bbit0(&p, wr.r2, ilog2(sizeof(pte_t)), 8); 1966 uasm_i_bbit0(&p, wr.r2, ilog2(sizeof(pte_t)), 8);
@@ -1989,6 +2015,19 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
1989 uasm_i_nop(&p); 2015 uasm_i_nop(&p);
1990 2016
1991 uasm_i_tlbr(&p); 2017 uasm_i_tlbr(&p);
2018
2019 switch (current_cpu_type()) {
2020 default:
2021 if (cpu_has_mips_r2) {
2022 uasm_i_ehb(&p);
2023
2024 case CPU_CAVIUM_OCTEON:
2025 case CPU_CAVIUM_OCTEON_PLUS:
2026 case CPU_CAVIUM_OCTEON2:
2027 break;
2028 }
2029 }
2030
1992 /* Examine entrylo 0 or 1 based on ptr. */ 2031 /* Examine entrylo 0 or 1 based on ptr. */
1993 if (use_bbit_insns()) { 2032 if (use_bbit_insns()) {
1994 uasm_i_bbit0(&p, wr.r2, ilog2(sizeof(pte_t)), 8); 2033 uasm_i_bbit0(&p, wr.r2, ilog2(sizeof(pte_t)), 8);
@@ -2036,24 +2075,25 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
2036 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); 2075 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
2037 uasm_i_nop(&p); 2076 uasm_i_nop(&p);
2038 2077
2039 if ((p - handle_tlbl) > FASTPATH_SIZE) 2078 if (p >= handle_tlbl_end)
2040 panic("TLB load handler fastpath space exceeded"); 2079 panic("TLB load handler fastpath space exceeded");
2041 2080
2042 uasm_resolve_relocs(relocs, labels); 2081 uasm_resolve_relocs(relocs, labels);
2043 pr_debug("Wrote TLB load handler fastpath (%u instructions).\n", 2082 pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
2044 (unsigned int)(p - handle_tlbl)); 2083 (unsigned int)(p - handle_tlbl));
2045 2084
2046 dump_handler("r4000_tlb_load", handle_tlbl, ARRAY_SIZE(handle_tlbl)); 2085 dump_handler("r4000_tlb_load", handle_tlbl, handle_tlbl_size);
2047} 2086}
2048 2087
2049static void __cpuinit build_r4000_tlb_store_handler(void) 2088static void __cpuinit build_r4000_tlb_store_handler(void)
2050{ 2089{
2051 u32 *p = handle_tlbs; 2090 u32 *p = handle_tlbs;
2091 const int handle_tlbs_size = handle_tlbs_end - handle_tlbs;
2052 struct uasm_label *l = labels; 2092 struct uasm_label *l = labels;
2053 struct uasm_reloc *r = relocs; 2093 struct uasm_reloc *r = relocs;
2054 struct work_registers wr; 2094 struct work_registers wr;
2055 2095
2056 memset(handle_tlbs, 0, sizeof(handle_tlbs)); 2096 memset(handle_tlbs, 0, handle_tlbs_size * sizeof(handle_tlbs[0]));
2057 memset(labels, 0, sizeof(labels)); 2097 memset(labels, 0, sizeof(labels));
2058 memset(relocs, 0, sizeof(relocs)); 2098 memset(relocs, 0, sizeof(relocs));
2059 2099
@@ -2090,24 +2130,25 @@ static void __cpuinit build_r4000_tlb_store_handler(void)
2090 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); 2130 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
2091 uasm_i_nop(&p); 2131 uasm_i_nop(&p);
2092 2132
2093 if ((p - handle_tlbs) > FASTPATH_SIZE) 2133 if (p >= handle_tlbs_end)
2094 panic("TLB store handler fastpath space exceeded"); 2134 panic("TLB store handler fastpath space exceeded");
2095 2135
2096 uasm_resolve_relocs(relocs, labels); 2136 uasm_resolve_relocs(relocs, labels);
2097 pr_debug("Wrote TLB store handler fastpath (%u instructions).\n", 2137 pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
2098 (unsigned int)(p - handle_tlbs)); 2138 (unsigned int)(p - handle_tlbs));
2099 2139
2100 dump_handler("r4000_tlb_store", handle_tlbs, ARRAY_SIZE(handle_tlbs)); 2140 dump_handler("r4000_tlb_store", handle_tlbs, handle_tlbs_size);
2101} 2141}
2102 2142
2103static void __cpuinit build_r4000_tlb_modify_handler(void) 2143static void __cpuinit build_r4000_tlb_modify_handler(void)
2104{ 2144{
2105 u32 *p = handle_tlbm; 2145 u32 *p = handle_tlbm;
2146 const int handle_tlbm_size = handle_tlbm_end - handle_tlbm;
2106 struct uasm_label *l = labels; 2147 struct uasm_label *l = labels;
2107 struct uasm_reloc *r = relocs; 2148 struct uasm_reloc *r = relocs;
2108 struct work_registers wr; 2149 struct work_registers wr;
2109 2150
2110 memset(handle_tlbm, 0, sizeof(handle_tlbm)); 2151 memset(handle_tlbm, 0, handle_tlbm_size * sizeof(handle_tlbm[0]));
2111 memset(labels, 0, sizeof(labels)); 2152 memset(labels, 0, sizeof(labels));
2112 memset(relocs, 0, sizeof(relocs)); 2153 memset(relocs, 0, sizeof(relocs));
2113 2154
@@ -2145,14 +2186,28 @@ static void __cpuinit build_r4000_tlb_modify_handler(void)
2145 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); 2186 uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
2146 uasm_i_nop(&p); 2187 uasm_i_nop(&p);
2147 2188
2148 if ((p - handle_tlbm) > FASTPATH_SIZE) 2189 if (p >= handle_tlbm_end)
2149 panic("TLB modify handler fastpath space exceeded"); 2190 panic("TLB modify handler fastpath space exceeded");
2150 2191
2151 uasm_resolve_relocs(relocs, labels); 2192 uasm_resolve_relocs(relocs, labels);
2152 pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n", 2193 pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
2153 (unsigned int)(p - handle_tlbm)); 2194 (unsigned int)(p - handle_tlbm));
2154 2195
2155 dump_handler("r4000_tlb_modify", handle_tlbm, ARRAY_SIZE(handle_tlbm)); 2196 dump_handler("r4000_tlb_modify", handle_tlbm, handle_tlbm_size);
2197}
2198
2199static void __cpuinit flush_tlb_handlers(void)
2200{
2201 local_flush_icache_range((unsigned long)handle_tlbl,
2202 (unsigned long)handle_tlbl_end);
2203 local_flush_icache_range((unsigned long)handle_tlbs,
2204 (unsigned long)handle_tlbs_end);
2205 local_flush_icache_range((unsigned long)handle_tlbm,
2206 (unsigned long)handle_tlbm_end);
2207#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
2208 local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd,
2209 (unsigned long)tlbmiss_handler_setup_pgd_end);
2210#endif
2156} 2211}
2157 2212
2158void __cpuinit build_tlb_refill_handler(void) 2213void __cpuinit build_tlb_refill_handler(void)
@@ -2187,6 +2242,7 @@ void __cpuinit build_tlb_refill_handler(void)
2187 build_r3000_tlb_load_handler(); 2242 build_r3000_tlb_load_handler();
2188 build_r3000_tlb_store_handler(); 2243 build_r3000_tlb_store_handler();
2189 build_r3000_tlb_modify_handler(); 2244 build_r3000_tlb_modify_handler();
2245 flush_tlb_handlers();
2190 run_once++; 2246 run_once++;
2191 } 2247 }
2192#else 2248#else
@@ -2214,23 +2270,10 @@ void __cpuinit build_tlb_refill_handler(void)
2214 build_r4000_tlb_modify_handler(); 2270 build_r4000_tlb_modify_handler();
2215 if (!cpu_has_local_ebase) 2271 if (!cpu_has_local_ebase)
2216 build_r4000_tlb_refill_handler(); 2272 build_r4000_tlb_refill_handler();
2273 flush_tlb_handlers();
2217 run_once++; 2274 run_once++;
2218 } 2275 }
2219 if (cpu_has_local_ebase) 2276 if (cpu_has_local_ebase)
2220 build_r4000_tlb_refill_handler(); 2277 build_r4000_tlb_refill_handler();
2221 } 2278 }
2222} 2279}
2223
2224void __cpuinit flush_tlb_handlers(void)
2225{
2226 local_flush_icache_range((unsigned long)handle_tlbl,
2227 (unsigned long)handle_tlbl + sizeof(handle_tlbl));
2228 local_flush_icache_range((unsigned long)handle_tlbs,
2229 (unsigned long)handle_tlbs + sizeof(handle_tlbs));
2230 local_flush_icache_range((unsigned long)handle_tlbm,
2231 (unsigned long)handle_tlbm + sizeof(handle_tlbm));
2232#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
2233 local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd_array,
2234 (unsigned long)tlbmiss_handler_setup_pgd_array + sizeof(handle_tlbm));
2235#endif
2236}