aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc/mm/init_64.c104
1 files changed, 65 insertions, 39 deletions
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 445369132e03..696bb095e0fc 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -1660,10 +1660,11 @@ static void __init sun4v_ktsb_init(void)
1660 ((unsigned long)&swapper_4m_tsb[0] - KERNBASE)); 1660 ((unsigned long)&swapper_4m_tsb[0] - KERNBASE));
1661 1661
1662 ktsb_descr[1].pgsz_idx = HV_PGSZ_IDX_4MB; 1662 ktsb_descr[1].pgsz_idx = HV_PGSZ_IDX_4MB;
1663 ktsb_descr[1].pgsz_mask = (HV_PGSZ_MASK_4MB | 1663 ktsb_descr[1].pgsz_mask = ((HV_PGSZ_MASK_4MB |
1664 HV_PGSZ_MASK_256MB); 1664 HV_PGSZ_MASK_256MB |
1665 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA4) 1665 HV_PGSZ_MASK_2GB |
1666 ktsb_descr[1].pgsz_mask |= HV_PGSZ_MASK_2GB; 1666 HV_PGSZ_MASK_16GB) &
1667 cpu_pgsz_mask);
1667 ktsb_descr[1].assoc = 1; 1668 ktsb_descr[1].assoc = 1;
1668 ktsb_descr[1].num_ttes = KERNEL_TSB4M_NENTRIES; 1669 ktsb_descr[1].num_ttes = KERNEL_TSB4M_NENTRIES;
1669 ktsb_descr[1].ctx_idx = 0; 1670 ktsb_descr[1].ctx_idx = 0;
@@ -1686,6 +1687,47 @@ void __cpuinit sun4v_ktsb_register(void)
1686 } 1687 }
1687} 1688}
1688 1689
1690static void __init sun4u_linear_pte_xor_finalize(void)
1691{
1692#ifndef CONFIG_DEBUG_PAGEALLOC
1693 /* This is where we would add Panther support for
1694 * 32MB and 256MB pages.
1695 */
1696#endif
1697}
1698
1699static void __init sun4v_linear_pte_xor_finalize(void)
1700{
1701#ifndef CONFIG_DEBUG_PAGEALLOC
1702 if (cpu_pgsz_mask & HV_PGSZ_MASK_256MB) {
1703 kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^
1704 0xfffff80000000000UL;
1705 kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V |
1706 _PAGE_P_4V | _PAGE_W_4V);
1707 } else {
1708 kern_linear_pte_xor[1] = kern_linear_pte_xor[0];
1709 }
1710
1711 if (cpu_pgsz_mask & HV_PGSZ_MASK_2GB) {
1712 kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZ2GB_4V) ^
1713 0xfffff80000000000UL;
1714 kern_linear_pte_xor[2] |= (_PAGE_CP_4V | _PAGE_CV_4V |
1715 _PAGE_P_4V | _PAGE_W_4V);
1716 } else {
1717 kern_linear_pte_xor[2] = kern_linear_pte_xor[1];
1718 }
1719
1720 if (cpu_pgsz_mask & HV_PGSZ_MASK_16GB) {
1721 kern_linear_pte_xor[3] = (_PAGE_VALID | _PAGE_SZ16GB_4V) ^
1722 0xfffff80000000000UL;
1723 kern_linear_pte_xor[3] |= (_PAGE_CP_4V | _PAGE_CV_4V |
1724 _PAGE_P_4V | _PAGE_W_4V);
1725 } else {
1726 kern_linear_pte_xor[3] = kern_linear_pte_xor[2];
1727 }
1728#endif
1729}
1730
1689/* paging_init() sets up the page tables */ 1731/* paging_init() sets up the page tables */
1690 1732
1691static unsigned long last_valid_pfn; 1733static unsigned long last_valid_pfn;
@@ -1745,10 +1787,8 @@ void __init paging_init(void)
1745 ktsb_phys_patch(); 1787 ktsb_phys_patch();
1746 } 1788 }
1747 1789
1748 if (tlb_type == hypervisor) { 1790 if (tlb_type == hypervisor)
1749 sun4v_patch_tlb_handlers(); 1791 sun4v_patch_tlb_handlers();
1750 sun4v_ktsb_init();
1751 }
1752 1792
1753 /* Find available physical memory... 1793 /* Find available physical memory...
1754 * 1794 *
@@ -1807,9 +1847,6 @@ void __init paging_init(void)
1807 1847
1808 __flush_tlb_all(); 1848 __flush_tlb_all();
1809 1849
1810 if (tlb_type == hypervisor)
1811 sun4v_ktsb_register();
1812
1813 prom_build_devicetree(); 1850 prom_build_devicetree();
1814 of_populate_present_mask(); 1851 of_populate_present_mask();
1815#ifndef CONFIG_SMP 1852#ifndef CONFIG_SMP
@@ -1823,6 +1860,11 @@ void __init paging_init(void)
1823 mdesc_fill_in_cpu_data(cpu_all_mask); 1860 mdesc_fill_in_cpu_data(cpu_all_mask);
1824#endif 1861#endif
1825 mdesc_get_page_sizes(cpu_all_mask, &cpu_pgsz_mask); 1862 mdesc_get_page_sizes(cpu_all_mask, &cpu_pgsz_mask);
1863
1864 sun4v_linear_pte_xor_finalize();
1865
1866 sun4v_ktsb_init();
1867 sun4v_ktsb_register();
1826 } else { 1868 } else {
1827 unsigned long impl, ver; 1869 unsigned long impl, ver;
1828 1870
@@ -1834,8 +1876,19 @@ void __init paging_init(void)
1834 if (impl == PANTHER_IMPL) 1876 if (impl == PANTHER_IMPL)
1835 cpu_pgsz_mask |= (HV_PGSZ_MASK_32MB | 1877 cpu_pgsz_mask |= (HV_PGSZ_MASK_32MB |
1836 HV_PGSZ_MASK_256MB); 1878 HV_PGSZ_MASK_256MB);
1879
1880 sun4u_linear_pte_xor_finalize();
1837 } 1881 }
1838 1882
1883 /* Flush the TLBs and the 4M TSB so that the updated linear
1884 * pte XOR settings are realized for all mappings.
1885 */
1886 __flush_tlb_all();
1887#ifndef CONFIG_DEBUG_PAGEALLOC
1888 memset(swapper_4m_tsb, 0x40, sizeof(swapper_4m_tsb));
1889#endif
1890 __flush_tlb_all();
1891
1839 /* Setup bootmem... */ 1892 /* Setup bootmem... */
1840 last_valid_pfn = end_pfn = bootmem_init(phys_base); 1893 last_valid_pfn = end_pfn = bootmem_init(phys_base);
1841 1894
@@ -2230,7 +2283,6 @@ static void __init sun4u_pgprot_init(void)
2230 kern_linear_pte_xor[0] |= (_PAGE_CP_4U | _PAGE_CV_4U | 2283 kern_linear_pte_xor[0] |= (_PAGE_CP_4U | _PAGE_CV_4U |
2231 _PAGE_P_4U | _PAGE_W_4U); 2284 _PAGE_P_4U | _PAGE_W_4U);
2232 2285
2233 /* XXX Should use 256MB on Panther. XXX */
2234 for (i = 1; i < 4; i++) 2286 for (i = 1; i < 4; i++)
2235 kern_linear_pte_xor[i] = kern_linear_pte_xor[0]; 2287 kern_linear_pte_xor[i] = kern_linear_pte_xor[0];
2236 2288
@@ -2280,34 +2332,8 @@ static void __init sun4v_pgprot_init(void)
2280 kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V | 2332 kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V |
2281 _PAGE_P_4V | _PAGE_W_4V); 2333 _PAGE_P_4V | _PAGE_W_4V);
2282 2334
2283#ifdef CONFIG_DEBUG_PAGEALLOC 2335 for (i = 1; i < 4; i++)
2284 kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^ 2336 kern_linear_pte_xor[i] = kern_linear_pte_xor[0];
2285 0xfffff80000000000UL;
2286#else
2287 kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^
2288 0xfffff80000000000UL;
2289#endif
2290 kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V |
2291 _PAGE_P_4V | _PAGE_W_4V);
2292
2293 i = 2;
2294
2295 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA4) {
2296#ifdef CONFIG_DEBUG_PAGEALLOC
2297 kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^
2298 0xfffff80000000000UL;
2299#else
2300 kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZ2GB_4V) ^
2301 0xfffff80000000000UL;
2302#endif
2303 kern_linear_pte_xor[2] |= (_PAGE_CP_4V | _PAGE_CV_4V |
2304 _PAGE_P_4V | _PAGE_W_4V);
2305
2306 i = 3;
2307 }
2308
2309 for (; i < 4; i++)
2310 kern_linear_pte_xor[i] = kern_linear_pte_xor[i - 1];
2311 2337
2312 pg_iobits = (_PAGE_VALID | _PAGE_PRESENT_4V | __DIRTY_BITS_4V | 2338 pg_iobits = (_PAGE_VALID | _PAGE_PRESENT_4V | __DIRTY_BITS_4V |
2313 __ACCESS_BITS_4V | _PAGE_E_4V); 2339 __ACCESS_BITS_4V | _PAGE_E_4V);