include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / arch / parisc / mm / init.c
index 25ad28d..f4f4d70 100644 (file)
@@ -6,7 +6,7 @@
  *    changed by Philipp Rumpf
  *  Copyright 1999 Philipp Rumpf (prumpf@tux.org)
  *  Copyright 2004 Randolph Chung (tausq@debian.org)
- *  Copyright 2006 Helge Deller (deller@gmx.de)
+ *  Copyright 2006-2007 Helge Deller (deller@gmx.de)
  *
  */
 
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
+#include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/pci.h>         /* for hppa_dma_ops and pcxl_dma_ops */
@@ -24,6 +25,7 @@
 #include <linux/pagemap.h>     /* for release_pages and page_cache_release */
 
 #include <asm/pgalloc.h>
+#include <asm/pgtable.h>
 #include <asm/tlb.h>
 #include <asm/pdc_chassis.h>
 #include <asm/mmzone.h>
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
-extern char _text;     /* start of kernel code, defined by linker */
 extern int  data_start;
-extern char _end;      /* end of BSS, defined by linker */
-extern char __init_begin, __init_end;
 
 #ifdef CONFIG_DISCONTIGMEM
 struct node_map_data node_data[MAX_NUMNODES] __read_mostly;
-bootmem_data_t bmem_data[MAX_NUMNODES] __read_mostly;
 unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly;
 #endif
 
@@ -68,11 +66,11 @@ static struct resource sysram_resources[MAX_PHYSMEM_RANGES] __read_mostly;
 physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly;
 int npmem_ranges __read_mostly;
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 #define MAX_MEM         (~0UL)
-#else /* !__LP64__ */
+#else /* !CONFIG_64BIT */
 #define MAX_MEM         (3584U*1024U*1024U)
-#endif /* !__LP64__ */
+#endif /* !CONFIG_64BIT */
 
 static unsigned long mem_limit __read_mostly = MAX_MEM;
 
@@ -80,12 +78,11 @@ static void __init mem_limit_func(void)
 {
        char *cp, *end;
        unsigned long limit;
-       extern char saved_command_line[];
 
        /* We need this before __setup() functions are called */
 
        limit = MAX_MEM;
-       for (cp = saved_command_line; *cp; ) {
+       for (cp = boot_command_line; *cp; ) {
                if (memcmp(cp, "mem=", 4) == 0) {
                        cp += 4;
                        limit = memparse(cp, &end);
@@ -265,7 +262,7 @@ static void __init setup_bootmem(void)
 #ifdef CONFIG_DISCONTIGMEM
        for (i = 0; i < MAX_PHYSMEM_RANGES; i++) {
                memset(NODE_DATA(i), 0, sizeof(pg_data_t));
-               NODE_DATA(i)->bdata = &bmem_data[i];
+               NODE_DATA(i)->bdata = &bootmem_node_data[i];
        }
        memset(pfnnid_map, 0xff, sizeof(pfnnid_map));
 
@@ -308,21 +305,21 @@ static void __init setup_bootmem(void)
         */
        max_low_pfn = max_pfn;
 
-       if ((bootmap_pfn - bootmap_start_pfn) != bootmap_pages) {
-               printk(KERN_WARNING "WARNING! bootmap sizing is messed up!\n");
-               BUG();
-       }
+       /* bootmap sizing messed up? */
+       BUG_ON((bootmap_pfn - bootmap_start_pfn) != bootmap_pages);
 
        /* reserve PAGE0 pdc memory, kernel text/data/bss & bootmap */
 
 #define PDC_CONSOLE_IO_IODC_SIZE 32768
 
        reserve_bootmem_node(NODE_DATA(0), 0UL,
-                       (unsigned long)(PAGE0->mem_free + PDC_CONSOLE_IO_IODC_SIZE));
-       reserve_bootmem_node(NODE_DATA(0),__pa((unsigned long)&_text),
-                       (unsigned long)(&_end - &_text));
+                       (unsigned long)(PAGE0->mem_free +
+                               PDC_CONSOLE_IO_IODC_SIZE), BOOTMEM_DEFAULT);
+       reserve_bootmem_node(NODE_DATA(0), __pa((unsigned long)_text),
+                       (unsigned long)(_end - _text), BOOTMEM_DEFAULT);
        reserve_bootmem_node(NODE_DATA(0), (bootmap_start_pfn << PAGE_SHIFT),
-                       ((bootmap_pfn - bootmap_start_pfn) << PAGE_SHIFT));
+                       ((bootmap_pfn - bootmap_start_pfn) << PAGE_SHIFT),
+                       BOOTMEM_DEFAULT);
 
 #ifndef CONFIG_DISCONTIGMEM
 
@@ -331,7 +328,8 @@ static void __init setup_bootmem(void)
        for (i = 0; i < npmem_holes; i++) {
                reserve_bootmem_node(NODE_DATA(0),
                                (pmem_holes[i].start_pfn << PAGE_SHIFT),
-                               (pmem_holes[i].pages << PAGE_SHIFT));
+                               (pmem_holes[i].pages << PAGE_SHIFT),
+                               BOOTMEM_DEFAULT);
        }
 #endif
 
@@ -349,14 +347,15 @@ static void __init setup_bootmem(void)
                        initrd_below_start_ok = 1;
                        printk(KERN_INFO "initrd: reserving %08lx-%08lx (mem_max %08lx)\n", __pa(initrd_start), __pa(initrd_start) + initrd_reserve, mem_max);
 
-                       reserve_bootmem_node(NODE_DATA(0),__pa(initrd_start), initrd_reserve);
+                       reserve_bootmem_node(NODE_DATA(0), __pa(initrd_start),
+                                       initrd_reserve, BOOTMEM_DEFAULT);
                }
        }
 #endif
 
        data_resource.start =  virt_to_phys(&data_start);
