Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / sh / mm / init.c
index 95b5368..77b4a83 100644 (file)
@@ -3,7 +3,7 @@
  *  linux/arch/sh/mm/init.c
  *
  *  Copyright (C) 1999  Niibe Yutaka
- *  Copyright (C) 2002  Paul Mundt
+ *  Copyright (C) 2002, 2004  Paul Mundt
  *
  *  Based on linux/arch/i386/mm/init.c:
  *   Copyright (C) 1995  Linus Torvalds
@@ -51,11 +51,6 @@ unsigned long mmu_context_cache = NO_CONTEXT;
 #define MAX_LOW_PFN    (NODE_DATA(0)->bdata->node_low_pfn)
 #endif
 
-#ifdef CONFIG_DISCONTIGMEM
-pg_data_t discontig_page_data[MAX_NUMNODES];
-bootmem_data_t discontig_node_bdata[MAX_NUMNODES];
-#endif
-
 void (*copy_page)(void *from, void *to);
 void (*clear_page)(void *to);
 
@@ -66,7 +61,7 @@ void show_mem(void)
 
        printk("Mem-info:\n");
        show_free_areas();
-       printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+       printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
        i = max_mapnr;
        while (i-- > 0) {
                total++;
@@ -83,6 +78,66 @@ void show_mem(void)
        printk("%d pages swap cached\n",cached);
 }
 
+static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
+{
+       pgd_t *pgd;
+       pmd_t *pmd;
+       pte_t *pte;
+
+       pgd = swapper_pg_dir + pgd_index(addr);
+       if (pgd_none(*pgd)) {
+               pgd_ERROR(*pgd);
+               return;
+       }
+
+       pmd = pmd_offset(pgd, addr);
+       if (pmd_none(*pmd)) {
+               pte = (pte_t *)get_zeroed_page(GFP_ATOMIC);
+               set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
+               if (pte != pte_offset_kernel(pmd, 0)) {
+                       pmd_ERROR(*pmd);
+                       return;
+               }
+       }
+
+       pte = pte_offset_kernel(pmd, addr);
+       if (!pte_none(*pte)) {
+               pte_ERROR(*pte);
+               return;
+       }
+
+       set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
+
+       __flush_tlb_page(get_asid(), addr);
+}
+
+/*
+ * As a performance optimization, other platforms preserve the fixmap mapping
+ * across a context switch, we don't presently do this, but this could be done
+ * in a similar fashion as to the wired TLB interface that sh64 uses (by way
+ * of the memorry mapped UTLB configuration) -- this unfortunately forces us to
+ * give up a TLB entry for each mapping we want to preserve. While this may be
+ * viable for a small number of fixmaps, it's not particularly useful for
+ * everything and needs to be carefully evaluated. (ie, we may want this for
+ * the vsyscall page).
+ *
+ * XXX: Perhaps add a _PAGE_WIRED flag or something similar that we can pass
+ * in at __set_fixmap() time to determine the appropriate behavior to follow.
+ *
+ *                                      -- PFM.
+ */
+void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
+{
+       unsigned long address = __fix_to_virt(idx);
+
+       if (idx >= __end_of_fixed_addresses) {
+               BUG();
+               return;
+       }
+
+       set_pte_phys(address, phys, prot);
+}
+
 /* References to section boundaries */
 
 extern char _text, _etext, _edata, __bss_start, _end;
@@ -154,19 +209,8 @@ void __init paging_init(void)
         */
        disable_mmu();
 #endif
-
-       free_area_init_node(0, NODE_DATA(0), 0, zones_size, __MEMORY_START >> PAGE_SHIFT, 0);
-       /* XXX: MRB-remove - this doesn't seem sane, should this be done somewhere else ?*/
-       mem_map = NODE_DATA(0)->node_mem_map;
-
-#ifdef CONFIG_DISCONTIGMEM
-       /*
-        * And for discontig, do some more fixups on the zone sizes..
-        */
-       zones_size[ZONE_DMA] = __MEMORY_SIZE_2ND >> PAGE_SHIFT;
-       zones_size[ZONE_NORMAL] = 0;
-       free_area_init_node(1, NODE_DATA(1), 0, zones_size, __MEMORY_START_2ND >> PAGE_SHIFT, 0);
-#endif
+       NODE_DATA(0)->node_mem_map = NULL;
+       free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0);
 }
 
 void __init mem_init(void)
@@ -190,7 +234,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.
         */
@@ -199,9 +243,6 @@ void __init mem_init(void)
 
        /* this will put all low memory onto the freelists */
        totalram_pages += free_all_bootmem_node(NODE_DATA(0));
-#ifdef CONFIG_DISCONTIGMEM
-       totalram_pages += free_all_bootmem_node(NODE_DATA(1));
-#endif
        reservedpages = 0;
        for (tmp = 0; tmp < num_physpages; tmp++)
                /*
@@ -228,11 +269,11 @@ void __init mem_init(void)
 void free_initmem(void)
 {
        unsigned long addr;
-       
+
        addr = (unsigned long)(&__init_begin);
        for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(addr));
-               set_page_count(virt_to_page(addr), 1);
+               init_page_count(virt_to_page(addr));
                free_page(addr);
                totalram_pages++;
        }
@@ -245,7 +286,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
        unsigned long p;
        for (p = start; p < end; p += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(p));
-               set_page_count(virt_to_page(p), 1);
+               init_page_count(virt_to_page(p));
                free_page(p);
                totalram_pages++;
        }