Introduce flags for reserve_bootmem()
[deliverable/linux.git] / arch / sparc64 / mm / init.c
index 3010227fe24313ccddc630068c9503aa77b7c409..e726c45645ff3bc85df870d7eed4613427062133 100644 (file)
@@ -201,7 +201,7 @@ inline void flush_dcache_page_impl(struct page *page)
 #define dcache_dirty_cpu(page) \
        (((page)->flags >> PG_dcache_cpu_shift) & PG_dcache_cpu_mask)
 
-static __inline__ void set_dcache_dirty(struct page *page, int this_cpu)
+static inline void set_dcache_dirty(struct page *page, int this_cpu)
 {
        unsigned long mask = this_cpu;
        unsigned long non_cpu_bits;
@@ -223,7 +223,7 @@ static __inline__ void set_dcache_dirty(struct page *page, int this_cpu)
                             : "g1", "g7");
 }
 
-static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long cpu)
+static inline void clear_dcache_dirty_cpu(struct page *page, unsigned long cpu)
 {
        unsigned long mask = (1UL << PG_dcache_dirty);
 
@@ -631,7 +631,6 @@ void prom_world(int enter)
        __asm__ __volatile__("flushw");
 }
 
-#ifdef DCACHE_ALIASING_POSSIBLE
 void __flush_dcache_range(unsigned long start, unsigned long end)
 {
        unsigned long va;
@@ -655,7 +654,6 @@ void __flush_dcache_range(unsigned long start, unsigned long end)
                                               "i" (ASI_DCACHE_INVALIDATE));
        }
 }
-#endif /* DCACHE_ALIASING_POSSIBLE */
 
 /* get_new_mmu_context() uses "cache + 1".  */
 DEFINE_SPINLOCK(ctx_alloc_lock);
@@ -999,7 +997,7 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
                prom_printf("reserve_bootmem(initrd): base[%llx] size[%lx]\n",
                        initrd_start, initrd_end);
 #endif
-               reserve_bootmem(initrd_start, size);
+               reserve_bootmem(initrd_start, size, BOOTMEM_DEFAULT);
 
                initrd_start += PAGE_OFFSET;
                initrd_end += PAGE_OFFSET;
@@ -1009,7 +1007,7 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
 #ifdef CONFIG_DEBUG_BOOTMEM
        prom_printf("reserve_bootmem(kernel): base[%lx] size[%lx]\n", kern_base, kern_size);
 #endif
-       reserve_bootmem(kern_base, kern_size);
+       reserve_bootmem(kern_base, kern_size, BOOTMEM_DEFAULT);
        *pages_avail -= PAGE_ALIGN(kern_size) >> PAGE_SHIFT;
 
        /* Add back in the initmem pages. */
@@ -1026,7 +1024,7 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
        prom_printf("reserve_bootmem(bootmap): base[%lx] size[%lx]\n",
                    (bootmap_pfn << PAGE_SHIFT), size);
 #endif
-       reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size);
+       reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size, BOOTMEM_DEFAULT);
 
        for (i = 0; i < pavail_ents; i++) {
                unsigned long start_pfn, end_pfn;
@@ -1135,14 +1133,9 @@ static void __init mark_kpte_bitmap(unsigned long start, unsigned long end)
        }
 }
 
-static void __init kernel_physical_mapping_init(void)
+static void __init init_kpte_bitmap(void)
 {
        unsigned long i;
-#ifdef CONFIG_DEBUG_PAGEALLOC
-       unsigned long mem_alloced = 0UL;
-#endif
-
-       read_obp_memory("reg", &pall[0], &pall_ents);
 
        for (i = 0; i < pall_ents; i++) {
                unsigned long phys_start, phys_end;
@@ -1151,14 +1144,24 @@ static void __init kernel_physical_mapping_init(void)
                phys_end = phys_start + pall[i].reg_size;
 
                mark_kpte_bitmap(phys_start, phys_end);
+       }
+}
 