-       data_resource.end = virt_to_phys(&_end)-1;
-       code_resource.start = virt_to_phys(&_text);
+       data_resource.end = virt_to_phys(_end) - 1;
+       code_resource.start = virt_to_phys(_text);
        code_resource.end = virt_to_phys(&data_start)-1;
 
        /* We don't know which region the kernel will be in, so try
@@ -372,34 +371,22 @@ static void __init setup_bootmem(void)
 
 void free_initmem(void)
 {
-       unsigned long addr, init_begin, init_end;
-
-       printk(KERN_INFO "Freeing unused kernel memory: ");
+       unsigned long addr;
+       unsigned long init_begin = (unsigned long)__init_begin;
+       unsigned long init_end = (unsigned long)__init_end;
 
 #ifdef CONFIG_DEBUG_KERNEL
        /* Attempt to catch anyone trying to execute code here
         * by filling the page with BRK insns.
-        * 
-        * If we disable interrupts for all CPUs, then IPI stops working.
-        * Kinda breaks the global cache flushing.
         */
-       local_irq_disable();
-
-       memset(&__init_begin, 0x00, 
-               (unsigned long)&__init_end - (unsigned long)&__init_begin);
-
-       flush_data_cache();
-       asm volatile("sync" : : );
-       flush_icache_range((unsigned long)&__init_begin, (unsigned long)&__init_end);
-       asm volatile("sync" : : );
-
-       local_irq_enable();
+       memset((void *)init_begin, 0x00, init_end - init_begin);
+       flush_icache_range(init_begin, init_end);
 #endif
        
        /* align __init_begin and __init_end to page size,
           ignoring linker script where we might have tried to save RAM */
-       init_begin = PAGE_ALIGN((unsigned long)(&__init_begin));
-       init_end   = PAGE_ALIGN((unsigned long)(&__init_end));
+       init_begin = PAGE_ALIGN(init_begin);
+       init_end = PAGE_ALIGN(init_end);
        for (addr = init_begin; addr < init_end; addr += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(addr));
                init_page_count(virt_to_page(addr));
@@ -411,7 +398,8 @@ void free_initmem(void)
        /* set up a new led state on systems shipped LED State panel */
        pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE);
        
-       printk("%luk freed\n", (init_end - init_begin) >> 10);
+       printk(KERN_INFO "Freeing unused kernel memory: %luk freed\n",
+               (init_end - init_begin) >> 10);
 }
 
 
@@ -447,8 +435,8 @@ void mark_rodata_ro(void)
 #define SET_MAP_OFFSET(x) ((void *)(((unsigned long)(x) + VM_MAP_OFFSET) \
                                     & ~(VM_MAP_OFFSET-1)))
 
-void *vmalloc_start __read_mostly;
-EXPORT_SYMBOL(vmalloc_start);
+void *parisc_vmalloc_start __read_mostly;
+EXPORT_SYMBOL(parisc_vmalloc_start);
 
 #ifdef CONFIG_PA11
 unsigned long pcxl_dma_start __read_mostly;
