x86: kill bad_ppro
[deliverable/linux.git] / arch / x86 / kernel / e820.c
index 5051ce744b4e93b2cefcfd4c82b477d568feace3..432c49178577735d10f93a4eba7a315c292b4ed2 100644 (file)
@@ -359,6 +359,26 @@ static struct e820entry new_bios[E820_X_MAX] __initdata;
        return 0;
 }
 
+static int __init __copy_e820_map(struct e820entry *biosmap, int nr_map)
+{
+       while (nr_map) {
+               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;
+
+               e820_add_region(start, size, type);
+
+               biosmap++;
+               nr_map--;
+       }
+       return 0;
+}
+
 /*
  * Copy the BIOS e820 map into a safe place.
  *
@@ -374,19 +394,7 @@ int __init copy_e820_map(struct e820entry *biosmap, int nr_map)
        if (nr_map < 2)
                return -1;
 
-       do {
-               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;
-
-               e820_add_region(start, size, type);
-       } while (biosmap++, --nr_map);
-       return 0;
+       return __copy_e820_map(biosmap, nr_map);
 }
 
 u64 __init e820_update_range(u64 start, u64 size, unsigned old_type,
@@ -496,6 +504,31 @@ __init void e820_setup_gap(void)
               pci_mem_start, gapstart, gapsize);
 }
 
+/**
+ * Because of the size limitation of struct boot_params, only first
+ * 128 E820 memory entries are passed to kernel via
+ * boot_params.e820_map, others are passed via SETUP_E820_EXT node of
+ * linked list of struct setup_data, which is parsed here.
+ */
+void __init parse_e820_ext(struct setup_data *sdata, unsigned long pa_data)
+{
+       u32 map_len;
+       int entries;
+       struct e820entry *extmap;
+
+       entries = sdata->len / sizeof(struct e820entry);
+       map_len = sdata->len + sizeof(struct setup_data);
+       if (map_len > PAGE_SIZE)
+               sdata = early_ioremap(pa_data, map_len);
+       extmap = (struct e820entry *)(sdata->data);
+       __copy_e820_map(extmap, entries);
+       sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+       if (map_len > PAGE_SIZE)
+               early_iounmap(sdata, map_len);
+       printk(KERN_INFO "extended physical RAM map:\n");
+       e820_print_map("extended");
+}
+
 #if defined(CONFIG_X86_64) || \
        (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
 /**
@@ -612,17 +645,6 @@ void __init free_early(u64 start, u64 end)
        early_res[j - 1].end = 0;
 }
 
-int __init page_is_reserved_early(unsigned long pagenr)
-{
-       u64 start = (u64)pagenr << PAGE_SHIFT;
-       int i;
-       struct early_res *r;
-
-       i = find_overlapped_early(start, start + PAGE_SIZE);
-       r = &early_res[i];
-       return (i < MAX_EARLY_RES && r->end);
-}
-
 void __init early_res_to_bootmem(u64 start, u64 end)
 {
        int i;
@@ -976,3 +998,35 @@ void __init finish_e820_parsing(void)
                e820_print_map("user");
        }
 }
+
+/*
+ * Mark e820 reserved areas as busy for the resource manager.
+ */
+void __init e820_reserve_resources(void)
+{
+       int i;
+       struct resource *res;
+
+       res = alloc_bootmem_low(sizeof(struct resource) * e820.nr_map);
+       for (i = 0; i < e820.nr_map; i++) {
+               switch (e820.map[i].type) {
+               case E820_RAM:  res->name = "System RAM"; break;
+               case E820_ACPI: res->name = "ACPI Tables"; break;
+               case E820_NVS:  res->name = "ACPI Non-volatile Storage"; break;
+               default:        res->name = "reserved";
+               }
+               res->start = e820.map[i].addr;
+               res->end = res->start + e820.map[i].size - 1;
+#ifndef CONFIG_RESOURCES_64BIT
+               if (res->end > 0x100000000ULL) {
+                       res++;
+                       continue;
+               }
+#endif
+               res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+               insert_resource(&iomem_resource, res);
+               res++;
+       }
+}
+
+
This page took 0.027174 seconds and 5 git commands to generate.