ftrace: use dynamic patching for updating mcount calls
[deliverable/linux.git] / arch / x86 / kernel / e820_64.c
CommitLineData
2f36fa13 1/*
1da177e4
LT
2 * Handle the memory map.
3 * The functions here do the job until bootmem takes over.
8059b2a2
VP
4 *
5 * Getting sanitize_e820_map() in sync with i386 version by applying change:
6 * - Provisions for empty E820 memory regions (reported by certain BIOSes).
7 * Alex Achenbach <xela@slit.de>, December 2002.
8 * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
9 *
1da177e4 10 */
1da177e4
LT
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <linux/init.h>
14#include <linux/bootmem.h>
15#include <linux/ioport.h>
16#include <linux/string.h>
5f5609df 17#include <linux/kexec.h>
b9491ac8 18#include <linux/module.h>
e8eff5ac 19#include <linux/mm.h>
74dfd666
RW
20#include <linux/suspend.h>
21#include <linux/pfn.h>
b9491ac8 22
1a91023a 23#include <asm/pgtable.h>
1da177e4
LT
24#include <asm/page.h>
25#include <asm/e820.h>
26#include <asm/proto.h>
30c82645 27#include <asm/setup.h>
2bc0414e 28#include <asm/sections.h>
718fc13b 29#include <asm/kdebug.h>
e44b7b75 30#include <asm/trampoline.h>
1da177e4 31
b92e9fac 32struct e820map e820;
3bd4d18c 33
2f36fa13 34/*
1da177e4
LT
35 * PFN of last memory page.
36 */
2f36fa13 37unsigned long end_pfn;
1da177e4 38
2f36fa13 39/*
67794292
TG
40 * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
41 * The direct mapping extends to max_pfn_mapped, so that we can directly access
1da177e4 42 * apertures, ACPI and other tables without having to play with fixmaps.
2f36fa13 43 */
67794292 44unsigned long max_pfn_mapped;
1da177e4 45
2f36fa13 46/*
1da177e4
LT
47 * Last pfn which the user wants to use.
48 */
caff0710 49static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT;
1da177e4 50
75175278
AK
51/*
52 * Early reserved memory areas.
53 */
54#define MAX_EARLY_RES 20
30c82645 55
75175278
AK
56struct early_res {
57 unsigned long start, end;
25eff8d4 58 char name[16];
75175278
AK
59};
60static struct early_res early_res[MAX_EARLY_RES] __initdata = {
25eff8d4 61 { 0, PAGE_SIZE, "BIOS data page" }, /* BIOS data page */
e44b7b75
PM
62#ifdef CONFIG_X86_TRAMPOLINE
63 { TRAMPOLINE_BASE, TRAMPOLINE_BASE + 2 * PAGE_SIZE, "TRAMPOLINE" },
1da177e4 64#endif
75175278
AK
65 {}
66};
67
25eff8d4 68void __init reserve_early(unsigned long start, unsigned long end, char *name)
75175278
AK
69{
70 int i;
71 struct early_res *r;
72 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
73 r = &early_res[i];
74 if (end > r->start && start < r->end)
25eff8d4
YL
75 panic("Overlapping early reservations %lx-%lx %s to %lx-%lx %s\n",
76 start, end - 1, name?name:"", r->start, r->end - 1, r->name);
1da177e4 77 }
75175278
AK
78 if (i >= MAX_EARLY_RES)
79 panic("Too many early reservations");
80 r = &early_res[i];
81 r->start = start;
82 r->end = end;
25eff8d4
YL
83 if (name)
84 strncpy(r->name, name, sizeof(r->name) - 1);
75175278 85}
ac71d12c 86
50eae2a7
HY
87void __init free_early(unsigned long start, unsigned long end)
88{
89 struct early_res *r;
90 int i, j;
91
92 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
93 r = &early_res[i];
94 if (start == r->start && end == r->end)
95 break;
96 }
97 if (i >= MAX_EARLY_RES || !early_res[i].end)
98 panic("free_early on not reserved area: %lx-%lx!", start, end);
99
100 for (j = i + 1; j < MAX_EARLY_RES && early_res[j].end; j++)
101 ;
102
781fe2eb 103 memmove(&early_res[i], &early_res[i + 1],
50eae2a7
HY
104 (j - 1 - i) * sizeof(struct early_res));
105
106 early_res[j - 1].end = 0;
107}
108
1a27fc0a 109void __init early_res_to_bootmem(unsigned long start, unsigned long end)
75175278
AK
110{
111 int i;
1a27fc0a 112 unsigned long final_start, final_end;
75175278
AK
113 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
114 struct early_res *r = &early_res[i];
1a27fc0a
YL
115 final_start = max(start, r->start);
116 final_end = min(end, r->end);
117 if (final_start >= final_end)
118 continue;
119 printk(KERN_INFO " early res: %d [%lx-%lx] %s\n", i,
120 final_start, final_end - 1, r->name);
121 reserve_bootmem_generic(final_start, final_end - final_start);
ac71d12c 122 }
75175278 123}
ac71d12c 124
75175278 125/* Check for already reserved areas */
1a7a34af 126static inline int __init
48c508b3 127bad_addr(unsigned long *addrp, unsigned long size, unsigned long align)
75175278
AK
128{
129 int i;
130 unsigned long addr = *addrp, last;
131 int changed = 0;
132again:
133 last = addr + size;
134 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
135 struct early_res *r = &early_res[i];
136 if (last >= r->start && addr < r->end) {
48c508b3 137 *addrp = addr = round_up(r->end, align);
75175278
AK
138 changed = 1;
139 goto again;
140 }
076422d2 141 }
75175278 142 return changed;
2f36fa13 143}
1da177e4 144
272b9cad 145/* Check for already reserved areas */
1a7a34af 146static inline int __init
272b9cad
YL
147bad_addr_size(unsigned long *addrp, unsigned long *sizep, unsigned long align)
148{
149 int i;
150 unsigned long addr = *addrp, last;
151 unsigned long size = *sizep;
152 int changed = 0;
153again:
154 last = addr + size;
155 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
156 struct early_res *r = &early_res[i];
157 if (last > r->start && addr < r->start) {
158 size = r->start - addr;
159 changed = 1;
160 goto again;
161 }
162 if (last > r->end && addr < r->end) {
163 addr = round_up(r->end, align);
164 size = last - addr;
165 changed = 1;
166 goto again;
167 }
168 if (last <= r->end && addr >= r->start) {
169 (*sizep)++;
170 return 0;
171 }
172 }
173 if (changed) {
174 *addrp = addr;
175 *sizep = size;
176 }
177 return changed;
178}
95222368
AV
179/*
180 * This function checks if any part of the range <start,end> is mapped
181 * with type.
182 */
b92e9fac 183int
eee5a9fa 184e820_any_mapped(unsigned long start, unsigned long end, unsigned type)
2f36fa13 185{
1da177e4 186 int i;
2f36fa13
TG
187
188 for (i = 0; i < e820.nr_map; i++) {
189 struct e820entry *ei = &e820.map[i];
190
191 if (type && ei->type != type)
1da177e4 192 continue;
48c8b113 193 if (ei->addr >= end || ei->addr + ei->size <= start)
2f36fa13
TG
194 continue;
195 return 1;
196 }
1da177e4
LT
197 return 0;
198}
b92e9fac 199EXPORT_SYMBOL_GPL(e820_any_mapped);
1da177e4 200
79e453d4
LT
201/*
202 * This function checks if the entire range <start,end> is mapped with type.
203 *
204 * Note: this function only works correct if the e820 table is sorted and
205 * not-overlapping, which is the case
206 */
2f36fa13
TG
207int __init e820_all_mapped(unsigned long start, unsigned long end,
208 unsigned type)
79e453d4
LT
209{
210 int i;
2f36fa13 211
79e453d4
LT
212 for (i = 0; i < e820.nr_map; i++) {
213 struct e820entry *ei = &e820.map[i];
2f36fa13 214
79e453d4
LT
215 if (type && ei->type != type)
216 continue;
217 /* is the region (part) in overlap with the current region ?*/
218 if (ei->addr >= end || ei->addr + ei->size <= start)
219 continue;
220
221 /* if the region is at the beginning of <start,end> we move
222 * start to the end of the region since it's ok until there
223 */
224 if (ei->addr <= start)
225 start = ei->addr + ei->size;
2f36fa13
TG
226 /*
227 * if start is now at or beyond end, we're done, full
228 * coverage
229 */
79e453d4 230 if (start >= end)
2f36fa13 231 return 1;
79e453d4
LT
232 }
233 return 0;
234}
235
2f36fa13 236/*
24a5da73 237 * Find a free area with specified alignment in a specific range.
2f36fa13
TG
238 */
239unsigned long __init find_e820_area(unsigned long start, unsigned long end,
48c508b3 240 unsigned long size, unsigned long align)
2f36fa13
TG
241{
242 int i;
243
244 for (i = 0; i < e820.nr_map; i++) {
245 struct e820entry *ei = &e820.map[i];
48c508b3
YL
246 unsigned long addr, last;
247 unsigned long ei_last;
2f36fa13
TG
248
249 if (ei->type != E820_RAM)
250 continue;
48c508b3
YL
251 addr = round_up(ei->addr, align);
252 ei_last = ei->addr + ei->size;
2f36fa13 253 if (addr < start)
48c508b3 254 addr = round_up(start, align);
272b9cad 255 if (addr >= ei_last)
2f36fa13 256 continue;
48c508b3 257 while (bad_addr(&addr, size, align) && addr+size <= ei_last)
1da177e4 258 ;
24a5da73 259 last = addr + size;
48c508b3 260 if (last > ei_last)
1da177e4 261 continue;
2f36fa13 262 if (last > end)
1da177e4 263 continue;
2f36fa13
TG
264 return addr;
265 }
266 return -1UL;
267}
1da177e4 268
272b9cad
YL
269/*
270 * Find next free range after *start
271 */
c64df707
YL
272unsigned long __init find_e820_area_size(unsigned long start,
273 unsigned long *sizep,
274 unsigned long align)
272b9cad
YL
275{
276 int i;
277
278 for (i = 0; i < e820.nr_map; i++) {
279 struct e820entry *ei = &e820.map[i];
280 unsigned long addr, last;
281 unsigned long ei_last;
282
283 if (ei->type != E820_RAM)
284 continue;
285 addr = round_up(ei->addr, align);
286 ei_last = ei->addr + ei->size;
272b9cad
YL
287 if (addr < start)
288 addr = round_up(start, align);
272b9cad
YL
289 if (addr >= ei_last)
290 continue;
291 *sizep = ei_last - addr;
c64df707
YL
292 while (bad_addr_size(&addr, sizep, align) &&
293 addr + *sizep <= ei_last)
272b9cad
YL
294 ;
295 last = addr + *sizep;
272b9cad
YL
296 if (last > ei_last)
297 continue;
298 return addr;
299 }
300 return -1UL;
301
302}
1da177e4
LT
303/*
304 * Find the highest page frame number we have available
305 */
306unsigned long __init e820_end_of_ram(void)
307{
2f36fa13
TG
308 unsigned long end_pfn;
309
5cb248ab 310 end_pfn = find_max_pfn_with_active_regions();
2f36fa13 311
67794292
TG
312 if (end_pfn > max_pfn_mapped)
313 max_pfn_mapped = end_pfn;
314 if (max_pfn_mapped > MAXMEM>>PAGE_SHIFT)
315 max_pfn_mapped = MAXMEM>>PAGE_SHIFT;
1da177e4
LT
316 if (end_pfn > end_user_pfn)
317 end_pfn = end_user_pfn;
67794292
TG
318 if (end_pfn > max_pfn_mapped)
319 end_pfn = max_pfn_mapped;
1da177e4 320
67794292 321 printk(KERN_INFO "max_pfn_mapped = %lu\n", max_pfn_mapped);
2f36fa13 322 return end_pfn;
1da177e4
LT
323}
324
485761bd 325/*
1da177e4
LT
326 * Mark e820 reserved areas as busy for the resource manager.
327 */
3def3d6d 328void __init e820_reserve_resources(void)
1da177e4
LT
329{
330 int i;
01561264
YL
331 struct resource *res;
332
333 res = alloc_bootmem_low(sizeof(struct resource) * e820.nr_map);
1da177e4 334 for (i = 0; i < e820.nr_map; i++) {
1da177e4
LT
335 switch (e820.map[i].type) {
336 case E820_RAM: res->name = "System RAM"; break;
337 case E820_ACPI: res->name = "ACPI Tables"; break;
338 case E820_NVS: res->name = "ACPI Non-volatile Storage"; break;
339 default: res->name = "reserved";
340 }
341 res->start = e820.map[i].addr;
342 res->end = res->start + e820.map[i].size - 1;
343 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
3def3d6d 344 insert_resource(&iomem_resource, res);
01561264 345 res++;
1da177e4
LT
346 }
347}
348
e8eff5ac
RW
349/*
350 * Find the ranges of physical addresses that do not correspond to
351 * e820 RAM areas and mark the corresponding pages as nosave for software
352 * suspend and suspend to RAM.
353 *
354 * This function requires the e820 map to be sorted and without any
355 * overlapping entries and assumes the first e820 area to be RAM.
356 */
357void __init e820_mark_nosave_regions(void)
358{
359 int i;
360 unsigned long paddr;
361
362 paddr = round_down(e820.map[0].addr + e820.map[0].size, PAGE_SIZE);
363 for (i = 1; i < e820.nr_map; i++) {
364 struct e820entry *ei = &e820.map[i];
365
366 if (paddr < ei->addr)
74dfd666
RW
367 register_nosave_region(PFN_DOWN(paddr),
368 PFN_UP(ei->addr));
e8eff5ac
RW
369
370 paddr = round_down(ei->addr + ei->size, PAGE_SIZE);
371 if (ei->type != E820_RAM)
74dfd666
RW
372 register_nosave_region(PFN_UP(ei->addr),
373 PFN_DOWN(paddr));
e8eff5ac
RW
374
375 if (paddr >= (end_pfn << PAGE_SHIFT))
376 break;
377 }
378}
379
3af044e0
DR
380/*
381 * Finds an active region in the address range from start_pfn to end_pfn and
382 * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
383 */
384static int __init e820_find_active_region(const struct e820entry *ei,
385 unsigned long start_pfn,
386 unsigned long end_pfn,
387 unsigned long *ei_startpfn,
388 unsigned long *ei_endpfn)
389{
390 *ei_startpfn = round_up(ei->addr, PAGE_SIZE) >> PAGE_SHIFT;
391 *ei_endpfn = round_down(ei->addr + ei->size, PAGE_SIZE) >> PAGE_SHIFT;
392
393 /* Skip map entries smaller than a page */
394 if (*ei_startpfn >= *ei_endpfn)
395 return 0;
396
67794292
TG
397 /* Check if max_pfn_mapped should be updated */
398 if (ei->type != E820_RAM && *ei_endpfn > max_pfn_mapped)
399 max_pfn_mapped = *ei_endpfn;
3af044e0
DR
400
401 /* Skip if map is outside the node */
402 if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
403 *ei_startpfn >= end_pfn)
404 return 0;
405
406 /* Check for overlaps */
407 if (*ei_startpfn < start_pfn)
408 *ei_startpfn = start_pfn;
409 if (*ei_endpfn > end_pfn)
410 *ei_endpfn = end_pfn;
411
412 /* Obey end_user_pfn to save on memmap */
413 if (*ei_startpfn >= end_user_pfn)
414 return 0;
415 if (*ei_endpfn > end_user_pfn)
416 *ei_endpfn = end_user_pfn;
417
418 return 1;
419}
420
5cb248ab
MG
421/* Walk the e820 map and register active regions within a node */
422void __init
423e820_register_active_regions(int nid, unsigned long start_pfn,
424 unsigned long end_pfn)
425{
3af044e0
DR
426 unsigned long ei_startpfn;
427 unsigned long ei_endpfn;
5cb248ab 428 int i;
5cb248ab 429
3af044e0
DR
430 for (i = 0; i < e820.nr_map; i++)
431 if (e820_find_active_region(&e820.map[i],
432 start_pfn, end_pfn,
433 &ei_startpfn, &ei_endpfn))
434 add_active_range(nid, ei_startpfn, ei_endpfn);
5cb248ab
MG
435}
436
2f36fa13 437/*
1da177e4 438 * Add a memory region to the kernel e820 map.
2f36fa13 439 */
1da177e4
LT
440void __init add_memory_region(unsigned long start, unsigned long size, int type)
441{
442 int x = e820.nr_map;
443
444 if (x == E820MAX) {
445 printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
446 return;
447 }
448
449 e820.map[x].addr = start;
450 e820.map[x].size = size;
451 e820.map[x].type = type;
452 e820.nr_map++;
453}
454
a7e96629
DR
455/*
456 * Find the hole size (in bytes) in the memory range.
457 * @start: starting address of the memory range to scan
458 * @end: ending address of the memory range to scan
459 */
460unsigned long __init e820_hole_size(unsigned long start, unsigned long end)
461{
462 unsigned long start_pfn = start >> PAGE_SHIFT;
463 unsigned long end_pfn = end >> PAGE_SHIFT;
2f36fa13 464 unsigned long ei_startpfn, ei_endpfn, ram = 0;
a7e96629
DR
465 int i;
466
467 for (i = 0; i < e820.nr_map; i++) {
468 if (e820_find_active_region(&e820.map[i],
469 start_pfn, end_pfn,
470 &ei_startpfn, &ei_endpfn))
471 ram += ei_endpfn - ei_startpfn;
472 }
473 return end - start - (ram << PAGE_SHIFT);
474}
475
013d23e1 476static void __init e820_print_map(char *who)
1da177e4
LT
477{
478 int i;
479
480 for (i = 0; i < e820.nr_map; i++) {
5a3ece79 481 printk(KERN_INFO " %s: %016Lx - %016Lx ", who,
2f36fa13
TG
482 (unsigned long long) e820.map[i].addr,
483 (unsigned long long)
484 (e820.map[i].addr + e820.map[i].size));
1da177e4 485 switch (e820.map[i].type) {
2f36fa13
TG
486 case E820_RAM:
487 printk(KERN_CONT "(usable)\n");
488 break;
1da177e4 489 case E820_RESERVED:
2f36fa13
TG
490 printk(KERN_CONT "(reserved)\n");
491 break;
1da177e4 492 case E820_ACPI:
2f36fa13
TG
493 printk(KERN_CONT "(ACPI data)\n");
494 break;
1da177e4 495 case E820_NVS:
2f36fa13
TG
496 printk(KERN_CONT "(ACPI NVS)\n");
497 break;
498 default:
499 printk(KERN_CONT "type %u\n", e820.map[i].type);
500 break;
1da177e4
LT
501 }
502 }
503}
504
505/*
506 * Sanitize the BIOS e820 map.
507 *
2f36fa13 508 * Some e820 responses include overlapping entries. The following
1da177e4
LT
509 * replaces the original e820 map with a new one, removing overlaps.
510 *
511 */
2f36fa13 512static int __init sanitize_e820_map(struct e820entry *biosmap, char *pnr_map)
1da177e4
LT
513{
514 struct change_member {
515 struct e820entry *pbios; /* pointer to original bios entry */
516 unsigned long long addr; /* address for this change point */
517 };
518 static struct change_member change_point_list[2*E820MAX] __initdata;
519 static struct change_member *change_point[2*E820MAX] __initdata;
520 static struct e820entry *overlap_list[E820MAX] __initdata;
521 static struct e820entry new_bios[E820MAX] __initdata;
522 struct change_member *change_tmp;
523 unsigned long current_type, last_type;
524 unsigned long long last_addr;
525 int chgidx, still_changing;
526 int overlap_entries;
527 int new_bios_entry;
8059b2a2 528 int old_nr, new_nr, chg_nr;
1da177e4
LT
529 int i;
530
531 /*
2f36fa13
TG
532 Visually we're performing the following
533 (1,2,3,4 = memory types)...
1da177e4
LT
534
535 Sample memory map (w/overlaps):
536 ____22__________________
537 ______________________4_
538 ____1111________________
539 _44_____________________
540 11111111________________
541 ____________________33__
542 ___________44___________
543 __________33333_________
544 ______________22________
545 ___________________2222_
546 _________111111111______
547 _____________________11_
548 _________________4______
549
550 Sanitized equivalent (no overlap):
551 1_______________________
552 _44_____________________
553 ___1____________________
554 ____22__________________
555 ______11________________
556 _________1______________
557 __________3_____________
558 ___________44___________
559 _____________33_________
560 _______________2________
561 ________________1_______
562 _________________4______
563 ___________________2____
564 ____________________33__
565 ______________________4_
566 */
567
568 /* if there's only one memory region, don't bother */
569 if (*pnr_map < 2)
570 return -1;
571
572 old_nr = *pnr_map;
573
574 /* bail out if we find any unreasonable addresses in bios map */
2f36fa13 575 for (i = 0; i < old_nr; i++)
1da177e4
LT
576 if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
577 return -1;
578
579 /* create pointers for initial change-point information (for sorting) */
2f36fa13 580 for (i = 0; i < 2 * old_nr; i++)
1da177e4
LT
581 change_point[i] = &change_point_list[i];
582
8059b2a2
VP
583 /* record all known change-points (starting and ending addresses),
584 omitting those that are for empty memory regions */
1da177e4 585 chgidx = 0;
2f36fa13 586 for (i = 0; i < old_nr; i++) {
8059b2a2
VP
587 if (biosmap[i].size != 0) {
588 change_point[chgidx]->addr = biosmap[i].addr;
589 change_point[chgidx++]->pbios = &biosmap[i];
2f36fa13
TG
590 change_point[chgidx]->addr = biosmap[i].addr +
591 biosmap[i].size;
8059b2a2
VP
592 change_point[chgidx++]->pbios = &biosmap[i];
593 }
1da177e4 594 }
8059b2a2 595 chg_nr = chgidx;
1da177e4
LT
596
597 /* sort change-point list by memory addresses (low -> high) */
598 still_changing = 1;
599 while (still_changing) {
600 still_changing = 0;
2f36fa13
TG
601 for (i = 1; i < chg_nr; i++) {
602 unsigned long long curaddr, lastaddr;
603 unsigned long long curpbaddr, lastpbaddr;
604
605 curaddr = change_point[i]->addr;
606 lastaddr = change_point[i - 1]->addr;
607 curpbaddr = change_point[i]->pbios->addr;
608 lastpbaddr = change_point[i - 1]->pbios->addr;
609
610 /*
611 * swap entries, when:
612 *
613 * curaddr > lastaddr or
614 * curaddr == lastaddr and curaddr == curpbaddr and
615 * lastaddr != lastpbaddr
616 */
617 if (curaddr < lastaddr ||
618 (curaddr == lastaddr && curaddr == curpbaddr &&
619 lastaddr != lastpbaddr)) {
1da177e4
LT
620 change_tmp = change_point[i];
621 change_point[i] = change_point[i-1];
622 change_point[i-1] = change_tmp;
2f36fa13 623 still_changing = 1;
1da177e4
LT
624 }
625 }
626 }
627
628 /* create a new bios memory map, removing overlaps */
2f36fa13
TG
629 overlap_entries = 0; /* number of entries in the overlap table */
630 new_bios_entry = 0; /* index for creating new bios map entries */
1da177e4
LT
631 last_type = 0; /* start with undefined memory type */
632 last_addr = 0; /* start with 0 as last starting address */
2f36fa13 633
1da177e4 634 /* loop through change-points, determining affect on the new bios map */
2f36fa13 635 for (chgidx = 0; chgidx < chg_nr; chgidx++) {
1da177e4 636 /* keep track of all overlapping bios entries */
2f36fa13
TG
637 if (change_point[chgidx]->addr ==
638 change_point[chgidx]->pbios->addr) {
639 /*
640 * add map entry to overlap list (> 1 entry
641 * implies an overlap)
642 */
643 overlap_list[overlap_entries++] =
644 change_point[chgidx]->pbios;
645 } else {
646 /*
647 * remove entry from list (order independent,
648 * so swap with last)
649 */
650 for (i = 0; i < overlap_entries; i++) {
651 if (overlap_list[i] ==
652 change_point[chgidx]->pbios)
653 overlap_list[i] =
654 overlap_list[overlap_entries-1];
1da177e4
LT
655 }
656 overlap_entries--;
657 }
2f36fa13
TG
658 /*
659 * if there are overlapping entries, decide which
660 * "type" to use (larger value takes precedence --
661 * 1=usable, 2,3,4,4+=unusable)
662 */
1da177e4 663 current_type = 0;
2f36fa13 664 for (i = 0; i < overlap_entries; i++)
1da177e4
LT
665 if (overlap_list[i]->type > current_type)
666 current_type = overlap_list[i]->type;
2f36fa13
TG
667 /*
668 * continue building up new bios map based on this
669 * information
670 */
1da177e4
LT
671 if (current_type != last_type) {
672 if (last_type != 0) {
673 new_bios[new_bios_entry].size =
674 change_point[chgidx]->addr - last_addr;
2f36fa13
TG
675 /*
676 * move forward only if the new size
677 * was non-zero
678 */
1da177e4 679 if (new_bios[new_bios_entry].size != 0)
2f36fa13
TG
680 /*
681 * no more space left for new
682 * bios entries ?
683 */
1da177e4 684 if (++new_bios_entry >= E820MAX)
2f36fa13 685 break;
1da177e4
LT
686 }
687 if (current_type != 0) {
2f36fa13
TG
688 new_bios[new_bios_entry].addr =
689 change_point[chgidx]->addr;
1da177e4 690 new_bios[new_bios_entry].type = current_type;
2f36fa13 691 last_addr = change_point[chgidx]->addr;
1da177e4
LT
692 }
693 last_type = current_type;
694 }
695 }
2f36fa13
TG
696 /* retain count for new bios entries */
697 new_nr = new_bios_entry;
1da177e4
LT
698
699 /* copy new bios mapping into original location */
2f36fa13 700 memcpy(biosmap, new_bios, new_nr * sizeof(struct e820entry));
1da177e4
LT
701 *pnr_map = new_nr;
702
703 return 0;
704}
705
706/*
707 * Copy the BIOS e820 map into a safe place.
708 *
709 * Sanity-check it while we're at it..
710 *
711 * If we're lucky and live on a modern system, the setup code
712 * will have given us a memory map that we can use to properly
713 * set up memory. If we aren't, we'll fake a memory map.
1da177e4 714 */
2f36fa13 715static int __init copy_e820_map(struct e820entry *biosmap, int nr_map)
1da177e4
LT
716{
717 /* Only one memory region (or negative)? Ignore it */
718 if (nr_map < 2)
719 return -1;
720
721 do {
320a6b2e
AH
722 u64 start = biosmap->addr;
723 u64 size = biosmap->size;
724 u64 end = start + size;
725 u32 type = biosmap->type;
1da177e4
LT
726
727 /* Overflow in 64 bits? Ignore the memory map. */
728 if (start > end)
729 return -1;
730
1da177e4 731 add_memory_region(start, size, type);
2f36fa13 732 } while (biosmap++, --nr_map);
1da177e4
LT
733 return 0;
734}
735
013d23e1 736static void early_panic(char *msg)
1da177e4 737{
8380aabb
AK
738 early_printk(msg);
739 panic(msg);
740}
1da177e4 741
746ef0cd
GOC
742/* We're not void only for x86 32-bit compat */
743char * __init machine_specific_memory_setup(void)
8380aabb 744{
746ef0cd 745 char *who = "BIOS-e820";
1da177e4
LT
746 /*
747 * Try to copy the BIOS-supplied E820-map.
748 *
749 * Otherwise fake a memory map; one section from 0k->640k,
750 * the next section from 1mb->appropriate_mem_k
751 */
30c82645
PA
752 sanitize_e820_map(boot_params.e820_map, &boot_params.e820_entries);
753 if (copy_e820_map(boot_params.e820_map, boot_params.e820_entries) < 0)
8380aabb 754 early_panic("Cannot find a valid memory map");
1da177e4 755 printk(KERN_INFO "BIOS-provided physical RAM map:\n");
746ef0cd
GOC
756 e820_print_map(who);
757
758 /* In case someone cares... */
759 return who;
1da177e4
LT
760}
761
2c8c0e6b
AK
762static int __init parse_memopt(char *p)
763{
764 if (!p)
765 return -EINVAL;
766 end_user_pfn = memparse(p, &p);
2f36fa13 767 end_user_pfn >>= PAGE_SHIFT;
2c8c0e6b 768 return 0;
2f36fa13 769}
2c8c0e6b 770early_param("mem", parse_memopt);
1da177e4 771
2c8c0e6b 772static int userdef __initdata;
1da177e4 773
2c8c0e6b 774static int __init parse_memmap_opt(char *p)
69cda7b1 775{
2c8c0e6b 776 char *oldp;
69cda7b1 777 unsigned long long start_at, mem_size;
778
2c8c0e6b
AK
779 if (!strcmp(p, "exactmap")) {
780#ifdef CONFIG_CRASH_DUMP
2f36fa13
TG
781 /*
782 * If we are doing a crash dump, we still need to know
783 * the real mem size before original memory map is
2c8c0e6b
AK
784 * reset.
785 */
15803a43 786 e820_register_active_regions(0, 0, -1UL);
2c8c0e6b 787 saved_max_pfn = e820_end_of_ram();
15803a43 788 remove_all_active_ranges();
2c8c0e6b 789#endif
67794292 790 max_pfn_mapped = 0;
2c8c0e6b
AK
791 e820.nr_map = 0;
792 userdef = 1;
793 return 0;
794 }
795
796 oldp = p;
797 mem_size = memparse(p, &p);
798 if (p == oldp)
799 return -EINVAL;
b3ca74a2
VB
800
801 userdef = 1;
69cda7b1 802 if (*p == '@') {
2c8c0e6b 803 start_at = memparse(p+1, &p);
69cda7b1 804 add_memory_region(start_at, mem_size, E820_RAM);
805 } else if (*p == '#') {
2c8c0e6b 806 start_at = memparse(p+1, &p);
69cda7b1 807 add_memory_region(start_at, mem_size, E820_ACPI);
808 } else if (*p == '$') {
2c8c0e6b 809 start_at = memparse(p+1, &p);
69cda7b1 810 add_memory_region(start_at, mem_size, E820_RESERVED);
811 } else {
812 end_user_pfn = (mem_size >> PAGE_SHIFT);
813 }
2c8c0e6b
AK
814 return *p == '\0' ? 0 : -EINVAL;
815}
816early_param("memmap", parse_memmap_opt);
817
43999d9e 818void __init finish_e820_parsing(void)
2c8c0e6b
AK
819{
820 if (userdef) {
b3ca74a2
VB
821 char nr = e820.nr_map;
822
823 if (sanitize_e820_map(e820.map, &nr) < 0)
824 early_panic("Invalid user supplied memory map");
825 e820.nr_map = nr;
826
2c8c0e6b
AK
827 printk(KERN_INFO "user-defined physical RAM map:\n");
828 e820_print_map("user");
829 }
69cda7b1 830}
831
5dca6a1b
YL
832void __init update_memory_range(u64 start, u64 size, unsigned old_type,
833 unsigned new_type)
834{
835 int i;
836
837 BUG_ON(old_type == new_type);
838
839 for (i = 0; i < e820.nr_map; i++) {
840 struct e820entry *ei = &e820.map[i];
841 u64 final_start, final_end;
842 if (ei->type != old_type)
843 continue;
844 /* totally covered? */
845 if (ei->addr >= start && ei->size <= size) {
846 ei->type = new_type;
847 continue;
848 }
849 /* partially covered */
850 final_start = max(start, ei->addr);
851 final_end = min(start + size, ei->addr + ei->size);
852 if (final_start >= final_end)
853 continue;
854 add_memory_region(final_start, final_end - final_start,
855 new_type);
856 }
857}
858
aaf23042
YL
859void __init update_e820(void)
860{
861 u8 nr_map;
862
863 nr_map = e820.nr_map;
864 if (sanitize_e820_map(e820.map, &nr_map))
865 return;
866 e820.nr_map = nr_map;
867 printk(KERN_INFO "modified physical RAM map:\n");
868 e820_print_map("modified");
869}
870
a1e97782 871unsigned long pci_mem_start = 0xaeedbabe;
2ee60e17 872EXPORT_SYMBOL(pci_mem_start);
a1e97782
AK
873
874/*
875 * Search for the biggest gap in the low 32 bits of the e820
876 * memory space. We pass this space to PCI to assign MMIO resources
877 * for hotplug or unconfigured devices in.
878 * Hopefully the BIOS let enough space left.
879 */
880__init void e820_setup_gap(void)
881{
f0eca962 882 unsigned long gapstart, gapsize, round;
a1e97782
AK
883 unsigned long last;
884 int i;
885 int found = 0;
886
887 last = 0x100000000ull;
888 gapstart = 0x10000000;
889 gapsize = 0x400000;
890 i = e820.nr_map;
891 while (--i >= 0) {
892 unsigned long long start = e820.map[i].addr;
893 unsigned long long end = start + e820.map[i].size;
894
895 /*
896 * Since "last" is at most 4GB, we know we'll
897 * fit in 32 bits if this condition is true
898 */
899 if (last > end) {
900 unsigned long gap = last - end;
901
902 if (gap > gapsize) {
903 gapsize = gap;
904 gapstart = end;
905 found = 1;
906 }
907 }
908 if (start < last)
909 last = start;
910 }
911
912 if (!found) {
913 gapstart = (end_pfn << PAGE_SHIFT) + 1024*1024;
2f36fa13
TG
914 printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit "
915 "address range\n"
916 KERN_ERR "PCI: Unassigned devices with 32bit resource "
917 "registers may break!\n");
a1e97782
AK
918 }
919
920 /*
f0eca962
DR
921 * See how much we want to round up: start off with
922 * rounding to the next 1MB area.
a1e97782 923 */
f0eca962
DR
924 round = 0x100000;
925 while ((gapsize >> 4) > round)
926 round += round;
927 /* Fun with two's complement */
928 pci_mem_start = (gapstart + round) & -round;
a1e97782 929
2f36fa13
TG
930 printk(KERN_INFO
931 "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
932 pci_mem_start, gapstart, gapsize);
a1e97782 933}
e820482c
KA
934
935int __init arch_get_ram_range(int slot, u64 *addr, u64 *size)
936{
937 int i;
938
939 if (slot < 0 || slot >= e820.nr_map)
940 return -1;
941 for (i = slot; i < e820.nr_map; i++) {
942 if (e820.map[i].type != E820_RAM)
943 continue;
944 break;
945 }
946 if (i == e820.nr_map || e820.map[i].addr > (max_pfn << PAGE_SHIFT))
947 return -1;
948 *addr = e820.map[i].addr;
949 *size = min_t(u64, e820.map[i].size + e820.map[i].addr,
950 max_pfn << PAGE_SHIFT) - *addr;
951 return i + 1;
952}
This page took 0.479007 seconds and 5 git commands to generate.