x86: reserve end-of-conventional-memory to 1MB on 32-bit
[sfrench/cifs-2.6.git] / arch / x86 / kernel / e820_32.c
index 3c86b979a40aed829b52797cd8e90c88a6c8ed81..0240cd778365d12a05e3096e4b7492b510573e5a 100644 (file)
@@ -7,7 +7,6 @@
 #include <linux/kexec.h>
 #include <linux/module.h>
 #include <linux/mm.h>
-#include <linux/efi.h>
 #include <linux/pfn.h>
 #include <linux/uaccess.h>
 #include <linux/suspend.h>
 #include <asm/e820.h>
 #include <asm/setup.h>
 
-#ifdef CONFIG_EFI
-int efi_enabled = 0;
-EXPORT_SYMBOL(efi_enabled);
-#endif
-
 struct e820map e820;
 struct change_member {
        struct e820entry *pbios; /* pointer to original bios entry */
@@ -37,19 +31,6 @@ unsigned long pci_mem_start = 0x10000000;
 EXPORT_SYMBOL(pci_mem_start);
 #endif
 extern int user_defined_memmap;
-struct resource data_resource = {
-       .name   = "Kernel data",
-       .start  = 0,
-       .end    = 0,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
-};
-
-struct resource code_resource = {
-       .name   = "Kernel code",
-       .start  = 0,
-       .end    = 0,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
-};
 
 static struct resource system_rom_resource = {
        .name   = "System ROM",
@@ -104,60 +85,6 @@ static struct resource video_rom_resource = {
        .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
 };
 
-static struct resource video_ram_resource = {
-       .name   = "Video RAM area",
-       .start  = 0xa0000,
-       .end    = 0xbffff,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
-};
-
-static struct resource standard_io_resources[] = { {
-       .name   = "dma1",
-       .start  = 0x0000,
-       .end    = 0x001f,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-}, {
-       .name   = "pic1",
-       .start  = 0x0020,
-       .end    = 0x0021,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-}, {
-       .name   = "timer0",
-       .start  = 0x0040,
-       .end    = 0x0043,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-}, {
-       .name   = "timer1",
-       .start  = 0x0050,
-       .end    = 0x0053,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-}, {
-       .name   = "keyboard",
-       .start  = 0x0060,
-       .end    = 0x006f,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-}, {
-       .name   = "dma page reg",
-       .start  = 0x0080,
-       .end    = 0x008f,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-}, {
-       .name   = "pic2",
-       .start  = 0x00a0,
-       .end    = 0x00a1,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-}, {
-       .name   = "dma2",
-       .start  = 0x00c0,
-       .end    = 0x00df,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-}, {
-       .name   = "fpu",
-       .start  = 0x00f0,
-       .end    = 0x00ff,
-       .flags  = IORESOURCE_BUSY | IORESOURCE_IO
-} };
-
 #define ROMSIGNATURE 0xaa55
 
 static int __init romsignature(const unsigned char *rom)
@@ -253,8 +180,9 @@ static void __init probe_roms(void)
  * Request address space for all standard RAM and ROM resources
  * and also for regions reported as reserved by the e820.
  */
-static void __init
-legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
+void __init init_iomem_resources(struct resource *code_resource,
+               struct resource *data_resource,
+               struct resource *bss_resource)
 {
        int i;
 
@@ -287,40 +215,15 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
                         */
                        request_resource(res, code_resource);
                        request_resource(res, data_resource);
+                       request_resource(res, bss_resource);
 #ifdef CONFIG_KEXEC
-                       request_resource(res, &crashk_res);
+                       if (crashk_res.start != crashk_res.end)
+                               request_resource(res, &crashk_res);
 #endif
                }
        }
 }
 
