diff options
-rw-r--r-- | arch/sparc/mm/init_64.c | 104 |
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 | ||
1690 | static 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 | |||
1699 | static 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 | ||
1691 | static unsigned long last_valid_pfn; | 1733 | static 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); |