diff options
Diffstat (limited to 'arch/sparc64/mm/init.c')
-rw-r--r-- | arch/sparc64/mm/init.c | 84 |
1 files changed, 47 insertions, 37 deletions
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index a41df7bef035..3c10daf8fc01 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c | |||
@@ -46,15 +46,11 @@ | |||
46 | #include <asm/tsb.h> | 46 | #include <asm/tsb.h> |
47 | #include <asm/hypervisor.h> | 47 | #include <asm/hypervisor.h> |
48 | #include <asm/prom.h> | 48 | #include <asm/prom.h> |
49 | #include <asm/sstate.h> | ||
50 | #include <asm/mdesc.h> | 49 | #include <asm/mdesc.h> |
51 | #include <asm/cpudata.h> | 50 | #include <asm/cpudata.h> |
52 | #include <asm/irq.h> | 51 | #include <asm/irq.h> |
53 | 52 | ||
54 | #define MAX_PHYS_ADDRESS (1UL << 42UL) | 53 | #include "init.h" |
55 | #define KPTE_BITMAP_CHUNK_SZ (256UL * 1024UL * 1024UL) | ||
56 | #define KPTE_BITMAP_BYTES \ | ||
57 | ((MAX_PHYS_ADDRESS / KPTE_BITMAP_CHUNK_SZ) / 8) | ||
58 | 54 | ||
59 | unsigned long kern_linear_pte_xor[2] __read_mostly; | 55 | unsigned long kern_linear_pte_xor[2] __read_mostly; |
60 | 56 | ||
@@ -416,17 +412,9 @@ void mmu_info(struct seq_file *m) | |||
416 | #endif /* CONFIG_DEBUG_DCFLUSH */ | 412 | #endif /* CONFIG_DEBUG_DCFLUSH */ |
417 | } | 413 | } |
418 | 414 | ||
419 | struct linux_prom_translation { | ||
420 | unsigned long virt; | ||
421 | unsigned long size; | ||
422 | unsigned long data; | ||
423 | }; | ||
424 | |||
425 | /* Exported for kernel TLB miss handling in ktlb.S */ | ||
426 | struct linux_prom_translation prom_trans[512] __read_mostly; | 415 | struct linux_prom_translation prom_trans[512] __read_mostly; |
427 | unsigned int prom_trans_ents __read_mostly; | 416 | unsigned int prom_trans_ents __read_mostly; |
428 | 417 | ||
429 | /* Exported for SMP bootup purposes. */ | ||
430 | unsigned long kern_locked_tte_data; | 418 | unsigned long kern_locked_tte_data; |
431 | 419 | ||
432 | /* The obp translations are saved based on 8k pagesize, since obp can | 420 | /* The obp translations are saved based on 8k pagesize, since obp can |
@@ -938,6 +926,10 @@ int of_node_to_nid(struct device_node *dp) | |||
938 | int count, nid; | 926 | int count, nid; |
939 | u64 grp; | 927 | u64 grp; |
940 | 928 | ||
929 | /* This is the right thing to do on currently supported | ||
930 | * SUN4U NUMA platforms as well, as the PCI controller does | ||
931 | * not sit behind any particular memory controller. | ||
932 | */ | ||
941 | if (!mlgroups) | 933 | if (!mlgroups) |
942 | return -1; | 934 | return -1; |
943 | 935 | ||
@@ -1206,8 +1198,44 @@ out: | |||
1206 | return err; | 1198 | return err; |
1207 | } | 1199 | } |
1208 | 1200 | ||
1201 | static int __init numa_parse_jbus(void) | ||
1202 | { | ||
1203 | unsigned long cpu, index; | ||
1204 | |||
1205 | /* NUMA node id is encoded in bits 36 and higher, and there is | ||
1206 | * a 1-to-1 mapping from CPU ID to NUMA node ID. | ||
1207 | */ | ||
1208 | index = 0; | ||
1209 | for_each_present_cpu(cpu) { | ||
1210 | numa_cpu_lookup_table[cpu] = index; | ||
1211 | numa_cpumask_lookup_table[index] = cpumask_of_cpu(cpu); | ||
1212 | node_masks[index].mask = ~((1UL << 36UL) - 1UL); | ||
1213 | node_masks[index].val = cpu << 36UL; | ||
1214 | |||
1215 | index++; | ||
1216 | } | ||
1217 | num_node_masks = index; | ||
1218 | |||
1219 | add_node_ranges(); | ||
1220 | |||
1221 | for (index = 0; index < num_node_masks; index++) { | ||
1222 | allocate_node_data(index); | ||
1223 | node_set_online(index); | ||
1224 | } | ||
1225 | |||
1226 | return 0; | ||
1227 | } | ||
1228 | |||
1209 | static int __init numa_parse_sun4u(void) | 1229 | static int __init numa_parse_sun4u(void) |
1210 | { | 1230 | { |
1231 | if (tlb_type == cheetah || tlb_type == cheetah_plus) { | ||
1232 | unsigned long ver; | ||
1233 | |||
1234 | __asm__ ("rdpr %%ver, %0" : "=r" (ver)); | ||
1235 | if ((ver >> 32UL) == __JALAPENO_ID || | ||
1236 | (ver >> 32UL) == __SERRANO_ID) | ||
1237 | return numa_parse_jbus(); | ||
1238 | } | ||
1211 | return -1; | 1239 | return -1; |
1212 | } | 1240 | } |
1213 | 1241 | ||
@@ -1633,8 +1661,6 @@ void __cpuinit sun4v_ktsb_register(void) | |||
1633 | 1661 | ||
1634 | /* paging_init() sets up the page tables */ | 1662 | /* paging_init() sets up the page tables */ |
1635 | 1663 | ||
1636 | extern void central_probe(void); | ||
1637 | |||
1638 | static unsigned long last_valid_pfn; | 1664 | static unsigned long last_valid_pfn; |
1639 | pgd_t swapper_pg_dir[2048]; | 1665 | pgd_t swapper_pg_dir[2048]; |
1640 | 1666 | ||
@@ -1679,8 +1705,6 @@ void __init paging_init(void) | |||
1679 | kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL; | 1705 | kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL; |
1680 | kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; | 1706 | kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; |
1681 | 1707 | ||
1682 | sstate_booting(); | ||
1683 | |||
1684 | /* Invalidate both kernel TSBs. */ | 1708 | /* Invalidate both kernel TSBs. */ |
1685 | memset(swapper_tsb, 0x40, sizeof(swapper_tsb)); | 1709 | memset(swapper_tsb, 0x40, sizeof(swapper_tsb)); |
1686 | #ifndef CONFIG_DEBUG_PAGEALLOC | 1710 | #ifndef CONFIG_DEBUG_PAGEALLOC |
@@ -1803,9 +1827,6 @@ void __init paging_init(void) | |||
1803 | } | 1827 | } |
1804 | 1828 | ||
1805 | printk("Booting Linux...\n"); | 1829 | printk("Booting Linux...\n"); |
1806 | |||
1807 | central_probe(); | ||
1808 | cpu_probe(); | ||
1809 | } | 1830 | } |
1810 | 1831 | ||
1811 | int __init page_in_phys_avail(unsigned long paddr) | 1832 | int __init page_in_phys_avail(unsigned long paddr) |
@@ -2032,7 +2053,6 @@ pgprot_t PAGE_COPY __read_mostly; | |||
2032 | pgprot_t PAGE_SHARED __read_mostly; | 2053 | pgprot_t PAGE_SHARED __read_mostly; |
2033 | EXPORT_SYMBOL(PAGE_SHARED); | 2054 | EXPORT_SYMBOL(PAGE_SHARED); |
2034 | 2055 | ||
2035 | pgprot_t PAGE_EXEC __read_mostly; | ||
2036 | unsigned long pg_iobits __read_mostly; | 2056 | unsigned long pg_iobits __read_mostly; |
2037 | 2057 | ||
2038 | unsigned long _PAGE_IE __read_mostly; | 2058 | unsigned long _PAGE_IE __read_mostly; |
@@ -2045,14 +2065,6 @@ unsigned long _PAGE_CACHE __read_mostly; | |||
2045 | EXPORT_SYMBOL(_PAGE_CACHE); | 2065 | EXPORT_SYMBOL(_PAGE_CACHE); |
2046 | 2066 | ||
2047 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | 2067 | #ifdef CONFIG_SPARSEMEM_VMEMMAP |
2048 | |||
2049 | #define VMEMMAP_CHUNK_SHIFT 22 | ||
2050 | #define VMEMMAP_CHUNK (1UL << VMEMMAP_CHUNK_SHIFT) | ||
2051 | #define VMEMMAP_CHUNK_MASK ~(VMEMMAP_CHUNK - 1UL) | ||
2052 | #define VMEMMAP_ALIGN(x) (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK) | ||
2053 | |||
2054 | #define VMEMMAP_SIZE ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \ | ||
2055 | sizeof(struct page *)) >> VMEMMAP_CHUNK_SHIFT) | ||
2056 | unsigned long vmemmap_table[VMEMMAP_SIZE]; | 2068 | unsigned long vmemmap_table[VMEMMAP_SIZE]; |
2057 | 2069 | ||
2058 | int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) | 2070 | int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) |
@@ -2136,7 +2148,6 @@ static void __init sun4u_pgprot_init(void) | |||
2136 | _PAGE_CACHE_4U | _PAGE_P_4U | | 2148 | _PAGE_CACHE_4U | _PAGE_P_4U | |
2137 | __ACCESS_BITS_4U | __DIRTY_BITS_4U | | 2149 | __ACCESS_BITS_4U | __DIRTY_BITS_4U | |
2138 | _PAGE_EXEC_4U | _PAGE_L_4U); | 2150 | _PAGE_EXEC_4U | _PAGE_L_4U); |
2139 | PAGE_EXEC = __pgprot(_PAGE_EXEC_4U); | ||
2140 | 2151 | ||
2141 | _PAGE_IE = _PAGE_IE_4U; | 2152 | _PAGE_IE = _PAGE_IE_4U; |
2142 | _PAGE_E = _PAGE_E_4U; | 2153 | _PAGE_E = _PAGE_E_4U; |
@@ -2147,10 +2158,10 @@ static void __init sun4u_pgprot_init(void) | |||
2147 | 2158 | ||
2148 | #ifdef CONFIG_DEBUG_PAGEALLOC | 2159 | #ifdef CONFIG_DEBUG_PAGEALLOC |
2149 | kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZBITS_4U) ^ | 2160 | kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZBITS_4U) ^ |
2150 | 0xfffff80000000000; | 2161 | 0xfffff80000000000UL; |
2151 | #else | 2162 | #else |
2152 | kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4U) ^ | 2163 | kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4U) ^ |
2153 | 0xfffff80000000000; | 2164 | 0xfffff80000000000UL; |
2154 | #endif | 2165 | #endif |
2155 | kern_linear_pte_xor[0] |= (_PAGE_CP_4U | _PAGE_CV_4U | | 2166 | kern_linear_pte_xor[0] |= (_PAGE_CP_4U | _PAGE_CV_4U | |
2156 | _PAGE_P_4U | _PAGE_W_4U); | 2167 | _PAGE_P_4U | _PAGE_W_4U); |
@@ -2188,7 +2199,6 @@ static void __init sun4v_pgprot_init(void) | |||
2188 | __ACCESS_BITS_4V | __DIRTY_BITS_4V | | 2199 | __ACCESS_BITS_4V | __DIRTY_BITS_4V | |
2189 | _PAGE_EXEC_4V); | 2200 | _PAGE_EXEC_4V); |
2190 | PAGE_KERNEL_LOCKED = PAGE_KERNEL; | 2201 | PAGE_KERNEL_LOCKED = PAGE_KERNEL; |
2191 | PAGE_EXEC = __pgprot(_PAGE_EXEC_4V); | ||
2192 | 2202 | ||
2193 | _PAGE_IE = _PAGE_IE_4V; | 2203 | _PAGE_IE = _PAGE_IE_4V; |
2194 | _PAGE_E = _PAGE_E_4V; | 2204 | _PAGE_E = _PAGE_E_4V; |
@@ -2196,20 +2206,20 @@ static void __init sun4v_pgprot_init(void) | |||
2196 | 2206 | ||
2197 | #ifdef CONFIG_DEBUG_PAGEALLOC | 2207 | #ifdef CONFIG_DEBUG_PAGEALLOC |
2198 | kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^ | 2208 | kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^ |
2199 | 0xfffff80000000000; | 2209 | 0xfffff80000000000UL; |
2200 | #else | 2210 | #else |
2201 | kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^ | 2211 | kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^ |
2202 | 0xfffff80000000000; | 2212 | 0xfffff80000000000UL; |
2203 | #endif | 2213 | #endif |
2204 | kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V | | 2214 | kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V | |
2205 | _PAGE_P_4V | _PAGE_W_4V); | 2215 | _PAGE_P_4V | _PAGE_W_4V); |
2206 | 2216 | ||
2207 | #ifdef CONFIG_DEBUG_PAGEALLOC | 2217 | #ifdef CONFIG_DEBUG_PAGEALLOC |
2208 | kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^ | 2218 | kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^ |
2209 | 0xfffff80000000000; | 2219 | 0xfffff80000000000UL; |
2210 | #else | 2220 | #else |
2211 | kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^ | 2221 | kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^ |
2212 | 0xfffff80000000000; | 2222 | 0xfffff80000000000UL; |
2213 | #endif | 2223 | #endif |
2214 | kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V | | 2224 | kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V | |
2215 | _PAGE_P_4V | _PAGE_W_4V); | 2225 | _PAGE_P_4V | _PAGE_W_4V); |