-/*
- * Request address space for all standard resources
- *
- * This is called just before pcibios_init(), which is also a
- * subsys_initcall, but is linked in later (in arch/i386/pci/common.c).
- */
-static int __init request_standard_resources(void)
-{
-       int i;
-
-       printk("Setting up standard PCI resources\n");
-       if (efi_enabled)
-               efi_initialize_iomem_resources(&code_resource, &data_resource);
-       else
-               legacy_init_iomem_resources(&code_resource, &data_resource);
-
-       /* EFI systems may still have VGA */
-       request_resource(&iomem_resource, &video_ram_resource);
-
-       /* request I/O space for devices used on all i[345]86 PCs */
-       for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
-               request_resource(&ioport_resource, &standard_io_resources[i]);
-       return 0;
-}
-
-subsys_initcall(request_standard_resources);
-
 #if defined(CONFIG_PM) && defined(CONFIG_HIBERNATION)
 /**
  * e820_mark_nosave_regions - Find the ranges of physical addresses that do not
@@ -357,19 +260,17 @@ void __init add_memory_region(unsigned long long start,
 {
        int x;
 
-       if (!efi_enabled) {
-                       x = e820.nr_map;
+       x = e820.nr_map;
 
-               if (x == E820MAX) {
-                   printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
-                   return;
-               }
-
-               e820.map[x].addr = start;
-               e820.map[x].size = size;
-               e820.map[x].type = type;
-               e820.nr_map++;
+       if (x == E820MAX) {
+               printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
+               return;
        }
+
+       e820.map[x].addr = start;
+       e820.map[x].size = size;
+       e820.map[x].type = type;
+       e820.nr_map++;
 } /* add_memory_region */
 
 /*
@@ -549,61 +450,25 @@ int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
  * thinkpad 560x, for example, does not cooperate with the memory
  * detection code.)
  */
-int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
+int __init copy_e820_map(struct e820entry *biosmap, int nr_map)
 {
        /* Only one memory region (or negative)? Ignore it */
        if (nr_map < 2)
                return -1;
 
        do {
-               unsigned long long start = biosmap->addr;
-               unsigned long long size = biosmap->size;
-               unsigned long long end = start + size;
-               unsigned long type = biosmap->type;
+               u64 start = biosmap->addr;
+               u64 size = biosmap->size;
+               u64 end = start + size;
+               u32 type = biosmap->type;
 
                /* Overflow in 64 bits? Ignore the memory map. */
                if (start > end)
                        return -1;
 
-               /*
-                * Some BIOSes claim RAM in the 640k - 1M region.
-                * Not right. Fix it up.
-                */
-               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;
-}
+       } while (biosmap++, --nr_map);
 
-/*
- * Callback for efi_memory_walk.
- */
-static int __init
-efi_find_max_pfn(unsigned long start, unsigned long end, void *arg)
-{
-       unsigned long *max_pfn = arg, pfn;
-
-       if (start < end) {
-               pfn = PFN_UP(end -1);
-               if (pfn > *max_pfn)
-                       *max_pfn = pfn;
-       }
-       return 0;
-}
-
-static int __init
-efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
-{
-       memory_present(0, PFN_UP(start), PFN_DOWN(end));
        return 0;
 }
 
@@ -615,11 +480,6 @@ void __init find_max_pfn(void)
        int i;
 
        max_pfn = 0;
-       if (efi_enabled) {
-               efi_memmap_walk(efi_find_max_pfn, &max_pfn);
-               efi_memmap_walk(efi_memory_present_wrapper, NULL);
-               return;
-       }
 
        for (i = 0; i < e820.nr_map; i++) {
                unsigned long start, end;
@@ -636,24 +496,6 @@ void __init find_max_pfn(void)
        }
 }
 
-/*
- * Free all available memory for boot time allocation.  Used
- * as a callback function by efi_memory_walk()
- */
-
-static int __init
-free_available_memory(unsigned long start, unsigned long end, void *arg)
-{
-       /* check max_low_pfn */
-       if (start >= (max_low_pfn << PAGE_SHIFT))
-               return 0;
-       if (end >= (max_low_pfn << PAGE_SHIFT))
-               end = max_low_pfn << PAGE_SHIFT;
-       if (start < end)
-               free_bootmem(start, end - start);
-
-       return 0;
-}
 /*
  * Register fully available low RAM pages with the bootmem allocator.
  */
