void __init e820_print_map(char *who) { int i; for (i = 0; i < e820.nr_map; i++) { printk(KERN_INFO " %s: %016Lx - %016Lx ", who, (unsigned long long) e820.map[i].addr, (unsigned long long) (e820.map[i].addr + e820.map[i].size)); e820_print_type(e820.map[i].type); printk(KERN_CONT "\n"); } }
void __init e820__print_table(char *who) { int i; for (i = 0; i < e820_table->nr_entries; i++) { pr_info("%s: [mem %#018Lx-%#018Lx] ", who, e820_table->entries[i].addr, e820_table->entries[i].addr + e820_table->entries[i].size - 1); e820_print_type(e820_table->entries[i].type); pr_cont("\n"); } }
/* make e820 not cover the range */ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type, int checktype) { int i; u64 end; u64 real_removed_size = 0; if (size > (ULLONG_MAX - start)) size = ULLONG_MAX - start; end = start + size; printk(KERN_DEBUG "e820 remove range: %016Lx - %016Lx ", (unsigned long long) start, (unsigned long long) end); e820_print_type(old_type); printk(KERN_CONT "\n"); for (i = 0; i < e820.nr_map; i++) { struct e820entry *ei = &e820.map[i]; u64 final_start, final_end; if (checktype && ei->type != old_type) continue; /* totally covered? */ if (ei->addr >= start && (ei->addr + ei->size) <= (start + size)) { real_removed_size += ei->size; memset(ei, 0, sizeof(struct e820entry)); continue; } /* partially covered */ final_start = max(start, ei->addr); final_end = min(start + size, ei->addr + ei->size); if (final_start >= final_end) continue; real_removed_size += final_end - final_start; ei->size -= final_end - final_start; if (ei->addr < final_start) continue; ei->addr = final_end; } return real_removed_size; }
static u64 __init __e820_update_range(struct e820map *e820x, u64 start, u64 size, unsigned old_type, unsigned new_type) { u64 end; unsigned int i; u64 real_updated_size = 0; BUG_ON(old_type == new_type); if (size > (ULLONG_MAX - start)) size = ULLONG_MAX - start; end = start + size; printk(KERN_DEBUG "e820 update range: %016Lx - %016Lx ", (unsigned long long) start, (unsigned long long) end); e820_print_type(old_type); printk(KERN_CONT " ==> "); e820_print_type(new_type); printk(KERN_CONT "\n"); for (i = 0; i < e820x->nr_map; i++) { struct e820entry *ei = &e820x->map[i]; u64 final_start, final_end; u64 ei_end; if (ei->type != old_type) continue; ei_end = ei->addr + ei->size; /* totally covered by new range? */ if (ei->addr >= start && ei_end <= end) { ei->type = new_type; real_updated_size += ei->size; continue; } /* new range is totally covered? */ if (ei->addr < start && ei_end > end) { __e820_add_region(e820x, start, size, new_type); __e820_add_region(e820x, end, ei_end - end, ei->type); ei->size = start - ei->addr; real_updated_size += size; continue; } /* partially covered */ final_start = max(start, ei->addr); final_end = min(end, ei_end); if (final_start >= final_end) continue; __e820_add_region(e820x, final_start, final_end - final_start, new_type); real_updated_size += final_end - final_start; /* * left range could be head or tail, so need to update * size at first. */ ei->size -= final_end - final_start; if (ei->addr < final_start) continue; ei->addr = final_end; } return real_updated_size; }