linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / parisc / mm / init.c
index 871d7df..7847ca1 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/initrd.h>
 #include <linux/swap.h>
 #include <linux/unistd.h>
+#include <linux/nodemask.h>    /* for node_online_map */
+#include <linux/pagemap.h>     /* for release_pages and page_cache_release */
 
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
@@ -34,9 +36,9 @@ 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];
-bootmem_data_t bmem_data[MAX_NUMNODES];
-unsigned char pfnnid_map[PFNNID_MAP_MAX];
+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
 
 static struct resource data_resource = {
@@ -56,16 +58,14 @@ static struct resource pdcdata_resource = {
        .flags  = IORESOURCE_BUSY | IORESOURCE_MEM,
 };
 
-static struct resource sysram_resources[MAX_PHYSMEM_RANGES];
-
-static unsigned long max_pfn;
+static struct resource sysram_resources[MAX_PHYSMEM_RANGES] __read_mostly;
 
 /* The following array is initialized from the firmware specific
  * information retrieved in kernel/inventory.c.
  */
 
-physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES];
-int npmem_ranges;
+physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly;
+int npmem_ranges __read_mostly;
 
 #ifdef __LP64__
 #define MAX_MEM         (~0UL)
@@ -73,7 +73,7 @@ int npmem_ranges;
 #define MAX_MEM         (3584U*1024U*1024U)
 #endif /* !__LP64__ */
 
-static unsigned long mem_limit = MAX_MEM;
+static unsigned long mem_limit __read_mostly = MAX_MEM;
 
 static void __init mem_limit_func(void)
 {
@@ -179,7 +179,7 @@ static void __init setup_bootmem(void)
 
                        size = (pmem_ranges[i].pages << PAGE_SHIFT);
                        start = (pmem_ranges[i].start_pfn << PAGE_SHIFT);
-                       printk(KERN_INFO "%2d) Start 0x%016lx End 0x%016lx Size %6ld Mb\n",
+                       printk(KERN_INFO "%2d) Start 0x%016lx End 0x%016lx Size %6ld MB\n",
                                i,start, start + (size - 1), size >> 20);
                }
        }
@@ -212,7 +212,7 @@ static void __init setup_bootmem(void)
 
                rsize = pmem_ranges[i].pages << PAGE_SHIFT;
                if ((mem_max + rsize) > mem_limit) {
-                       printk(KERN_WARNING "Memory truncated to %ld Mb\n", mem_limit >> 20);
+                       printk(KERN_WARNING "Memory truncated to %ld MB\n", mem_limit >> 20);
                        if (mem_max == mem_limit)
                                npmem_ranges = i;
                        else {
@@ -228,7 +228,7 @@ static void __init setup_bootmem(void)
                mem_max += rsize;
        }
 
-       printk(KERN_INFO "Total Memory: %ld Mb\n",mem_max >> 20);
+       printk(KERN_INFO "Total Memory: %ld MB\n",mem_max >> 20);
 
 #ifndef CONFIG_DISCONTIGMEM
        /* Merge the ranges, keeping track of the holes */
@@ -268,8 +268,6 @@ static void __init setup_bootmem(void)
        }
        memset(pfnnid_map, 0xff, sizeof(pfnnid_map));
 
-       numnodes = npmem_ranges;
-
        for (i = 0; i < npmem_ranges; i++)
                node_set_online(i);
 #endif
@@ -302,6 +300,13 @@ static void __init setup_bootmem(void)
                        max_pfn = start_pfn + npages;
        }
 