@@ -661,10 +503,6 @@ void __init register_bootmem_low_pages(unsigned long max_low_pfn)
 {
        int i;
 
-       if (efi_enabled) {
-               efi_memmap_walk(free_available_memory, NULL);
-               return;
-       }
        for (i = 0; i < e820.nr_map; i++) {
                unsigned long curr_pfn, last_pfn, size;
                /*
@@ -705,7 +543,7 @@ void __init e820_register_memory(void)
        int i;
 
        /*
-        * Search for the bigest gap in the low 32 bits of the e820
+        * Search for the biggest gap in the low 32 bits of the e820
         * memory space.
         */
        last = 0x100000000ull;
@@ -772,56 +610,12 @@ void __init print_memory_map(char *who)
        }
 }
 
-static __init __always_inline void efi_limit_regions(unsigned long long size)
-{
-       unsigned long long current_addr = 0;
-       efi_memory_desc_t *md, *next_md;
-       void *p, *p1;
-       int i, j;
-
-       j = 0;
-       p1 = memmap.map;
-       for (p = p1, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) {
-               md = p;
-               next_md = p1;
-               current_addr = md->phys_addr +
-                       PFN_PHYS(md->num_pages);
-               if (is_available_memory(md)) {
-                       if (md->phys_addr >= size) continue;
-                       memcpy(next_md, md, memmap.desc_size);
-                       if (current_addr >= size) {
-                               next_md->num_pages -=
-                                       PFN_UP(current_addr-size);
-                       }
-                       p1 += memmap.desc_size;
-                       next_md = p1;
-                       j++;
-               } else if ((md->attribute & EFI_MEMORY_RUNTIME) ==
-                          EFI_MEMORY_RUNTIME) {
-                       /* In order to make runtime services
-                        * available we have to include runtime
-                        * memory regions in memory map */
-                       memcpy(next_md, md, memmap.desc_size);
-                       p1 += memmap.desc_size;
-                       next_md = p1;
-                       j++;
-               }
-       }
-       memmap.nr_map = j;
-       memmap.map_end = memmap.map +
-               (memmap.nr_map * memmap.desc_size);
-}
-
 void __init limit_regions(unsigned long long size)
 {
        unsigned long long current_addr;
        int i;
 
        print_memory_map("limit_regions start");
-       if (efi_enabled) {
-               efi_limit_regions(size);
-               return;
-       }
        for (i = 0; i < e820.nr_map; i++) {
                current_addr = e820.map[i].addr + e820.map[i].size;
                if (current_addr < size)
@@ -942,3 +736,40 @@ static int __init parse_memmap(char *arg)
        return 0;
 }
 early_param("memmap", parse_memmap);
+void __init update_memory_range(u64 start, u64 size, unsigned old_type,
+                               unsigned new_type)
+{
+       int i;
+
+       BUG_ON(old_type == new_type);
+
+       for (i = 0; i < e820.nr_map; i++) {
+               struct e820entry *ei = &e820.map[i];
+               u64 final_start, final_end;
+               if (ei->type != old_type)
+                       continue;
+               /* totally covered? */
+               if (ei->addr >= start && ei->size <= size) {
+                       ei->type = new_type;
+                       continue;
+               }
+               /* partially covered */
+               final_start = max(start, ei->addr);
+               final_end = min(start + size, ei->addr + ei->size);
+               if (final_start >= final_end)
+                       continue;
+               add_memory_region(final_start, final_end - final_start,
+                                        new_type);
+       }
+}
+void __init update_e820(void)
+{
+       u8 nr_map;
+
+       nr_map = e820.nr_map;
+       if (sanitize_e820_map(e820.map, &nr_map))
+               return;
+       e820.nr_map = nr_map;
+       printk(KERN_INFO "modified physical RAM map:\n");
+       print_memory_map("modified");
+}