Merge branch 'for-linus' of git://www.linux-m32r.org/git/takata/linux-2.6_dev
[pandora-kernel.git] / arch / x86 / kernel / e820_64.c
index 9184e64..124480c 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/setup.h>
 #include <asm/sections.h>
 #include <asm/kdebug.h>
+#include <asm/trampoline.h>
 
 struct e820map e820;
 
@@ -36,11 +37,11 @@ struct e820map e820;
 unsigned long end_pfn;
 
 /*
- * end_pfn only includes RAM, while end_pfn_map includes all e820 entries.
- * The direct mapping extends to end_pfn_map, so that we can directly access
+ * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
+ * The direct mapping extends to max_pfn_mapped, so that we can directly access
  * apertures, ACPI and other tables without having to play with fixmaps.
  */
-unsigned long end_pfn_map;
+unsigned long max_pfn_mapped;
 
 /*
  * Last pfn which the user wants to use.
@@ -58,8 +59,8 @@ struct early_res {
 };
 static struct early_res early_res[MAX_EARLY_RES] __initdata = {
        { 0, PAGE_SIZE, "BIOS data page" },                     /* BIOS data page */
-#ifdef CONFIG_SMP
-       { SMP_TRAMPOLINE_BASE, SMP_TRAMPOLINE_BASE + 2*PAGE_SIZE, "SMP_TRAMPOLINE" },
+#ifdef CONFIG_X86_TRAMPOLINE
+       { TRAMPOLINE_BASE, TRAMPOLINE_BASE + 2 * PAGE_SIZE, "TRAMPOLINE" },
 #endif
        {}
 };
@@ -83,19 +84,46 @@ void __init reserve_early(unsigned long start, unsigned long end, char *name)
                strncpy(r->name, name, sizeof(r->name) - 1);
 }
 
-void __init early_res_to_bootmem(void)
+void __init free_early(unsigned long start, unsigned long end)
+{
+       struct early_res *r;
+       int i, j;
+
+       for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
+               r = &early_res[i];
+               if (start == r->start && end == r->end)
+                       break;
+       }
+       if (i >= MAX_EARLY_RES || !early_res[i].end)
+               panic("free_early on not reserved area: %lx-%lx!", start, end);
+
+       for (j = i + 1; j < MAX_EARLY_RES && early_res[j].end; j++)
+               ;
+
+       memmove(&early_res[i], &early_res[i + 1],
+              (j - 1 - i) * sizeof(struct early_res));
+
+       early_res[j - 1].end = 0;
+}
+
+void __init early_res_to_bootmem(unsigned long start, unsigned long end)
 {
        int i;
+       unsigned long final_start, final_end;
        for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
                struct early_res *r = &early_res[i];
-               printk(KERN_INFO "early res: %d [%lx-%lx] %s\n", i,
-                       r->start, r->end - 1, r->name);
-               reserve_bootmem_generic(r->start, r->end - r->start);
+               final_start = max(start, r->start);
+               final_end = min(end, r->end);
+               if (final_start >= final_end)
+                       continue;
+               printk(KERN_INFO "  early res: %d [%lx-%lx] %s\n", i,
+                       final_start, final_end - 1, r->name);
+               reserve_bootmem_generic(final_start, final_end - final_start);
        }
 }
 
 /* Check for already reserved areas */
-static inline int
+static inline int __init
 bad_addr(unsigned long *addrp, unsigned long size, unsigned long align)
 {
        int i;
@@ -115,7 +143,7 @@ again:
 }
 
 /* Check for already reserved areas */
-static inline int
+static inline int __init
 bad_addr_size(unsigned long *addrp, unsigned long *sizep, unsigned long align)
 {
        int i;
@@ -241,7 +269,9 @@ unsigned long __init find_e820_area(unsigned long start, unsigned long end,
 /*
  * Find next free range after *start
  */
-unsigned long __init find_e820_area_size(unsigned long start, unsigned long *sizep, unsigned long align)
+unsigned long __init find_e820_area_size(unsigned long start,
+                                        unsigned long *sizep,
+                                        unsigned long align)
 {
        int i;
 
@@ -254,17 +284,15 @@ unsigned long __init find_e820_area_size(unsigned long start, unsigned long *siz
                        continue;
                addr = round_up(ei->addr, align);
                ei_last = ei->addr + ei->size;
-//             printk(KERN_DEBUG "find_e820_area_size : e820 %d [%llx, %lx]\n", i, ei->addr, ei_last);
                if (addr < start)
                        addr = round_up(start, align);
-//             printk(KERN_DEBUG "find_e820_area_size : 0 [%lx, %lx]\n", addr, ei_last);
                if (addr >= ei_last)
                        continue;
                *sizep = ei_last - addr;
-               while (bad_addr_size(&addr, sizep, align) && addr+ *sizep <= ei_last)
+               while (bad_addr_size(&addr, sizep, align) &&
+                       addr + *sizep <= ei_last)
                        ;
                last = addr + *sizep;
-//             printk(KERN_DEBUG "find_e820_area_size : 1 [%lx, %lx]\n", addr, last);
                if (last > ei_last)
                        continue;
                return addr;
@@ -281,16 +309,16 @@ unsigned long __init e820_end_of_ram(void)
 
        end_pfn = find_max_pfn_with_active_regions();
 
-       if (end_pfn > end_pfn_map)
-               end_pfn_map = end_pfn;
-       if (end_pfn_map > MAXMEM>>PAGE_SHIFT)
-               end_pfn_map = MAXMEM>>PAGE_SHIFT;
+       if (end_pfn > max_pfn_mapped)
+               max_pfn_mapped = end_pfn;
+       if (max_pfn_mapped > MAXMEM>>PAGE_SHIFT)
+               max_pfn_mapped = MAXMEM>>PAGE_SHIFT;
        if (end_pfn > end_user_pfn)
                end_pfn = end_user_pfn;
-       if (end_pfn > end_pfn_map)
-               end_pfn = end_pfn_map;
+       if (end_pfn > max_pfn_mapped)
+               end_pfn = max_pfn_mapped;
 
-       printk(KERN_INFO "end_pfn_map = %lu\n", end_pfn_map);
+       printk(KERN_INFO "max_pfn_mapped = %lu\n", max_pfn_mapped);
        return end_pfn;
 }
 
@@ -366,9 +394,9 @@ static int __init e820_find_active_region(const struct e820entry *ei,
        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 max_pfn_mapped should be updated */
+       if (ei->type != E820_RAM && *ei_endpfn > max_pfn_mapped)
+               max_pfn_mapped = *ei_endpfn;
 
        /* Skip if map is outside the node */
        if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
@@ -759,7 +787,7 @@ static int __init parse_memmap_opt(char *p)
                saved_max_pfn = e820_end_of_ram();
                remove_all_active_ranges();
 #endif
-               end_pfn_map = 0;
+               max_pfn_mapped = 0;
                e820.nr_map = 0;
                userdef = 1;
                return 0;