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