+       /* IOMMU is always used to access "high mem" on those boxes
+        * that can support enough mem that a PCI device couldn't
+        * directly DMA to any physical addresses.
+        * ISA DMA support will need to revisit this.
+        */
+       max_low_pfn = max_pfn;
+
        if ((bootmap_pfn - bootmap_start_pfn) != bootmap_pages) {
                printk(KERN_WARNING "WARNING! bootmap sizing is messed up!\n");
                BUG();
@@ -366,17 +371,11 @@ static void __init setup_bootmem(void)
 
 void free_initmem(void)
 {
-       /* FIXME: */
-#if 0
-       printk(KERN_INFO "NOT FREEING INITMEM (%dk)\n",
-                       (&__init_end - &__init_begin) >> 10);
-       return;
-#else
        unsigned long addr;
        
        printk(KERN_INFO "Freeing unused kernel memory: ");
 
-#if 1
+#ifdef CONFIG_DEBUG_KERNEL
        /* Attempt to catch anyone trying to execute code here
         * by filling the page with BRK insns.
         * 
@@ -409,9 +408,21 @@ void free_initmem(void)
        pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE);
        
        printk("%luk freed\n", (unsigned long)(&__init_end - &__init_begin) >> 10);
-#endif
 }
 
+
+#ifdef CONFIG_DEBUG_RODATA
+void mark_rodata_ro(void)
+{
+       extern char __start_rodata, __end_rodata;
+       /* rodata memory was already mapped with KERNEL_RO access rights by
+           pagetable_init() and map_pages(). No need to do additional stuff here */
+       printk (KERN_INFO "Write protecting the kernel read-only data: %luk\n",
+               (unsigned long)(&__end_rodata - &__start_rodata) >> 10);
+}
+#endif
+
+
 /*
  * Just an arbitrary offset to serve as a "hole" between mapping areas
  * (between top of physical memory and a potential pcxl dma mapping
@@ -433,11 +444,11 @@ void free_initmem(void)
 #define SET_MAP_OFFSET(x) ((void *)(((unsigned long)(x) + VM_MAP_OFFSET) \
                                     & ~(VM_MAP_OFFSET-1)))
 
-void *vmalloc_start;
+void *vmalloc_start __read_mostly;
 EXPORT_SYMBOL(vmalloc_start);
 
 #ifdef CONFIG_PA11
-unsigned long pcxl_dma_start;
+unsigned long pcxl_dma_start __read_mostly;
 #endif
 
 void __init mem_init(void)
@@ -446,7 +457,6 @@ void __init mem_init(void)
 
 #ifndef CONFIG_DISCONTIGMEM
        max_mapnr = page_to_pfn(virt_to_page(high_memory - 1)) + 1;
-       mem_map = zone_table[ZONE_DMA]->zone_mem_map;
        totalram_pages += free_all_bootmem();
 #else
        {
@@ -473,12 +483,7 @@ void __init mem_init(void)
 
 }
 
-int do_check_pgt_cache(int low, int high)
-{
-       return 0;
-}
-
-unsigned long *empty_zero_page;
+unsigned long *empty_zero_page __read_mostly;
 
 void show_mem(void)
 {
@@ -508,8 +513,10 @@ void show_mem(void)
 
                for (j = node_start_pfn(i); j < node_end_pfn(i); j++) {
                        struct page *p;
+                       unsigned long flags;
 
-                       p = node_mem_map(i) + j - node_start_pfn(i);
+                       pgdat_resize_lock(NODE_DATA(i), &flags);
+                       p = nid_page_nr(i, j) - node_start_pfn(i);
 
                        total++;
                        if (PageReserved(p))
@@ -520,6 +527,7 @@ void show_mem(void)
                                free++;
                        else
                                shared += page_count(p) - 1;
+                       pgdat_resize_unlock(NODE_DATA(i), &flags);
                }
        }
 #endif
@@ -683,7 +691,7 @@ static void __init pagetable_init(void)
 
 #ifdef CONFIG_BLK_DEV_INITRD
        if (initrd_end && initrd_end > mem_limit) {
-               printk("initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end);
+               printk(KERN_INFO "initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end);
                map_pages(initrd_start, __pa(initrd_start),
                        initrd_end - initrd_start, PAGE_KERNEL);
        }
@@ -750,7 +758,7 @@ map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm)
 #if PTRS_PER_PMD == 1
        pmd = (pmd_t *)__pa(pg_dir);
 #else
-       pmd = (pmd_t *) (PAGE_MASK & pgd_val(*pg_dir));
+       pmd = (pmd_t *) pgd_address(*pg_dir);
 
        /*
         * pmd is physical at this point
@@ -761,7 +769,7 @@ map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm)
                pmd = (pmd_t *) __pa(pmd);
        }
 
-       pgd_val(*pg_dir) = _PAGE_TABLE | (unsigned long) pmd;
+       __pgd_val_set(*pg_dir, PxD_FLAG_PRESENT | PxD_FLAG_VALID | (unsigned long) pmd);
 #endif
        /* now change pmd to kernel virtual addresses */
 
@@ -771,11 +779,11 @@ map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm)
         * pg_table is physical at this point
         */
 