@@ -456,6 +444,15 @@ unsigned long pcxl_dma_start __read_mostly;
 
 void __init mem_init(void)
 {
+       int codesize, reservedpages, datasize, initsize;
+
+       /* Do sanity checks on page table constants */
+       BUILD_BUG_ON(PTE_ENTRY_SIZE != sizeof(pte_t));
+       BUILD_BUG_ON(PMD_ENTRY_SIZE != sizeof(pmd_t));
+       BUILD_BUG_ON(PGD_ENTRY_SIZE != sizeof(pgd_t));
+       BUILD_BUG_ON(PAGE_SHIFT + BITS_PER_PTE + BITS_PER_PMD + BITS_PER_PGD
+                       > BITS_PER_LONG);
+
        high_memory = __va((max_pfn << PAGE_SHIFT));
 
 #ifndef CONFIG_DISCONTIGMEM
@@ -470,23 +467,82 @@ void __init mem_init(void)
        }
 #endif
 
-       printk(KERN_INFO "Memory: %luk available\n", num_physpages << (PAGE_SHIFT-10));
+       codesize = (unsigned long)_etext - (unsigned long)_text;
+       datasize = (unsigned long)_edata - (unsigned long)_etext;
+       initsize = (unsigned long)__init_end - (unsigned long)__init_begin;
+
+       reservedpages = 0;
+{
+       unsigned long pfn;
+#ifdef CONFIG_DISCONTIGMEM
+       int i;
+
+       for (i = 0; i < npmem_ranges; i++) {
+               for (pfn = node_start_pfn(i); pfn < node_end_pfn(i); pfn++) {
+                       if (PageReserved(pfn_to_page(pfn)))
+                               reservedpages++;
+               }
+       }
+#else /* !CONFIG_DISCONTIGMEM */
+       for (pfn = 0; pfn < max_pfn; pfn++) {
+               /*
+                * Only count reserved RAM pages
+                */
+               if (PageReserved(pfn_to_page(pfn)))
+                       reservedpages++;
+       }
+#endif
+}
 
 #ifdef CONFIG_PA11
        if (hppa_dma_ops == &pcxl_dma_ops) {
                pcxl_dma_start = (unsigned long)SET_MAP_OFFSET(MAP_START);
-               vmalloc_start = SET_MAP_OFFSET(pcxl_dma_start + PCXL_DMA_MAP_SIZE);
+               parisc_vmalloc_start = SET_MAP_OFFSET(pcxl_dma_start
+                                               + PCXL_DMA_MAP_SIZE);
        } else {
                pcxl_dma_start = 0;
-               vmalloc_start = SET_MAP_OFFSET(MAP_START);
+               parisc_vmalloc_start = SET_MAP_OFFSET(MAP_START);
        }
 #else
-       vmalloc_start = SET_MAP_OFFSET(MAP_START);
+       parisc_vmalloc_start = SET_MAP_OFFSET(MAP_START);
 #endif
 
+       printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
+               nr_free_pages() << (PAGE_SHIFT-10),
+               num_physpages << (PAGE_SHIFT-10),
+               codesize >> 10,
+               reservedpages << (PAGE_SHIFT-10),
+               datasize >> 10,
+               initsize >> 10
+       );
+
+#ifdef CONFIG_DEBUG_KERNEL /* double-sanity-check paranoia */
+       printk("virtual kernel memory layout:\n"
+              "    vmalloc : 0x%p - 0x%p   (%4ld MB)\n"
+              "    memory  : 0x%p - 0x%p   (%4ld MB)\n"
+              "      .init : 0x%p - 0x%p   (%4ld kB)\n"
+              "      .data : 0x%p - 0x%p   (%4ld kB)\n"
+              "      .text : 0x%p - 0x%p   (%4ld kB)\n",
+
+              (void*)VMALLOC_START, (void*)VMALLOC_END,
+              (VMALLOC_END - VMALLOC_START) >> 20,
+
+              __va(0), high_memory,
+              ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20,
+
+              __init_begin, __init_end,
+              ((unsigned long)__init_end - (unsigned long)__init_begin) >> 10,
+
+              _etext, _edata,
+              ((unsigned long)_edata - (unsigned long)_etext) >> 10,
+
+              _text, _etext,
+              ((unsigned long)_etext - (unsigned long)_text) >> 10);
+#endif
 }
 
 unsigned long *empty_zero_page __read_mostly;
