|
@@ -149,6 +149,9 @@ static void __init e820_print_type(u32 type)
|
|
|
case E820_UNUSABLE:
|
|
|
printk(KERN_CONT "unusable");
|
|
|
break;
|
|
|
+ case E820_PRAM:
|
|
|
+ printk(KERN_CONT "persistent (type %u)", type);
|
|
|
+ break;
|
|
|
default:
|
|
|
printk(KERN_CONT "type %u", type);
|
|
|
break;
|
|
@@ -343,7 +346,7 @@ int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
|
|
|
* continue building up new bios map based on this
|
|
|
* information
|
|
|
*/
|
|
|
- if (current_type != last_type) {
|
|
|
+ if (current_type != last_type || current_type == E820_PRAM) {
|
|
|
if (last_type != 0) {
|
|
|
new_bios[new_bios_entry].size =
|
|
|
change_point[chgidx]->addr - last_addr;
|
|
@@ -688,6 +691,7 @@ void __init e820_mark_nosave_regions(unsigned long limit_pfn)
|
|
|
register_nosave_region(pfn, PFN_UP(ei->addr));
|
|
|
|
|
|
pfn = PFN_DOWN(ei->addr + ei->size);
|
|
|
+
|
|
|
if (ei->type != E820_RAM && ei->type != E820_RESERVED_KERN)
|
|
|
register_nosave_region(PFN_UP(ei->addr), pfn);
|
|
|
|
|
@@ -748,7 +752,7 @@ u64 __init early_reserve_e820(u64 size, u64 align)
|
|
|
/*
|
|
|
* Find the highest page frame number we have available
|
|
|
*/
|
|
|
-static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
|
|
|
+static unsigned long __init e820_end_pfn(unsigned long limit_pfn)
|
|
|
{
|
|
|
int i;
|
|
|
unsigned long last_pfn = 0;
|
|
@@ -759,7 +763,11 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
|
|
|
unsigned long start_pfn;
|
|
|
unsigned long end_pfn;
|
|
|
|
|
|
- if (ei->type != type)
|
|
|
+ /*
|
|
|
+ * Persistent memory is accounted as ram for purposes of
|
|
|
+ * establishing max_pfn and mem_map.
|
|
|
+ */
|
|
|
+ if (ei->type != E820_RAM && ei->type != E820_PRAM)
|
|
|
continue;
|
|
|
|
|
|
start_pfn = ei->addr >> PAGE_SHIFT;
|
|
@@ -784,12 +792,12 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
|
|
|
}
|
|
|
unsigned long __init e820_end_of_ram_pfn(void)
|
|
|
{
|
|
|
- return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
|
|
|
+ return e820_end_pfn(MAX_ARCH_PFN);
|
|
|
}
|
|
|
|
|
|
unsigned long __init e820_end_of_low_ram_pfn(void)
|
|
|
{
|
|
|
- return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
|
|
|
+ return e820_end_pfn(1UL << (32-PAGE_SHIFT));
|
|
|
}
|
|
|
|
|
|
static void early_panic(char *msg)
|
|
@@ -866,6 +874,9 @@ static int __init parse_memmap_one(char *p)
|
|
|
} else if (*p == '$') {
|
|
|
start_at = memparse(p+1, &p);
|
|
|
e820_add_region(start_at, mem_size, E820_RESERVED);
|
|
|
+ } else if (*p == '!') {
|
|
|
+ start_at = memparse(p+1, &p);
|
|
|
+ e820_add_region(start_at, mem_size, E820_PRAM);
|
|
|
} else
|
|
|
e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
|
|
|
|
|
@@ -907,6 +918,7 @@ static inline const char *e820_type_to_string(int e820_type)
|
|
|
case E820_ACPI: return "ACPI Tables";
|
|
|
case E820_NVS: return "ACPI Non-volatile Storage";
|
|
|
case E820_UNUSABLE: return "Unusable memory";
|
|
|
+ case E820_PRAM: return "Persistent RAM";
|
|
|
default: return "reserved";
|
|
|
}
|
|
|
}
|
|
@@ -940,7 +952,9 @@ void __init e820_reserve_resources(void)
|
|
|
* pci device BAR resource and insert them later in
|
|
|
* pcibios_resource_survey()
|
|
|
*/
|
|
|
- if (e820.map[i].type != E820_RESERVED || res->start < (1ULL<<20)) {
|
|
|
+ if (((e820.map[i].type != E820_RESERVED) &&
|
|
|
+ (e820.map[i].type != E820_PRAM)) ||
|
|
|
+ res->start < (1ULL<<20)) {
|
|
|
res->flags |= IORESOURCE_BUSY;
|
|
|
insert_resource(&iomem_resource, res);
|
|
|
}
|