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