-       pg_table = (pte_t *) (PAGE_MASK & pmd_val(*pmd));
+       pg_table = (pte_t *) pmd_address(*pmd);
        if (!pg_table)
                pg_table = (pte_t *) __pa(get_zeroed_page(GFP_KERNEL));
 
-       pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) pg_table;
+       __pmd_val_set(*pmd, PxD_FLAG_PRESENT | PxD_FLAG_VALID | (unsigned long) pg_table);
 
        /* now change pg_table to kernel virtual addresses */
 
@@ -785,8 +793,6 @@ map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm)
 EXPORT_SYMBOL(map_hpux_gateway_page);
 #endif
 
-extern void flush_tlb_all_local(void);
-
 void __init paging_init(void)
 {
        int i;
@@ -795,7 +801,7 @@ void __init paging_init(void)
        pagetable_init();
        gateway_init();
        flush_cache_all_local(); /* start with known state */
-       flush_tlb_all_local();
+       flush_tlb_all_local(NULL);
 
        for (i = 0; i < npmem_ranges; i++) {
                unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0 };
@@ -804,19 +810,21 @@ void __init paging_init(void)
                   ZONE_DMA zone. */
                zones_size[ZONE_DMA] = pmem_ranges[i].pages;
 
-               free_area_init_node(i,NODE_DATA(i),NULL,zones_size,
-                               pmem_ranges[i].start_pfn, 0);
-
 #ifdef CONFIG_DISCONTIGMEM
+               /* Need to initialize the pfnnid_map before we can initialize
+                  the zone */
                {
                    int j;
-                   for (j = (node_start_pfn(i) >> PFNNID_SHIFT);
-                        j <= (node_end_pfn(i) >> PFNNID_SHIFT);
+                   for (j = (pmem_ranges[i].start_pfn >> PFNNID_SHIFT);
+                        j <= ((pmem_ranges[i].start_pfn + pmem_ranges[i].pages) >> PFNNID_SHIFT);
                         j++) {
                        pfnnid_map[j] = i;
                    }
                }
 #endif
+
+               free_area_init_node(i, NODE_DATA(i), zones_size,
+                               pmem_ranges[i].start_pfn, NULL);
        }
 }
 
@@ -852,7 +860,7 @@ static unsigned long space_id_index;
 static unsigned long free_space_ids = NR_SPACE_IDS - 1;
 static unsigned long dirty_space_ids = 0;
 
-static spinlock_t sid_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sid_lock);
 
 unsigned long alloc_sid(void)
 {
@@ -984,7 +992,7 @@ void flush_tlb_all(void)
            do_recycle++;
        }
        spin_unlock(&sid_lock);
-       on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
+       on_each_cpu(flush_tlb_all_local, NULL, 1, 1);
        if (do_recycle) {
            spin_lock(&sid_lock);
            recycle_sids(recycle_ndirty,recycle_dirty_array);
@@ -996,7 +1004,7 @@ void flush_tlb_all(void)
 void flush_tlb_all(void)
 {
        spin_lock(&sid_lock);
-       flush_tlb_all_local();
+       flush_tlb_all_local(NULL);
        recycle_sids();
        spin_unlock(&sid_lock);
 }