linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / powerpc / mm / init_64.c
index 3ff3746..81cfb0c 100644 (file)
@@ -22,6 +22,7 @@
 
 #undef DEBUG
 
+#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -40,7 +41,6 @@
 #include <linux/idr.h>
 #include <linux/nodemask.h>
 #include <linux/module.h>
-#include <linux/poison.h>
 
 #include <asm/pgalloc.h>
 #include <asm/page.h>
 /* max amount of RAM to use */
 unsigned long __max_memory;
 
+/* info on what we think the IO hole is */
+unsigned long  io_hole_start;
+unsigned long  io_hole_size;
+
+/*
+ * Do very early mm setup.
+ */
+void __init mm_init_ppc64(void)
+{
+#ifndef CONFIG_PPC_ISERIES
+       unsigned long i;
+#endif
+
+       ppc64_boot_msg(0x100, "MM Init");
+
+       /* This is the story of the IO hole... please, keep seated,
+        * unfortunately, we are out of oxygen masks at the moment.
+        * So we need some rough way to tell where your big IO hole
+        * is. On pmac, it's between 2G and 4G, on POWER3, it's around
+        * that area as well, on POWER4 we don't have one, etc...
+        * We need that as a "hint" when sizing the TCE table on POWER3
+        * So far, the simplest way that seem work well enough for us it
+        * to just assume that the first discontinuity in our physical
+        * RAM layout is the IO hole. That may not be correct in the future
+        * (and isn't on iSeries but then we don't care ;)
+        */
+
+#ifndef CONFIG_PPC_ISERIES
+       for (i = 1; i < lmb.memory.cnt; i++) {
+               unsigned long base, prevbase, prevsize;
+
+               prevbase = lmb.memory.region[i-1].base;
+               prevsize = lmb.memory.region[i-1].size;
+               base = lmb.memory.region[i].base;
+               if (base > (prevbase + prevsize)) {
+                       io_hole_start = prevbase + prevsize;
+                       io_hole_size = base  - (prevbase + prevsize);
+                       break;
+               }
+       }
+#endif /* CONFIG_PPC_ISERIES */
+       if (io_hole_start)
+               printk("IO Hole assumed to be %lx -> %lx\n",
+                      io_hole_start, io_hole_start + io_hole_size - 1);
+
+       ppc64_boot_msg(0x100, "MM Init Done");
+}
+
 void free_initmem(void)
 {
        unsigned long addr;
 
        addr = (unsigned long)__init_begin;
        for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
-               memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
+               memset((void *)addr, 0xcc, PAGE_SIZE);
                ClearPageReserved(virt_to_page(addr));
-               init_page_count(virt_to_page(addr));
+               set_page_count(virt_to_page(addr), 1);
                free_page(addr);
                totalram_pages++;
        }
@@ -107,7 +155,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
                printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
        for (; start < end; start += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(start));
-               init_page_count(virt_to_page(start));
+               set_page_count(virt_to_page(start), 1);
                free_page(start);
                totalram_pages++;
        }
@@ -162,14 +210,7 @@ static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
 };
 #endif /* CONFIG_PPC_64K_PAGES */
 
-#ifdef CONFIG_HUGETLB_PAGE
-/* Hugepages need one extra cache, initialized in hugetlbpage.c.  We
- * can't put into the tables above, because HPAGE_SHIFT is not compile
- * time constant. */
-kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)+1];
-#else
 kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)];
-#endif
 
 void pgtable_cache_init(void)
 {