+EXPORT_SYMBOL(empty_zero_page);
 
 void show_mem(void)
 {
@@ -495,8 +551,6 @@ void show_mem(void)
 
        printk(KERN_INFO "Mem-info:\n");
        show_free_areas();
-       printk(KERN_INFO "Free swap:     %6ldkB\n",
-                               nr_swap_pages<<(PAGE_SHIFT-10));
 #ifndef CONFIG_DISCONTIGMEM
        i = max_mapnr;
        while (i-- > 0) {
@@ -543,15 +597,18 @@ void show_mem(void)
 #ifdef CONFIG_DISCONTIGMEM
        {
                struct zonelist *zl;
-               int i, j, k;
+               int i, j;
 
                for (i = 0; i < npmem_ranges; i++) {
+                       zl = node_zonelist(i, 0);
                        for (j = 0; j < MAX_NR_ZONES; j++) {
-                               zl = NODE_DATA(i)->node_zonelists + j;
+                               struct zoneref *z;
+                               struct zone *zone;
 
                                printk("Zone list for zone %d on node %d: ", j, i);
-                               for (k = 0; zl->zones[k] != NULL; k++) 
-                                       printk("[%d/%s] ", zone_to_nid(zl->zones[k]), zl->zones[k]->name);
+                               for_each_zone_zonelist(zone, z, zl, j)
+                                       printk("[%d/%s] ", zone_to_nid(zone),
+                                                               zone->name);
                                printk("\n");
                        }
                }
@@ -578,7 +635,7 @@ static void __init map_pages(unsigned long start_vaddr, unsigned long start_padd
        extern const unsigned long fault_vector_20;
        extern void * const linux_gateway_page;
 
-       ro_start = __pa((unsigned long)&_text);
+       ro_start = __pa((unsigned long)_text);
        ro_end   = __pa((unsigned long)&data_start);
        fv_addr  = __pa((unsigned long)&fault_vector_20) & PAGE_MASK;
        gw_addr  = __pa((unsigned long)&linux_gateway_page) & PAGE_MASK;
@@ -811,9 +868,7 @@ void __init paging_init(void)
        for (i = 0; i < npmem_ranges; i++) {
                unsigned long zones_size[MAX_NR_ZONES] = { 0, };
 
-               /* We have an IOMMU, so all memory can go into a single
-                  ZONE_DMA zone. */
-               zones_size[ZONE_DMA] = pmem_ranges[i].pages;
+               zones_size[ZONE_NORMAL] = pmem_ranges[i].pages;
 
 #ifdef CONFIG_DISCONTIGMEM
                /* Need to initialize the pfnnid_map before we can initialize
@@ -828,7 +883,7 @@ void __init paging_init(void)
                }
 #endif
 
-               free_area_init_node(i, NODE_DATA(i), zones_size,
+               free_area_init_node(i, zones_size,
                                pmem_ranges[i].start_pfn, NULL);
        }
 }
@@ -836,7 +891,7 @@ void __init paging_init(void)
 #ifdef CONFIG_PA20
 
 /*
- * Currently, all PA20 chips have 18 bit protection id's, which is the
+ * Currently, all PA20 chips have 18 bit protection IDs, which is the
  * limiting factor (space ids are 32 bits).
  */
 
@@ -845,10 +900,10 @@ void __init paging_init(void)
 #else
 
 /*
- * Currently we have a one-to-one relationship between space id's and
- * protection id's. Older parisc chips (PCXS, PCXT, PCXL, PCXL2) only
- * support 15 bit protection id's, so that is the limiting factor.
- * PCXT' has 18 bit protection id's, but only 16 bit spaceids, so it's
+ * Currently we have a one-to-one relationship between space IDs and
+ * protection IDs. Older parisc chips (PCXS, PCXT, PCXL, PCXL2) only
+ * support 15 bit protection IDs, so that is the limiting factor.
+ * PCXT' has 18 bit protection IDs, but only 16 bit spaceids, so it's
  * probably not worth the effort for a special case here.
  */
 
@@ -993,7 +1048,7 @@ void flush_tlb_all(void)
            do_recycle++;
        }
        spin_unlock(&sid_lock);
-       on_each_cpu(flush_tlb_all_local, NULL, 1, 1);
+       on_each_cpu(flush_tlb_all_local, NULL, 1);
        if (do_recycle) {
            spin_lock(&sid_lock);
            recycle_sids(recycle_ndirty,recycle_dirty_array);