1
2
3
4
5
6
7
8
9
10
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <linux/init.h>
14#include <linux/crash_dump.h>
15#include <linux/export.h>
16#include <linux/bootmem.h>
17#include <linux/pfn.h>
18#include <linux/suspend.h>
19#include <linux/acpi.h>
20#include <linux/firmware-map.h>
21#include <linux/memblock.h>
22#include <linux/sort.h>
23
24#include <asm/e820.h>
25#include <asm/proto.h>
26#include <asm/setup.h>
27#include <asm/cpufeature.h>
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43struct e820map e820;
44struct e820map e820_saved;
45
46
47unsigned long pci_mem_start = 0xaeedbabe;
48#ifdef CONFIG_PCI
49EXPORT_SYMBOL(pci_mem_start);
50#endif
51
52
53
54
55
56int
57e820_any_mapped(u64 start, u64 end, unsigned type)
58{
59 int i;
60
61 for (i = 0; i < e820.nr_map; i++) {
62 struct e820entry *ei = &e820.map[i];
63
64 if (type && ei->type != type)
65 continue;
66 if (ei->addr >= end || ei->addr + ei->size <= start)
67 continue;
68 return 1;
69 }
70 return 0;
71}
72EXPORT_SYMBOL_GPL(e820_any_mapped);
73
74
75
76
77
78
79
80int __init e820_all_mapped(u64 start, u64 end, unsigned type)
81{
82 int i;
83
84 for (i = 0; i < e820.nr_map; i++) {
85 struct e820entry *ei = &e820.map[i];
86
87 if (type && ei->type != type)
88 continue;
89
90 if (ei->addr >= end || ei->addr + ei->size <= start)
91 continue;
92
93
94
95
96 if (ei->addr <= start)
97 start = ei->addr + ei->size;
98
99
100
101
102 if (start >= end)
103 return 1;
104 }
105 return 0;
106}
107
108
109
110
111static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
112 int type)
113{
114 int x = e820x->nr_map;
115
116 if (x >= ARRAY_SIZE(e820x->map)) {
117 printk(KERN_ERR "e820: too many entries; ignoring [mem %#010llx-%#010llx]\n",
118 (unsigned long long) start,
119 (unsigned long long) (start + size - 1));
120 return;
121 }
122
123 e820x->map[x].addr = start;
124 e820x->map[x].size = size;
125 e820x->map[x].type = type;
126 e820x->nr_map++;
127}
128
129void __init e820_add_region(u64 start, u64 size, int type)
130{
131 __e820_add_region(&e820, start, size, type);
132}
133
134static void __init e820_print_type(u32 type)
135{
136 switch (type) {
137 case E820_RAM:
138 case E820_RESERVED_KERN:
139 printk(KERN_CONT "usable");
140 break;
141 case E820_RESERVED:
142 printk(KERN_CONT "reserved");
143 break;
144 case E820_ACPI:
145 printk(KERN_CONT "ACPI data");
146 break;
147 case E820_NVS:
148 printk(KERN_CONT "ACPI NVS");
149 break;
150 case E820_UNUSABLE:
151 printk(KERN_CONT "unusable");
152 break;
153 case E820_PMEM:
154 case E820_PRAM:
155 printk(KERN_CONT "persistent (type %u)", type);
156 break;
157 default:
158 printk(KERN_CONT "type %u", type);
159 break;
160 }
161}
162
163void __init e820_print_map(char *who)
164{
165 int i;
166
167 for (i = 0; i < e820.nr_map; i++) {
168 printk(KERN_INFO "%s: [mem %#018Lx-%#018Lx] ", who,
169 (unsigned long long) e820.map[i].addr,
170 (unsigned long long)
171 (e820.map[i].addr + e820.map[i].size - 1));
172 e820_print_type(e820.map[i].type);
173 printk(KERN_CONT "\n");
174 }
175}
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238struct change_member {
239 struct e820entry *pbios;
240 unsigned long long addr;
241};
242
243static int __init cpcompare(const void *a, const void *b)
244{
245 struct change_member * const *app = a, * const *bpp = b;
246 const struct change_member *ap = *app, *bp = *bpp;
247
248
249
250
251
252
253
254 if (ap->addr != bp->addr)
255 return ap->addr > bp->addr ? 1 : -1;
256
257 return (ap->addr != ap->pbios->addr) - (bp->addr != bp->pbios->addr);
258}
259
260int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
261 u32 *pnr_map)
262{
263 static struct change_member change_point_list[2*E820_X_MAX] __initdata;
264 static struct change_member *change_point[2*E820_X_MAX] __initdata;
265 static struct e820entry *overlap_list[E820_X_MAX] __initdata;
266 static struct e820entry new_bios[E820_X_MAX] __initdata;
267 unsigned long current_type, last_type;
268 unsigned long long last_addr;
269 int chgidx;
270 int overlap_entries;
271 int new_bios_entry;
272 int old_nr, new_nr, chg_nr;
273 int i;
274
275
276 if (*pnr_map < 2)
277 return -1;
278
279 old_nr = *pnr_map;
280 BUG_ON(old_nr > max_nr_map);
281
282
283 for (i = 0; i < old_nr; i++)
284 if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
285 return -1;
286
287
288 for (i = 0; i < 2 * old_nr; i++)
289 change_point[i] = &change_point_list[i];
290
291
292
293 chgidx = 0;
294 for (i = 0; i < old_nr; i++) {
295 if (biosmap[i].size != 0) {
296 change_point[chgidx]->addr = biosmap[i].addr;
297 change_point[chgidx++]->pbios = &biosmap[i];
298 change_point[chgidx]->addr = biosmap[i].addr +
299 biosmap[i].size;
300 change_point[chgidx++]->pbios = &biosmap[i];
301 }
302 }
303 chg_nr = chgidx;
304
305
306 sort(change_point, chg_nr, sizeof *change_point, cpcompare, NULL);
307
308
309 overlap_entries = 0;
310 new_bios_entry = 0;
311 last_type = 0;
312 last_addr = 0;
313
314
315 for (chgidx = 0; chgidx < chg_nr; chgidx++) {
316
317 if (change_point[chgidx]->addr ==
318 change_point[chgidx]->pbios->addr) {
319
320
321
322
323 overlap_list[overlap_entries++] =
324 change_point[chgidx]->pbios;
325 } else {
326
327
328
329
330 for (i = 0; i < overlap_entries; i++) {
331 if (overlap_list[i] ==
332 change_point[chgidx]->pbios)
333 overlap_list[i] =
334 overlap_list[overlap_entries-1];
335 }
336 overlap_entries--;
337 }
338
339
340
341
342
343 current_type = 0;
344 for (i = 0; i < overlap_entries; i++)
345 if (overlap_list[i]->type > current_type)
346 current_type = overlap_list[i]->type;
347
348
349
350
351 if (current_type != last_type || current_type == E820_PRAM) {
352 if (last_type != 0) {
353 new_bios[new_bios_entry].size =
354 change_point[chgidx]->addr - last_addr;
355
356
357
358
359 if (new_bios[new_bios_entry].size != 0)
360
361
362
363
364 if (++new_bios_entry >= max_nr_map)
365 break;
366 }
367 if (current_type != 0) {
368 new_bios[new_bios_entry].addr =
369 change_point[chgidx]->addr;
370 new_bios[new_bios_entry].type = current_type;
371 last_addr = change_point[chgidx]->addr;
372 }
373 last_type = current_type;
374 }
375 }
376
377 new_nr = new_bios_entry;
378
379
380 memcpy(biosmap, new_bios, new_nr * sizeof(struct e820entry));
381 *pnr_map = new_nr;
382
383 return 0;
384}
385
386static int __init __append_e820_map(struct e820entry *biosmap, int nr_map)
387{
388 while (nr_map) {
389 u64 start = biosmap->addr;
390 u64 size = biosmap->size;
391 u64 end = start + size;
392 u32 type = biosmap->type;
393
394
395 if (start > end)
396 return -1;
397
398 e820_add_region(start, size, type);
399
400 biosmap++;
401 nr_map--;
402 }
403 return 0;
404}
405
406
407
408
409
410
411
412
413
414
415static int __init append_e820_map(struct e820entry *biosmap, int nr_map)
416{
417
418 if (nr_map < 2)
419 return -1;
420
421 return __append_e820_map(biosmap, nr_map);
422}
423
424static u64 __init __e820_update_range(struct e820map *e820x, u64 start,
425 u64 size, unsigned old_type,
426 unsigned new_type)
427{
428 u64 end;
429 unsigned int i;
430 u64 real_updated_size = 0;
431
432 BUG_ON(old_type == new_type);
433
434 if (size > (ULLONG_MAX - start))
435 size = ULLONG_MAX - start;
436
437 end = start + size;
438 printk(KERN_DEBUG "e820: update [mem %#010Lx-%#010Lx] ",
439 (unsigned long long) start, (unsigned long long) (end - 1));
440 e820_print_type(old_type);
441 printk(KERN_CONT " ==> ");
442 e820_print_type(new_type);
443 printk(KERN_CONT "\n");
444
445 for (i = 0; i < e820x->nr_map; i++) {
446 struct e820entry *ei = &e820x->map[i];
447 u64 final_start, final_end;
448 u64 ei_end;
449
450 if (ei->type != old_type)
451 continue;
452
453 ei_end = ei->addr + ei->size;
454
455 if (ei->addr >= start && ei_end <= end) {
456 ei->type = new_type;
457 real_updated_size += ei->size;
458 continue;
459 }
460
461
462 if (ei->addr < start && ei_end > end) {
463 __e820_add_region(e820x, start, size, new_type);
464 __e820_add_region(e820x, end, ei_end - end, ei->type);
465 ei->size = start - ei->addr;
466 real_updated_size += size;
467 continue;
468 }
469
470
471 final_start = max(start, ei->addr);
472 final_end = min(end, ei_end);
473 if (final_start >= final_end)
474 continue;
475
476 __e820_add_region(e820x, final_start, final_end - final_start,
477 new_type);
478
479 real_updated_size += final_end - final_start;
480
481
482
483
484
485 ei->size -= final_end - final_start;
486 if (ei->addr < final_start)
487 continue;
488 ei->addr = final_end;
489 }
490 return real_updated_size;
491}
492
493u64 __init e820_update_range(u64 start, u64 size, unsigned old_type,
494 unsigned new_type)
495{
496 return __e820_update_range(&e820, start, size, old_type, new_type);
497}
498
499static u64 __init e820_update_range_saved(u64 start, u64 size,
500 unsigned old_type, unsigned new_type)
501{
502 return __e820_update_range(&e820_saved, start, size, old_type,
503 new_type);
504}
505
506
507u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
508 int checktype)
509{
510 int i;
511 u64 end;
512 u64 real_removed_size = 0;
513
514 if (size > (ULLONG_MAX - start))
515 size = ULLONG_MAX - start;
516
517 end = start + size;
518 printk(KERN_DEBUG "e820: remove [mem %#010Lx-%#010Lx] ",
519 (unsigned long long) start, (unsigned long long) (end - 1));
520 if (checktype)
521 e820_print_type(old_type);
522 printk(KERN_CONT "\n");
523
524 for (i = 0; i < e820.nr_map; i++) {
525 struct e820entry *ei = &e820.map[i];
526 u64 final_start, final_end;
527 u64 ei_end;
528
529 if (checktype && ei->type != old_type)
530 continue;
531
532 ei_end = ei->addr + ei->size;
533
534 if (ei->addr >= start && ei_end <= end) {
535 real_removed_size += ei->size;
536 memset(ei, 0, sizeof(struct e820entry));
537 continue;
538 }
539
540
541 if (ei->addr < start && ei_end > end) {
542 e820_add_region(end, ei_end - end, ei->type);
543 ei->size = start - ei->addr;
544 real_removed_size += size;
545 continue;
546 }
547
548
549 final_start = max(start, ei->addr);
550 final_end = min(end, ei_end);
551 if (final_start >= final_end)
552 continue;
553 real_removed_size += final_end - final_start;
554
555
556
557
558
559 ei->size -= final_end - final_start;
560 if (ei->addr < final_start)
561 continue;
562 ei->addr = final_end;
563 }
564 return real_removed_size;
565}
566
567void __init update_e820(void)
568{
569 if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map))
570 return;
571 printk(KERN_INFO "e820: modified physical RAM map:\n");
572 e820_print_map("modified");
573}
574static void __init update_e820_saved(void)
575{
576 sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map),
577 &e820_saved.nr_map);
578}
579#define MAX_GAP_END 0x100000000ull
580
581
582
583__init int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
584 unsigned long start_addr, unsigned long long end_addr)
585{
586 unsigned long long last;
587 int i = e820.nr_map;
588 int found = 0;
589
590 last = (end_addr && end_addr < MAX_GAP_END) ? end_addr : MAX_GAP_END;
591
592 while (--i >= 0) {
593 unsigned long long start = e820.map[i].addr;
594 unsigned long long end = start + e820.map[i].size;
595
596 if (end < start_addr)
597 continue;
598
599
600
601
602
603 if (last > end) {
604 unsigned long gap = last - end;
605
606 if (gap >= *gapsize) {
607 *gapsize = gap;
608 *gapstart = end;
609 found = 1;
610 }
611 }
612 if (start < last)
613 last = start;
614 }
615 return found;
616}
617
618
619
620
621
622
623
624__init void e820_setup_gap(void)
625{
626 unsigned long gapstart, gapsize;
627 int found;
628
629 gapstart = 0x10000000;
630 gapsize = 0x400000;
631 found = e820_search_gap(&gapstart, &gapsize, 0, MAX_GAP_END);
632
633#ifdef CONFIG_X86_64
634 if (!found) {
635 gapstart = (max_pfn << PAGE_SHIFT) + 1024*1024;
636 printk(KERN_ERR
637 "e820: cannot find a gap in the 32bit address range\n"
638 "e820: PCI devices with unassigned 32bit BARs may break!\n");
639 }
640#endif
641
642
643
644
645 pci_mem_start = gapstart;
646
647 printk(KERN_INFO
648 "e820: [mem %#010lx-%#010lx] available for PCI devices\n",
649 gapstart, gapstart + gapsize - 1);
650}
651
652
653
654
655
656
657
658void __init parse_e820_ext(u64 phys_addr, u32 data_len)
659{
660 int entries;
661 struct e820entry *extmap;
662 struct setup_data *sdata;
663
664 sdata = early_memremap(phys_addr, data_len);
665 entries = sdata->len / sizeof(struct e820entry);
666 extmap = (struct e820entry *)(sdata->data);
667 __append_e820_map(extmap, entries);
668 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
669 early_memunmap(sdata, data_len);
670 printk(KERN_INFO "e820: extended physical RAM map:\n");
671 e820_print_map("extended");
672}
673
674#if defined(CONFIG_X86_64) || \
675 (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
676
677
678
679
680
681
682
683
684void __init e820_mark_nosave_regions(unsigned long limit_pfn)
685{
686 int i;
687 unsigned long pfn = 0;
688
689 for (i = 0; i < e820.nr_map; i++) {
690 struct e820entry *ei = &e820.map[i];
691
692 if (pfn < PFN_UP(ei->addr))
693 register_nosave_region(pfn, PFN_UP(ei->addr));
694
695 pfn = PFN_DOWN(ei->addr + ei->size);
696
697 if (ei->type != E820_RAM && ei->type != E820_RESERVED_KERN)
698 register_nosave_region(PFN_UP(ei->addr), pfn);
699
700 if (pfn >= limit_pfn)
701 break;
702 }
703}
704#endif
705
706#ifdef CONFIG_ACPI
707
708
709
710
711static int __init e820_mark_nvs_memory(void)
712{
713 int i;
714
715 for (i = 0; i < e820.nr_map; i++) {
716 struct e820entry *ei = &e820.map[i];
717
718 if (ei->type == E820_NVS)
719 acpi_nvs_register(ei->addr, ei->size);
720 }
721
722 return 0;
723}
724core_initcall(e820_mark_nvs_memory);
725#endif
726
727
728
729
730u64 __init early_reserve_e820(u64 size, u64 align)
731{
732 u64 addr;
733
734 addr = __memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ACCESSIBLE);
735 if (addr) {
736 e820_update_range_saved(addr, size, E820_RAM, E820_RESERVED);
737 printk(KERN_INFO "e820: update e820_saved for early_reserve_e820\n");
738 update_e820_saved();
739 }
740
741 return addr;
742}
743
744#ifdef CONFIG_X86_32
745# ifdef CONFIG_X86_PAE
746# define MAX_ARCH_PFN (1ULL<<(36-PAGE_SHIFT))
747# else
748# define MAX_ARCH_PFN (1ULL<<(32-PAGE_SHIFT))
749# endif
750#else
751# define MAX_ARCH_PFN MAXMEM>>PAGE_SHIFT
752#endif
753
754
755
756
757static unsigned long __init e820_end_pfn(unsigned long limit_pfn)
758{
759 int i;
760 unsigned long last_pfn = 0;
761 unsigned long max_arch_pfn = MAX_ARCH_PFN;
762
763 for (i = 0; i < e820.nr_map; i++) {
764 struct e820entry *ei = &e820.map[i];
765 unsigned long start_pfn;
766 unsigned long end_pfn;
767
768
769
770
771
772 if (ei->type != E820_RAM && ei->type != E820_PRAM)
773 continue;
774
775 start_pfn = ei->addr >> PAGE_SHIFT;
776 end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT;
777
778 if (start_pfn >= limit_pfn)
779 continue;
780 if (end_pfn > limit_pfn) {
781 last_pfn = limit_pfn;
782 break;
783 }
784 if (end_pfn > last_pfn)
785 last_pfn = end_pfn;
786 }
787
788 if (last_pfn > max_arch_pfn)
789 last_pfn = max_arch_pfn;
790
791 printk(KERN_INFO "e820: last_pfn = %#lx max_arch_pfn = %#lx\n",
792 last_pfn, max_arch_pfn);
793 return last_pfn;
794}
795unsigned long __init e820_end_of_ram_pfn(void)
796{
797 return e820_end_pfn(MAX_ARCH_PFN);
798}
799
800unsigned long __init e820_end_of_low_ram_pfn(void)
801{
802 return e820_end_pfn(1UL << (32-PAGE_SHIFT));
803}
804
805static void early_panic(char *msg)
806{
807 early_printk(msg);
808 panic(msg);
809}
810
811static int userdef __initdata;
812
813
814static int __init parse_memopt(char *p)
815{
816 u64 mem_size;
817
818 if (!p)
819 return -EINVAL;
820
821 if (!strcmp(p, "nopentium")) {
822#ifdef CONFIG_X86_32
823 setup_clear_cpu_cap(X86_FEATURE_PSE);
824 return 0;
825#else
826 printk(KERN_WARNING "mem=nopentium ignored! (only supported on x86_32)\n");
827 return -EINVAL;
828#endif
829 }
830
831 userdef = 1;
832 mem_size = memparse(p, &p);
833
834 if (mem_size == 0)
835 return -EINVAL;
836 e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
837
838 return 0;
839}
840early_param("mem", parse_memopt);
841
842static int __init parse_memmap_one(char *p)
843{
844 char *oldp;
845 u64 start_at, mem_size;
846
847 if (!p)
848 return -EINVAL;
849
850 if (!strncmp(p, "exactmap", 8)) {
851#ifdef CONFIG_CRASH_DUMP
852
853
854
855
856
857 saved_max_pfn = e820_end_of_ram_pfn();
858#endif
859 e820.nr_map = 0;
860 userdef = 1;
861 return 0;
862 }
863
864 oldp = p;
865 mem_size = memparse(p, &p);
866 if (p == oldp)
867 return -EINVAL;
868
869 userdef = 1;
870 if (*p == '@') {
871 start_at = memparse(p+1, &p);
872 e820_add_region(start_at, mem_size, E820_RAM);
873 } else if (*p == '#') {
874 start_at = memparse(p+1, &p);
875 e820_add_region(start_at, mem_size, E820_ACPI);
876 } else if (*p == '$') {
877 start_at = memparse(p+1, &p);
878 e820_add_region(start_at, mem_size, E820_RESERVED);
879 } else if (*p == '!') {
880 start_at = memparse(p+1, &p);
881 e820_add_region(start_at, mem_size, E820_PRAM);
882 } else
883 e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
884
885 return *p == '\0' ? 0 : -EINVAL;
886}
887static int __init parse_memmap_opt(char *str)
888{
889 while (str) {
890 char *k = strchr(str, ',');
891
892 if (k)
893 *k++ = 0;
894
895 parse_memmap_one(str);
896 str = k;
897 }
898
899 return 0;
900}
901early_param("memmap", parse_memmap_opt);
902
903void __init finish_e820_parsing(void)
904{
905 if (userdef) {
906 if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map),
907 &e820.nr_map) < 0)
908 early_panic("Invalid user supplied memory map");
909
910 printk(KERN_INFO "e820: user-defined physical RAM map:\n");
911 e820_print_map("user");
912 }
913}
914
915static const char *e820_type_to_string(int e820_type)
916{
917 switch (e820_type) {
918 case E820_RESERVED_KERN:
919 case E820_RAM: return "System RAM";
920 case E820_ACPI: return "ACPI Tables";
921 case E820_NVS: return "ACPI Non-volatile Storage";
922 case E820_UNUSABLE: return "Unusable memory";
923 case E820_PRAM: return "Persistent Memory (legacy)";
924 case E820_PMEM: return "Persistent Memory";
925 default: return "reserved";
926 }
927}
928
929static unsigned long e820_type_to_iomem_type(int e820_type)
930{
931 switch (e820_type) {
932 case E820_RESERVED_KERN:
933 case E820_RAM:
934 return IORESOURCE_SYSTEM_RAM;
935 case E820_ACPI:
936 case E820_NVS:
937 case E820_UNUSABLE:
938 case E820_PRAM:
939 case E820_PMEM:
940 default:
941 return IORESOURCE_MEM;
942 }
943}
944
945static unsigned long e820_type_to_iores_desc(int e820_type)
946{
947 switch (e820_type) {
948 case E820_ACPI:
949 return IORES_DESC_ACPI_TABLES;
950 case E820_NVS:
951 return IORES_DESC_ACPI_NV_STORAGE;
952 case E820_PMEM:
953 return IORES_DESC_PERSISTENT_MEMORY;
954 case E820_PRAM:
955 return IORES_DESC_PERSISTENT_MEMORY_LEGACY;
956 case E820_RESERVED_KERN:
957 case E820_RAM:
958 case E820_UNUSABLE:
959 default:
960 return IORES_DESC_NONE;
961 }
962}
963
964static bool do_mark_busy(u32 type, struct resource *res)
965{
966
967 if (res->start < (1ULL<<20))
968 return true;
969
970
971
972
973
974 switch (type) {
975 case E820_RESERVED:
976 case E820_PRAM:
977 case E820_PMEM:
978 return false;
979 default:
980 return true;
981 }
982}
983
984
985
986
987static struct resource __initdata *e820_res;
988void __init e820_reserve_resources(void)
989{
990 int i;
991 struct resource *res;
992 u64 end;
993
994 res = alloc_bootmem(sizeof(struct resource) * e820.nr_map);
995 e820_res = res;
996 for (i = 0; i < e820.nr_map; i++) {
997 end = e820.map[i].addr + e820.map[i].size - 1;
998 if (end != (resource_size_t)end) {
999 res++;
1000 continue;
1001 }
1002 res->name = e820_type_to_string(e820.map[i].type);
1003 res->start = e820.map[i].addr;
1004 res->end = end;
1005
1006 res->flags = e820_type_to_iomem_type(e820.map[i].type);
1007 res->desc = e820_type_to_iores_desc(e820.map[i].type);
1008
1009
1010
1011
1012
1013
1014 if (do_mark_busy(e820.map[i].type, res)) {
1015 res->flags |= IORESOURCE_BUSY;
1016 insert_resource(&iomem_resource, res);
1017 }
1018 res++;
1019 }
1020
1021 for (i = 0; i < e820_saved.nr_map; i++) {
1022 struct e820entry *entry = &e820_saved.map[i];
1023 firmware_map_add_early(entry->addr,
1024 entry->addr + entry->size,
1025 e820_type_to_string(entry->type));
1026 }
1027}
1028
1029
1030static unsigned long ram_alignment(resource_size_t pos)
1031{
1032 unsigned long mb = pos >> 20;
1033
1034
1035 if (!mb)
1036 return 64*1024;
1037
1038
1039 if (mb < 16)
1040 return 1024*1024;
1041
1042
1043 return 64*1024*1024;
1044}
1045
1046#define MAX_RESOURCE_SIZE ((resource_size_t)-1)
1047
1048void __init e820_reserve_resources_late(void)
1049{
1050 int i;
1051 struct resource *res;
1052
1053 res = e820_res;
1054 for (i = 0; i < e820.nr_map; i++) {
1055 if (!res->parent && res->end)
1056 insert_resource_expand_to_fit(&iomem_resource, res);
1057 res++;
1058 }
1059
1060
1061
1062
1063
1064 for (i = 0; i < e820.nr_map; i++) {
1065 struct e820entry *entry = &e820.map[i];
1066 u64 start, end;
1067
1068 if (entry->type != E820_RAM)
1069 continue;
1070 start = entry->addr + entry->size;
1071 end = round_up(start, ram_alignment(start)) - 1;
1072 if (end > MAX_RESOURCE_SIZE)
1073 end = MAX_RESOURCE_SIZE;
1074 if (start >= end)
1075 continue;
1076 printk(KERN_DEBUG
1077 "e820: reserve RAM buffer [mem %#010llx-%#010llx]\n",
1078 start, end);
1079 reserve_region_with_split(&iomem_resource, start, end,
1080 "RAM buffer");
1081 }
1082}
1083
1084char *__init default_machine_specific_memory_setup(void)
1085{
1086 char *who = "BIOS-e820";
1087 u32 new_nr;
1088
1089
1090
1091
1092
1093
1094 new_nr = boot_params.e820_entries;
1095 sanitize_e820_map(boot_params.e820_map,
1096 ARRAY_SIZE(boot_params.e820_map),
1097 &new_nr);
1098 boot_params.e820_entries = new_nr;
1099 if (append_e820_map(boot_params.e820_map, boot_params.e820_entries)
1100 < 0) {
1101 u64 mem_size;
1102
1103
1104 if (boot_params.alt_mem_k
1105 < boot_params.screen_info.ext_mem_k) {
1106 mem_size = boot_params.screen_info.ext_mem_k;
1107 who = "BIOS-88";
1108 } else {
1109 mem_size = boot_params.alt_mem_k;
1110 who = "BIOS-e801";
1111 }
1112
1113 e820.nr_map = 0;
1114 e820_add_region(0, LOWMEMSIZE(), E820_RAM);
1115 e820_add_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
1116 }
1117
1118
1119 return who;
1120}
1121
1122void __init setup_memory_map(void)
1123{
1124 char *who;
1125
1126 who = x86_init.resources.memory_setup();
1127 memcpy(&e820_saved, &e820, sizeof(struct e820map));
1128 printk(KERN_INFO "e820: BIOS-provided physical RAM map:\n");
1129 e820_print_map(who);
1130}
1131
1132void __init memblock_x86_fill(void)
1133{
1134 int i;
1135 u64 end;
1136
1137
1138
1139
1140
1141
1142 memblock_allow_resize();
1143
1144 for (i = 0; i < e820.nr_map; i++) {
1145 struct e820entry *ei = &e820.map[i];
1146
1147 end = ei->addr + ei->size;
1148 if (end != (resource_size_t)end)
1149 continue;
1150
1151 if (ei->type != E820_RAM && ei->type != E820_RESERVED_KERN)
1152 continue;
1153
1154 memblock_add(ei->addr, ei->size);
1155 }
1156
1157
1158 memblock_trim_memory(PAGE_SIZE);
1159
1160 memblock_dump_all();
1161}
1162
1163void __init memblock_find_dma_reserve(void)
1164{
1165#ifdef CONFIG_X86_64
1166 u64 nr_pages = 0, nr_free_pages = 0;
1167 unsigned long start_pfn, end_pfn;
1168 phys_addr_t start, end;
1169 int i;
1170 u64 u;
1171
1172
1173
1174
1175
1176
1177 for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, NULL) {
1178 start_pfn = min(start_pfn, MAX_DMA_PFN);
1179 end_pfn = min(end_pfn, MAX_DMA_PFN);
1180 nr_pages += end_pfn - start_pfn;
1181 }
1182
1183 for_each_free_mem_range(u, NUMA_NO_NODE, MEMBLOCK_NONE, &start, &end,
1184 NULL) {
1185 start_pfn = min_t(unsigned long, PFN_UP(start), MAX_DMA_PFN);
1186 end_pfn = min_t(unsigned long, PFN_DOWN(end), MAX_DMA_PFN);
1187 if (start_pfn < end_pfn)
1188 nr_free_pages += end_pfn - start_pfn;
1189 }
1190
1191 set_dma_reserve(nr_pages - nr_free_pages);
1192#endif
1193}
1194