+static void __init kernel_physical_mapping_init(void)
+{
 #ifdef CONFIG_DEBUG_PAGEALLOC
+       unsigned long i, mem_alloced = 0UL;
+
+       for (i = 0; i < pall_ents; i++) {
+               unsigned long phys_start, phys_end;
+
+               phys_start = pall[i].phys_addr;
+               phys_end = phys_start + pall[i].reg_size;
+
                mem_alloced += kernel_map_range(phys_start, phys_end,
                                                PAGE_KERNEL);
-#endif
        }
 
-#ifdef CONFIG_DEBUG_PAGEALLOC
        printk("Allocated %ld bytes for kernel page tables.\n",
               mem_alloced);
 
@@ -1325,6 +1328,11 @@ pgd_t swapper_pg_dir[2048];
 static void sun4u_pgprot_init(void);
 static void sun4v_pgprot_init(void);
 
+/* Dummy function */
+void __init setup_per_cpu_areas(void)
+{
+}
+
 void __init paging_init(void)
 {
        unsigned long end_pfn, pages_avail, shift, phys_base;
@@ -1400,6 +1408,10 @@ void __init paging_init(void)
        
        inherit_prom_mappings();
        
+       read_obp_memory("reg", &pall[0], &pall_ents);
+
+       init_kpte_bitmap();
+
        /* Ok, we can use our TLB miss and window trap handlers safely.  */
        setup_tba();
 
@@ -1477,7 +1489,7 @@ static void __init taint_real_pages(void)
                                        goto do_next_page;
                                }
                        }
-                       reserve_bootmem(old_start, PAGE_SIZE);
+                       reserve_bootmem(old_start, PAGE_SIZE, BOOTMEM_DEFAULT);
 
                do_next_page:
                        old_start += PAGE_SIZE;
@@ -1647,6 +1659,58 @@ EXPORT_SYMBOL(_PAGE_E);
 unsigned long _PAGE_CACHE __read_mostly;
 EXPORT_SYMBOL(_PAGE_CACHE);
 
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+
+#define VMEMMAP_CHUNK_SHIFT    22
+#define VMEMMAP_CHUNK          (1UL << VMEMMAP_CHUNK_SHIFT)
+#define VMEMMAP_CHUNK_MASK     ~(VMEMMAP_CHUNK - 1UL)
+#define VMEMMAP_ALIGN(x)       (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK)
+
+#define VMEMMAP_SIZE   ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \
+                         sizeof(struct page *)) >> VMEMMAP_CHUNK_SHIFT)
+unsigned long vmemmap_table[VMEMMAP_SIZE];
+
+int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node)
+{
+       unsigned long vstart = (unsigned long) start;
+       unsigned long vend = (unsigned long) (start + nr);
+       unsigned long phys_start = (vstart - VMEMMAP_BASE);
+       unsigned long phys_end = (vend - VMEMMAP_BASE);
+       unsigned long addr = phys_start & VMEMMAP_CHUNK_MASK;
+       unsigned long end = VMEMMAP_ALIGN(phys_end);
+       unsigned long pte_base;
+
+       pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4U |
+                   _PAGE_CP_4U | _PAGE_CV_4U |
+                   _PAGE_P_4U | _PAGE_W_4U);
+       if (tlb_type == hypervisor)
+               pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4V |
+                           _PAGE_CP_4V | _PAGE_CV_4V |
+                           _PAGE_P_4V | _PAGE_W_4V);
+
+       for (; addr < end; addr += VMEMMAP_CHUNK) {
+               unsigned long *vmem_pp =
+                       vmemmap_table + (addr >> VMEMMAP_CHUNK_SHIFT);
+               void *block;
+
+               if (!(*vmem_pp & _PAGE_VALID)) {
+                       block = vmemmap_alloc_block(1UL << 22, node);
+                       if (!block)
+                               return -ENOMEM;
+
+                       *vmem_pp = pte_base | __pa(block);
+
+                       printk(KERN_INFO "[%p-%p] page_structs=%lu "
+                              "node=%d entry=%lu/%lu\n", start, block, nr,
+                              node,
+                              addr >> VMEMMAP_CHUNK_SHIFT,
+                              VMEMMAP_SIZE >> VMEMMAP_CHUNK_SHIFT);
+               }
+       }
+       return 0;
+}
+#endif /* CONFIG_SPARSEMEM_VMEMMAP */
+
 static void prot_init_common(unsigned long page_none,
                             unsigned long page_shared,
                             unsigned long page_copy,
@@ -1854,7 +1918,9 @@ void __flush_tlb_all(void)
                             "wrpr      %0, %1, %%pstate"
                             : "=r" (pstate)
                             : "i" (PSTATE_IE));
-       if (tlb_type == spitfire) {
+       if (tlb_type == hypervisor) {
+               sun4v_mmu_demap_all();
+       } else if (tlb_type == spitfire) {
                for (i = 0; i < 64; i++) {
                        /* Spitfire Errata #32 workaround */
                        /* NOTE: Always runs on spitfire, so no
@@ -1911,9 +1977,4 @@ void online_page(struct page *page)
        num_physpages++;
 }
 
-int remove_memory(u64 start, u64 size)
-{
-       return -EINVAL;
-}
-
 #endif /* CONFIG_MEMORY_HOTPLUG */
This page took 0.033093 seconds and 5 git commands to generate.