]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/sh/mm/init.c
Merge master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6-omap-h63xx.git] / arch / sh / mm / init.c
index 82b68c789a5f28c30e430fe9913654a341360b1c..53dde06073627d693d431fd308e6c647d87da30e 100644 (file)
@@ -23,9 +23,7 @@
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 pgd_t swapper_pg_dir[PTRS_PER_PGD];
-
-void (*copy_page)(void *from, void *to);
-void (*clear_page)(void *to);
+unsigned long cached_to_uncached = 0;
 
 void show_mem(void)
 {
@@ -102,7 +100,8 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
 
        set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
 
-       flush_tlb_one(get_asid(), addr);
+       if (cached_to_uncached)
+               flush_tlb_one(get_asid(), addr);
 }
 
 /*
@@ -131,6 +130,37 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
 
        set_pte_phys(address, phys, prot);
 }
+
+void __init page_table_range_init(unsigned long start, unsigned long end,
+                                        pgd_t *pgd_base)
+{
+       pgd_t *pgd;
+       pud_t *pud;
+       pmd_t *pmd;
+       int pgd_idx;
+       unsigned long vaddr;
+
+       vaddr = start & PMD_MASK;
+       end = (end + PMD_SIZE - 1) & PMD_MASK;
+       pgd_idx = pgd_index(vaddr);
+       pgd = pgd_base + pgd_idx;
+
+       for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
+               BUG_ON(pgd_none(*pgd));
+               pud = pud_offset(pgd, 0);
+               BUG_ON(pud_none(*pud));
+               pmd = pmd_offset(pud, 0);
+
+               if (!pmd_present(*pmd)) {
+                       pte_t *pte_table;
+                       pte_table = (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
+                       memset(pte_table, 0, PAGE_SIZE);
+                       pmd_populate_kernel(&init_mm, pmd, pte_table);
+               }
+
+               vaddr += PMD_SIZE;
+       }
+}
 #endif /* CONFIG_MMU */
 
 /*
@@ -150,6 +180,11 @@ void __init paging_init(void)
         * check for a null value. */
        set_TTB(swapper_pg_dir);
 
+       /* Populate the relevant portions of swapper_pg_dir so that
+        * we can use the fixmap entries without calling kmalloc.
+        * pte's will be filled in by __set_fixmap(). */
+       page_table_range_init(FIXADDR_START, FIXADDR_TOP, swapper_pg_dir);
+
        memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
 
        for_each_online_node(nid) {
@@ -167,9 +202,24 @@ void __init paging_init(void)
        }
 
        free_area_init_nodes(max_zone_pfns);
+
+#ifdef CONFIG_SUPERH32
+       /* Set up the uncached fixmap */
+       set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start));
+
+#ifdef CONFIG_29BIT
+       /*
+        * Handle trivial transitions between cached and uncached
+        * segments, making use of the 1:1 mapping relationship in
+        * 512MB lowmem.
+        */
+       cached_to_uncached = P2SEG - P1SEG;
+#endif
+#endif
 }
 
 static struct kcore_list kcore_mem, kcore_vmalloc;
+int after_bootmem = 0;
 
 void __init mem_init(void)
 {
@@ -202,17 +252,7 @@ void __init mem_init(void)
        memset(empty_zero_page, 0, PAGE_SIZE);
        __flush_wback_region(empty_zero_page, PAGE_SIZE);
 
-       /*
-        * Setup wrappers for copy/clear_page(), these will get overridden
-        * later in the boot process if a better method is available.
-        */
-#ifdef CONFIG_MMU
-       copy_page = copy_page_slow;
-       clear_page = clear_page_slow;
-#else
-       copy_page = copy_page_nommu;
-       clear_page = clear_page_nommu;
-#endif
+       after_bootmem = 1;
 
        codesize =  (unsigned long) &_etext - (unsigned long) &_text;
        datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
@@ -288,18 +328,12 @@ int arch_add_memory(int nid, u64 start, u64 size)
        /* We only have ZONE_NORMAL, so this is easy.. */
        ret = __add_pages(pgdat->node_zones + ZONE_NORMAL, start_pfn, nr_pages);
        if (unlikely(ret))
-               printk("%s: Failed, __add_pages() == %d\n", __FUNCTION__, ret);
+               printk("%s: Failed, __add_pages() == %d\n", __func__, ret);
 
        return ret;
 }
 EXPORT_SYMBOL_GPL(arch_add_memory);
 
-int remove_memory(u64 start, u64 size)
-{
-       return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(remove_memory);
-
 #ifdef CONFIG_NUMA
 int memory_add_physaddr_to_nid(u64 addr)
 {