[PATCH] Don't force reserve the 640k-1MB range
[linux-2.6-microblaze.git] / arch / x86_64 / kernel / e820.c
index d6d7f73..e06c271 100644 (file)
@@ -24,6 +24,8 @@
 #include <asm/bootsetup.h>
 #include <asm/sections.h>
 
+struct e820map e820 __initdata;
+
 /* 
  * PFN of last memory page.
  */
@@ -40,7 +42,7 @@ unsigned long end_pfn_map;
 /* 
  * Last pfn which the user wants to use.
  */
-unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT;  
+static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT;
 
 extern struct resource code_resource, data_resource;
 
@@ -69,12 +71,7 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
                return 1;
        } 
 #endif
-       /* kernel code + 640k memory hole (later should not be needed, but 
-          be paranoid for now) */
-       if (last >= 640*1024 && addr < 1024*1024) {
-               *addrp = 1024*1024;
-               return 1;
-       }
+       /* kernel code */
        if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) {
                *addrp = __pa_symbol(&_end);
                return 1;
@@ -517,13 +514,6 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
  * If we're lucky and live on a modern system, the setup code
  * will have given us a memory map that we can use to properly
  * set up memory.  If we aren't, we'll fake a memory map.
- *
- * We check to see that the memory map contains at least 2 elements
- * before we'll use it, because the detection code in setup.S may
- * not be perfect and most every PC known to man has two memory
- * regions: one from 0 to 640k, and one from 1mb up.  (The IBM
- * thinkpad 560x, for example, does not cooperate with the memory
- * detection code.)
  */
 static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
 {
@@ -541,25 +531,6 @@ static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
                if (start > end)
                        return -1;
 
-               /*
-                * Some BIOSes claim RAM in the 640k - 1M region.
-                * Not right. Fix it up.
-                * 
-                * This should be removed on Hammer which is supposed to not
-                * have non e820 covered ISA mappings there, but I had some strange
-                * problems so it stays for now.  -AK
-                */
-               if (type == E820_RAM) {
-                       if (start < 0x100000ULL && end > 0xA0000ULL) {
-                               if (start < 0xA0000ULL)
-                                       add_memory_region(start, 0xA0000ULL-start, type);
-                               if (end <= 0x100000ULL)
-                                       continue;
-                               start = 0x100000ULL;
-                               size = end - start;
-                       }
-               }
-
                add_memory_region(start, size, type);
        } while (biosmap++,--nr_map);
        return 0;
@@ -596,31 +567,64 @@ void __init setup_memory_region(void)
        e820_print_map(who);
 }
 
-void __init parse_memopt(char *p, char **from) 
-{ 
-       end_user_pfn = memparse(p, from);
+static int __init parse_memopt(char *p)
+{
+       if (!p)
+               return -EINVAL;
+       end_user_pfn = memparse(p, &p);
        end_user_pfn >>= PAGE_SHIFT;    
+       return 0;
 } 
+early_param("mem", parse_memopt);
+
+static int userdef __initdata;
 
-void __init parse_memmapopt(char *p, char **from)
+static int __init parse_memmap_opt(char *p)
 {
+       char *oldp;
        unsigned long long start_at, mem_size;
 
-       mem_size = memparse(p, from);
-       p = *from;
+       if (!strcmp(p, "exactmap")) {
+#ifdef CONFIG_CRASH_DUMP
+               /* If we are doing a crash dump, we
+                * still need to know the real mem
+                * size before original memory map is
+                * reset.
+                */
+               saved_max_pfn = e820_end_of_ram();
+#endif
+               end_pfn_map = 0;
+               e820.nr_map = 0;
+               userdef = 1;
+               return 0;
+       }
+
+       oldp = p;
+       mem_size = memparse(p, &p);
+       if (p == oldp)
+               return -EINVAL;
        if (*p == '@') {
-               start_at = memparse(p+1, from);
+               start_at = memparse(p+1, &p);
                add_memory_region(start_at, mem_size, E820_RAM);
        } else if (*p == '#') {
-               start_at = memparse(p+1, from);
+               start_at = memparse(p+1, &p);
                add_memory_region(start_at, mem_size, E820_ACPI);
        } else if (*p == '$') {
-               start_at = memparse(p+1, from);
+               start_at = memparse(p+1, &p);
                add_memory_region(start_at, mem_size, E820_RESERVED);
        } else {
                end_user_pfn = (mem_size >> PAGE_SHIFT);
        }
-       p = *from;
+       return *p == '\0' ? 0 : -EINVAL;
+}
+early_param("memmap", parse_memmap_opt);
+
+void finish_e820_parsing(void)
+{
+       if (userdef) {
+               printk(KERN_INFO "user-defined physical RAM map:\n");
+               e820_print_map("user");
+       }
 }
 
 unsigned long pci_mem_start = 0xaeedbabe;