#include <linux/acpi.h>
 #include <linux/kallsyms.h>
 #include <linux/edd.h>
+#include <linux/mmzone.h>
+
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 }
 
 #ifndef CONFIG_NUMA
-static void __init contig_initmem_init(void)
+static void __init
+contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
 {
-        unsigned long bootmap_size, bootmap; 
-        bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
-        bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
-        if (bootmap == -1L) 
-                panic("Cannot find bootmem map of size %ld\n",bootmap_size);
-        bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
-        e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT);
-        reserve_bootmem(bootmap, bootmap_size);
+       unsigned long bootmap_size, bootmap;
+
+       memory_present(0, start_pfn, end_pfn);
+       bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
+       bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
+       if (bootmap == -1L)
+               panic("Cannot find bootmem map of size %ld\n",bootmap_size);
+       bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
+       e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT);
+       reserve_bootmem(bootmap, bootmap_size);
 } 
 #endif
 
 #ifdef CONFIG_NUMA
        numa_initmem_init(0, end_pfn); 
 #else
-       contig_initmem_init(); 
+       contig_initmem_init(0, end_pfn);
 #endif
 
        /* Reserve direct mapping */
                }
        }
 #endif
+
+       sparse_init();
        paging_init();
 
        check_ioapic();
 
        return -1; 
 }
 
+#ifdef CONFIG_SPARSEMEM
+int early_pfn_to_nid(unsigned long pfn)
+{
+       return phys_to_nid(pfn << PAGE_SHIFT);
+}
+#endif
+
 /* Initialize bootmem allocator for a node */
 void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
 { 
        start_pfn = start >> PAGE_SHIFT;
        end_pfn = end >> PAGE_SHIFT;
 
+       memory_present(nodeid, start_pfn, end_pfn);
        nodedata_phys = find_e820_area(start, end, pgdat_size); 
        if (nodedata_phys == -1L) 
                panic("Cannot find memory pgdat in node %d\n", nodeid);
 
--- /dev/null
+#ifndef _ASM_X86_64_SPARSEMEM_H
+#define _ASM_X86_64_SPARSEMEM_H 1
+
+#ifdef CONFIG_SPARSEMEM
+
+/*
+ * generic non-linear memory support:
+ *
+ * 1) we will not split memory into more chunks than will fit into the flags
+ *    field of the struct page
+ *
+ * SECTION_SIZE_BITS           2^n: size of each section
+ * MAX_PHYSADDR_BITS           2^n: max size of physical address space
+ * MAX_PHYSMEM_BITS            2^n: how much memory we can have in that space
+ *
+ */
+
+#define SECTION_SIZE_BITS      27 /* matt - 128 is convenient right now */
+#define MAX_PHYSADDR_BITS      40
+#define MAX_PHYSMEM_BITS       40
+
+extern int early_pfn_to_nid(unsigned long pfn);
+
+#endif /* CONFIG_SPARSEMEM */
+
+#endif /* _ASM_X86_64_SPARSEMEM_H */