]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86_64/kernel/e820.c
Pull bugzilla-3774 into release branch
[linux-2.6-omap-h63xx.git] / arch / x86_64 / kernel / e820.c
index 13c6c37610e029978e13f829018600b21ed5ca42..0f4d5e209e9b7b015b1f99d55af809f4b80075bd 100644 (file)
@@ -193,37 +193,6 @@ unsigned long __init e820_end_of_ram(void)
        return end_pfn; 
 }
 
-/*
- * Find the hole size in the range.
- */
-unsigned long __init e820_hole_size(unsigned long start, unsigned long end)
-{
-       unsigned long ram = 0;
-       int i;
-
-       for (i = 0; i < e820.nr_map; i++) {
-               struct e820entry *ei = &e820.map[i];
-               unsigned long last, addr;
-
-               if (ei->type != E820_RAM ||
-                   ei->addr+ei->size <= start ||
-                   ei->addr >= end)
-                       continue;
-
-               addr = round_up(ei->addr, PAGE_SIZE);
-               if (addr < start)
-                       addr = start;
-
-               last = round_down(ei->addr + ei->size, PAGE_SIZE);
-               if (last >= end)
-                       last = end;
-
-               if (last > addr)
-                       ram += last - addr;
-       }
-       return ((end - start) - ram);
-}
-
 /*
  * Mark e820 reserved areas as busy for the resource manager.
  */
@@ -289,47 +258,61 @@ void __init e820_mark_nosave_regions(void)
        }
 }
 
-/* Walk the e820 map and register active regions within a node */
-void __init
-e820_register_active_regions(int nid, unsigned long start_pfn,
-                                                       unsigned long end_pfn)
+/*
+ * Finds an active region in the address range from start_pfn to end_pfn and
+ * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
+ */
+static int __init e820_find_active_region(const struct e820entry *ei,
+                                         unsigned long start_pfn,
+                                         unsigned long end_pfn,
+                                         unsigned long *ei_startpfn,
+                                         unsigned long *ei_endpfn)
 {
-       int i;
-       unsigned long ei_startpfn, ei_endpfn;
-       for (i = 0; i < e820.nr_map; i++) {
-               struct e820entry *ei = &e820.map[i];
-               ei_startpfn = round_up(ei->addr, PAGE_SIZE) >> PAGE_SHIFT;
-               ei_endpfn = round_down(ei->addr + ei->size, PAGE_SIZE)
-                                                               >> PAGE_SHIFT;
+       *ei_startpfn = round_up(ei->addr, PAGE_SIZE) >> PAGE_SHIFT;
+       *ei_endpfn = round_down(ei->addr + ei->size, PAGE_SIZE) >> PAGE_SHIFT;
 
-               /* Skip map entries smaller than a page */
-               if (ei_startpfn >= ei_endpfn)
-                       continue;
+       /* Skip map entries smaller than a page */
+       if (*ei_startpfn >= *ei_endpfn)
+               return 0;
 
-               /* Check if end_pfn_map should be updated */
-               if (ei->type != E820_RAM && ei_endpfn > end_pfn_map)
-                       end_pfn_map = ei_endpfn;
+       /* Check if end_pfn_map should be updated */
+       if (ei->type != E820_RAM && *ei_endpfn > end_pfn_map)
+               end_pfn_map = *ei_endpfn;
 
-               /* Skip if map is outside the node */
-               if (ei->type != E820_RAM ||
-                               ei_endpfn <= start_pfn ||
-                               ei_startpfn >= end_pfn)
-                       continue;
+       /* Skip if map is outside the node */
+       if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
+                                   *ei_startpfn >= end_pfn)
+               return 0;
 
-               /* Check for overlaps */
-               if (ei_startpfn < start_pfn)
-                       ei_startpfn = start_pfn;
-               if (ei_endpfn > end_pfn)
-                       ei_endpfn = end_pfn;
+       /* Check for overlaps */
+       if (*ei_startpfn < start_pfn)
+               *ei_startpfn = start_pfn;
+       if (*ei_endpfn > end_pfn)
+               *ei_endpfn = end_pfn;
 
-               /* Obey end_user_pfn to save on memmap */
-               if (ei_startpfn >= end_user_pfn)
-                       continue;
-               if (ei_endpfn > end_user_pfn)
-                       ei_endpfn = end_user_pfn;
+       /* Obey end_user_pfn to save on memmap */
+       if (*ei_startpfn >= end_user_pfn)
+               return 0;
+       if (*ei_endpfn > end_user_pfn)
+               *ei_endpfn = end_user_pfn;
 
-               add_active_range(nid, ei_startpfn, ei_endpfn);
-       }
+       return 1;
+}
+
+/* Walk the e820 map and register active regions within a node */
+void __init
+e820_register_active_regions(int nid, unsigned long start_pfn,
+                                                       unsigned long end_pfn)
+{
+       unsigned long ei_startpfn;
+       unsigned long ei_endpfn;
+       int i;
+
+       for (i = 0; i < e820.nr_map; i++)
+               if (e820_find_active_region(&e820.map[i],
+                                           start_pfn, end_pfn,
+                                           &ei_startpfn, &ei_endpfn))
+                       add_active_range(nid, ei_startpfn, ei_endpfn);
 }
 
 /* 
@@ -350,12 +333,35 @@ void __init add_memory_region(unsigned long start, unsigned long size, int type)
        e820.nr_map++;
 }
 
+/*
+ * Find the hole size (in bytes) in the memory range.
+ * @start: starting address of the memory range to scan
+ * @end: ending address of the memory range to scan
+ */
+unsigned long __init e820_hole_size(unsigned long start, unsigned long end)
+{
+       unsigned long start_pfn = start >> PAGE_SHIFT;
+       unsigned long end_pfn = end >> PAGE_SHIFT;
+       unsigned long ei_startpfn;
+       unsigned long ei_endpfn;
+       unsigned long ram = 0;
+       int i;
+
+       for (i = 0; i < e820.nr_map; i++) {
+               if (e820_find_active_region(&e820.map[i],
+                                           start_pfn, end_pfn,
+                                           &ei_startpfn, &ei_endpfn))
+                       ram += ei_endpfn - ei_startpfn;
+       }
+       return end - start - (ram << PAGE_SHIFT);
+}
+
 void __init e820_print_map(char *who)
 {
        int i;
 
        for (i = 0; i < e820.nr_map; i++) {
-               printk(" %s: %016Lx - %016Lx ", who,
+               printk(KERN_INFO " %s: %016Lx - %016Lx ", who,
                        (unsigned long long) e820.map[i].addr,
                        (unsigned long long) (e820.map[i].addr + e820.map[i].size));
                switch (e820.map[i].type) {