]> err.no Git - linux-2.6/blobdiff - arch/x86/kernel/e820.c
Merge branch 'linus' into tracing/urgent
[linux-2.6] / arch / x86 / kernel / e820.c
index 9836a079cfd9c8621cdb1d8844b796947485987b..9af89078f7bb0cb2b6ce7ed958c9483b24d4402e 100644 (file)
@@ -877,7 +877,8 @@ void __init early_res_to_bootmem(u64 start, u64 end)
        for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++)
                count++;
 
-       printk(KERN_INFO "(%d early reservations) ==> bootmem\n", count);
+       printk(KERN_INFO "(%d early reservations) ==> bootmem [%010llx - %010llx]\n",
+                        count, start, end);
        for (i = 0; i < count; i++) {
                struct early_res *r = &early_res[i];
                printk(KERN_INFO "  #%d [%010llx - %010llx] %16s", i,
@@ -1048,15 +1049,10 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
 # define MAX_ARCH_PFN MAXMEM>>PAGE_SHIFT
 #endif
 
-/*
- * Last pfn which the user wants to use.
- */
-unsigned long __initdata end_user_pfn = MAX_ARCH_PFN;
-
 /*
  * Find the highest page frame number we have available
  */
-unsigned long __init e820_end(void)
+static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
 {
        int i;
        unsigned long last_pfn = 0;
@@ -1064,26 +1060,41 @@ unsigned long __init e820_end(void)
 
        for (i = 0; i < e820.nr_map; i++) {
                struct e820entry *ei = &e820.map[i];
+               unsigned long start_pfn;
                unsigned long end_pfn;
 
-               if (ei->type != E820_RAM)
+               if (ei->type != type)
                        continue;
 
+               start_pfn = ei->addr >> PAGE_SHIFT;
                end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT;
+
+               if (start_pfn >= limit_pfn)
+                       continue;
+               if (end_pfn > limit_pfn) {
+                       last_pfn = limit_pfn;
+                       break;
+               }
                if (end_pfn > last_pfn)
                        last_pfn = end_pfn;
        }
 
        if (last_pfn > max_arch_pfn)
                last_pfn = max_arch_pfn;
-       if (last_pfn > end_user_pfn)
-               last_pfn = end_user_pfn;
 
        printk(KERN_INFO "last_pfn = %#lx max_arch_pfn = %#lx\n",
                         last_pfn, max_arch_pfn);
        return last_pfn;
 }
+unsigned long __init e820_end_of_ram_pfn(void)
+{
+       return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
+}
 
+unsigned long __init e820_end_of_low_ram_pfn(void)
+{
+       return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
+}
 /*
  * Finds an active region in the address range from start_pfn to last_pfn and
  * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
@@ -1114,12 +1125,6 @@ int __init e820_find_active_region(const struct e820entry *ei,
        if (*ei_endpfn > last_pfn)
                *ei_endpfn = last_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;
-
        return 1;
 }
 
@@ -1165,6 +1170,8 @@ static void early_panic(char *msg)
        panic(msg);
 }
 
+static int userdef __initdata;
+
 /* "mem=nopentium" disables the 4MB page tables. */
 static int __init parse_memopt(char *p)
 {
@@ -1180,17 +1187,14 @@ static int __init parse_memopt(char *p)
        }
 #endif
 
+       userdef = 1;
        mem_size = memparse(p, &p);
-       end_user_pfn = mem_size>>PAGE_SHIFT;
-       e820_update_range(mem_size, ULLONG_MAX - mem_size,
-               E820_RAM, E820_RESERVED);
+       e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
 
        return 0;
 }
 early_param("mem", parse_memopt);
 
-static int userdef __initdata;
-
 static int __init parse_memmap_opt(char *p)
 {
        char *oldp;
@@ -1206,7 +1210,7 @@ static int __init parse_memmap_opt(char *p)
                 * the real mem size before original memory map is
                 * reset.
                 */
-               saved_max_pfn = e820_end();
+               saved_max_pfn = e820_end_of_ram_pfn();
 #endif
                e820.nr_map = 0;
                userdef = 1;
@@ -1228,11 +1232,9 @@ static int __init parse_memmap_opt(char *p)
        } else if (*p == '$') {
                start_at = memparse(p+1, &p);
                e820_add_region(start_at, mem_size, E820_RESERVED);
-       } else {
-               end_user_pfn = (mem_size >> PAGE_SHIFT);
-               e820_update_range(mem_size, ULLONG_MAX - mem_size,
-                       E820_RAM, E820_RESERVED);
-       }
+       } else
+               e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
+
        return *p == '\0' ? 0 : -EINVAL;
 }
 early_param("memmap", parse_memmap_opt);
@@ -1337,6 +1339,12 @@ char *__init default_machine_specific_memory_setup(void)
 
 char *__init __attribute__((weak)) machine_specific_memory_setup(void)
 {
+       if (x86_quirks->arch_memory_setup) {
+               char *who = x86_quirks->arch_memory_setup();
+
+               if (who)
+                       return who;
+       }
        return default_machine_specific_memory_setup();
 }
 
@@ -1355,24 +1363,3 @@ void __init setup_memory_map(void)
        printk(KERN_INFO "BIOS-provided physical RAM map:\n");
        e820_print_map(who);
 }
-
-#ifdef CONFIG_X86_64
-int __init arch_get_ram_range(int slot, u64 *addr, u64 *size)
-{
-       int i;
-
-       if (slot < 0 || slot >= e820.nr_map)
-               return -1;
-       for (i = slot; i < e820.nr_map; i++) {
-               if (e820.map[i].type != E820_RAM)
-                       continue;
-               break;
-       }
-       if (i == e820.nr_map || e820.map[i].addr > (max_pfn << PAGE_SHIFT))
-               return -1;
-       *addr = e820.map[i].addr;
-       *size = min_t(u64, e820.map[i].size + e820.map[i].addr,
-               max_pfn << PAGE_SHIFT) - *addr;
-       return i + 1;
-}
-#endif