]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/mm/init.c
[ARM] Separate page table manipulation code from bootmem initialisation
[linux-2.6-omap-h63xx.git] / arch / arm / mm / init.c
index 9ea1f87a7079b863ee4d061103ef46b2aa00fa9b..83145d1d338997f02cd319ec5ef42f38ccc80269 100644 (file)
@@ -7,7 +7,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
@@ -26,7 +25,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#define TABLE_SIZE     (2 * PTRS_PER_PTE * sizeof(pte_t))
+#include "mm.h"
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
@@ -47,6 +46,11 @@ static struct meminfo meminfo __initdata = { 0, };
  */
 struct page *empty_zero_page;
 
+/*
+ * The pmd table for the upper-most set of pages.
+ */
+pmd_t *top_pmd;
+
 void show_mem(void)
 {
        int free = 0, total = 0, reserved = 0;
@@ -86,16 +90,6 @@ void show_mem(void)
        printk("%d pages swap cached\n", cached);
 }
 
-static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
-{
-       return pmd_offset(pgd, virt);
-}
-
-static inline pmd_t *pmd_off_k(unsigned long virt)
-{
-       return pmd_off(pgd_offset_k(virt), virt);
-}
-
 #define for_each_nodebank(iter,mi,no)                  \
        for (iter = 0; iter < mi->nr_banks; iter++)     \
                if (mi->bank[iter].node == no)
@@ -232,8 +226,43 @@ static __init void reserve_node_zero(pg_data_t *pgdat)
                reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size);
 }
 
-void __init build_mem_type_table(void);
-void __init create_mapping(struct map_desc *md);
+static inline void prepare_page_table(struct meminfo *mi)
+{
+       unsigned long addr;
+
+       /*
+        * Clear out all the mappings below the kernel image.
+        */
+       for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE)
+               pmd_clear(pmd_off_k(addr));
+
+#ifdef CONFIG_XIP_KERNEL
+       /* The XIP kernel is mapped in the module area -- skip over it */
+       addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK;
+#endif
+       for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE)
+               pmd_clear(pmd_off_k(addr));
+
+       /*
+        * Clear out all the kernel space mappings, except for the first
+        * memory bank, up to the end of the vmalloc region.
+        */
+       for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size);
+            addr < VMALLOC_END; addr += PGDIR_SIZE)
+               pmd_clear(pmd_off_k(addr));
+}
+
+static inline void map_memory_bank(struct membank *bank)
+{
+       struct map_desc map;
+
+       map.pfn = __phys_to_pfn(bank->start);
+       map.virtual = __phys_to_virt(bank->start);
+       map.length = bank->size;
+       map.type = MT_MEMORY;
+
+       create_mapping(&map);
+}
 
 static unsigned long __init
 bootmem_init_node(int node, int initrd_node, struct meminfo *mi)
@@ -251,23 +280,18 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi)
         * Calculate the pfn range, and map the memory banks for this node.
         */
        for_each_nodebank(i, mi, node) {
+               struct membank *bank = &mi->bank[i];
                unsigned long start, end;
-               struct map_desc map;
 
-               start = mi->bank[i].start >> PAGE_SHIFT;
-               end = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT;
+               start = bank->start >> PAGE_SHIFT;
+               end = (bank->start + bank->size) >> PAGE_SHIFT;
 
                if (start_pfn > start)
                        start_pfn = start;
                if (end_pfn < end)
                        end_pfn = end;
 
-               map.pfn = __phys_to_pfn(mi->bank[i].start);
-               map.virtual = __phys_to_virt(mi->bank[i].start);
-               map.length = mi->bank[i].size;
-               map.type = MT_MEMORY;
-
-               create_mapping(&map);
+               map_memory_bank(bank);
        }
 
        /*
@@ -351,7 +375,7 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi)
 
 static void __init bootmem_init(struct meminfo *mi)
 {
-       unsigned long addr, memend_pfn = 0;
+       unsigned long memend_pfn = 0;
        int node, initrd_node, i;
 
        /*
@@ -363,25 +387,7 @@ static void __init bootmem_init(struct meminfo *mi)
 
        memcpy(&meminfo, mi, sizeof(meminfo));
 
-       /*
-        * Clear out all the mappings below the kernel image.
-        */
-       for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE)
-               pmd_clear(pmd_off_k(addr));
-#ifdef CONFIG_XIP_KERNEL
-       /* The XIP kernel is mapped in the module area -- skip over it */
-       addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK;
-#endif
-       for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE)
-               pmd_clear(pmd_off_k(addr));
-
-       /*
-        * Clear out all the kernel space mappings, except for the first
-        * memory bank, up to the end of the vmalloc region.
-        */
-       for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size);
-            addr < VMALLOC_END; addr += PGDIR_SIZE)
-               pmd_clear(pmd_off_k(addr));
+       prepare_page_table(mi);
 
        /*
         * Locate which node contains the ramdisk image, if any.
@@ -443,9 +449,9 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
         * It is always first in the modulearea.
         */
 #ifdef CONFIG_XIP_KERNEL
-       map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PGDIR_MASK);
+       map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
        map.virtual = MODULE_START;
-       map.length = ((unsigned long)&_etext - map.virtual + ~PGDIR_MASK) & PGDIR_MASK;
+       map.length = ((unsigned long)&_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK;
        map.type = MT_ROM;
        create_mapping(&map);
 #endif