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/bootmem.h>
15#include <linux/ioport.h>
16#include <linux/string.h>
17#include <linux/kexec.h>
18#include <linux/module.h>
19#include <linux/mm.h>
20#include <linux/pfn.h>
21#include <linux/suspend.h>
22#include <linux/firmware-map.h>
23
24#include <asm/pgtable.h>
25#include <asm/page.h>
26#include <asm/e820.h>
27#include <asm/proto.h>
28#include <asm/setup.h>
29#include <asm/trampoline.h>
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45struct e820map e820;
46struct e820map e820_saved;
47
48
49unsigned long pci_mem_start = 0xaeedbabe;
50#ifdef CONFIG_PCI
51EXPORT_SYMBOL(pci_mem_start);
52#endif
53
54
55
56
57
58int
59e820_any_mapped(u64 start, u64 end, unsigned type)
60{
61 int i;
62
63 for (i = 0; i < e820.nr_map; i++) {
64 struct e820entry *ei = &e820.map[i];
65
66 if (type && ei->type != type)
67 continue;
68 if (ei->addr >= end || ei->addr + ei->size <= start)
69 continue;
70 return 1;
71 }
72 return 0;
73}
74EXPORT_SYMBOL_GPL(e820_any_mapped);
75
76
77
78
79
80
81
82int __init e820_all_mapped(u64 start, u64 end, unsigned type)
83{
84 int i;
85
86 for (i = 0; i < e820.nr_map; i++) {
87 struct e820entry *ei = &e820.map[i];
88
89 if (type && ei->type != type)
90 continue;
91
92 if (ei->addr >= end || ei->addr + ei->size <= start)
93 continue;
94
95
96
97
98 if (ei->addr <= start)
99 start = ei->addr + ei->size;
100
101
102
103
104 if (start >= end)
105 return 1;
106 }
107 return 0;
108}
109
110
111
112
113static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
114 int type)
115{
116 int x = e820x->nr_map;
117
118 if (x >= ARRAY_SIZE(e820x->map)) {
119 printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
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 default:
154 printk(KERN_CONT "type %u", type);
155 break;
156 }
157}
158
159void __init e820_print_map(char *who)
160{
161 int i;
162
163 for (i = 0; i < e820.nr_map; i++) {
164 printk(KERN_INFO " %s: %016Lx - %016Lx ", who,
165 (unsigned long long) e820.map[i].addr,
166 (unsigned long long)
167 (e820.map[i].addr + e820.map[i].size));
168 e820_print_type(e820.map[i].type);
169 printk(KERN_CONT "\n");
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
233
234
235int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
236 u32 *pnr_map)
237{
238 struct change_member {
239 struct e820entry *pbios;
240 unsigned long long addr;
241 };
242 static struct change_member change_point_list[2*E820_X_MAX] __initdata;
243 static struct change_member *change_point[2*E820_X_MAX] __initdata;
244 static struct e820entry *overlap_list[E820_X_MAX] __initdata;
245 static struct e820entry new_bios[E820_X_MAX] __initdata;
246 struct change_member *change_tmp;
247 unsigned long current_type, last_type;
248 unsigned long long last_addr;
249 int chgidx, still_changing;
250 int overlap_entries;
251 int new_bios_entry;
252 int old_nr, new_nr, chg_nr;
253 int i;
254
255
256 if (*pnr_map < 2)
257 return -1;
258
259 old_nr = *pnr_map;
260 BUG_ON(old_nr > max_nr_map);
261
262
263 for (i = 0; i < old_nr; i++)
264 if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
265 return -1;
266
267
268 for (i = 0; i < 2 * old_nr; i++)
269 change_point[i] = &change_point_list[i];
270
271
272
273 chgidx = 0;
274 for (i = 0; i < old_nr; i++) {
275 if (biosmap[i].size != 0) {
276 change_point[chgidx]->addr = biosmap[i].addr;
277 change_point[chgidx++]->pbios = &biosmap[i];
278 change_point[chgidx]->addr = biosmap[i].addr +
279 biosmap[i].size;
280 change_point[chgidx++]->pbios = &biosmap[i];
281 }
282 }
283 chg_nr = chgidx;
284
285
286 still_changing = 1;
287 while (still_changing) {
288 still_changing = 0;
289 for (i = 1; i < chg_nr; i++) {
290 unsigned long long curaddr, lastaddr;
291 unsigned long long curpbaddr, lastpbaddr;
292
293 curaddr = change_point[i]->addr;
294 lastaddr = change_point[i - 1]->addr;
295 curpbaddr = change_point[i]->pbios->addr;
296 lastpbaddr = change_point[i - 1]->pbios->addr;
297
298
299
300
301
302
303
304
305 if (curaddr < lastaddr ||
306 (curaddr == lastaddr && curaddr == curpbaddr &&
307 lastaddr != lastpbaddr)) {
308 change_tmp = change_point[i];
309 change_point[i] = change_point[i-1];
310 change_point[i-1] = change_tmp;
311 still_changing = 1;
312 }
313 }
314 }
315
316
317 overlap_entries = 0;
318 new_bios_entry = 0;
319 last_type = 0;
320 last_addr = 0;
321
322
323 for (chgidx = 0; chgidx < chg_nr; chgidx++) {
324
325 if (change_point[chgidx]->addr ==
326 change_point[chgidx]->pbios->addr) {
327
328
329
330
331 overlap_list[overlap_entries++] =
332 change_point[chgidx]->pbios;
333 } else {
334
335
336
337
338 for (i = 0; i < overlap_entries; i++) {
339 if (overlap_list[i] ==
340 change_point[chgidx]->pbios)
341 overlap_list[i] =
342 overlap_list[overlap_entries-1];
343 }
344 overlap_entries--;
345 }
346
347
348
349
350
351 current_type = 0;
352 for (i = 0; i < overlap_entries; i++)
353 if (overlap_list[i]->type > current_type)
354 current_type = overlap_list[i]->type;
355
356
357
358
359 if (current_type != last_type) {
360 if (last_type != 0) {
361 new_bios[new_bios_entry].size =
362 change_point[chgidx]->addr - last_addr;
363
364
365
366
367 if (new_bios[new_bios_entry].size != 0)
368
369
370
371
372 if (++new_bios_entry >= max_nr_map)
373 break;
374 }
375 if (current_type != 0) {
376 new_bios[new_bios_entry].addr =
377 change_point[chgidx]->addr;
378 new_bios[new_bios_entry].type = current_type;
379 last_addr = change_point[chgidx]->addr;
380 }
381 last_type = current_type;
382 }
383 }
384
385 new_nr = new_bios_entry;
386
387
388 memcpy(biosmap, new_bios, new_nr * sizeof(struct e820entry));
389 *pnr_map = new_nr;
390
391 return 0;
392}
393
394static int __init __append_e820_map(struct e820entry *biosmap, int nr_map)
395{
396 while (nr_map) {
397 u64 start = biosmap->addr;
398 u64 size = biosmap->size;
399 u64 end = start + size;
400 u32 type = biosmap->type;
401
402
403 if (start > end)
404 return -1;
405
406 e820_add_region(start, size, type);
407
408 biosmap++;
409 nr_map--;
410 }
411 return 0;
412}
413
414
415
416
417
418
419
420
421
422
423static int __init append_e820_map(struct e820entry *biosmap, int nr_map)
424{
425
426 if (nr_map < 2)
427 return -1;
428
429 return __append_e820_map(biosmap, nr_map);
430}
431
432static u64 __init __e820_update_range(struct e820map *e820x, u64 start,
433 u64 size, unsigned old_type,
434 unsigned new_type)
435{
436 u64 end;
437 unsigned int i;
438 u64 real_updated_size = 0;
439
440 BUG_ON(old_type == new_type);
441
442 if (size > (ULLONG_MAX - start))
443 size = ULLONG_MAX - start;
444
445 end = start + size;
446 printk(KERN_DEBUG "e820 update range: %016Lx - %016Lx ",
447 (unsigned long long) start,
448 (unsigned long long) end);
449 e820_print_type(old_type);
450 printk(KERN_CONT " ==> ");
451 e820_print_type(new_type);
452 printk(KERN_CONT "\n");
453
454 for (i = 0; i < e820x->nr_map; i++) {
455 struct e820entry *ei = &e820x->map[i];
456 u64 final_start, final_end;
457 u64 ei_end;
458
459 if (ei->type != old_type)
460 continue;
461
462 ei_end = ei->addr + ei->size;
463
464 if (ei->addr >= start && ei_end <= end) {
465 ei->type = new_type;
466 real_updated_size += ei->size;
467 continue;
468 }
469
470
471 if (ei->addr < start && ei_end > end) {
472 __e820_add_region(e820x, start, size, new_type);
473 __e820_add_region(e820x, end, ei_end - end, ei->type);
474 ei->size = start - ei->addr;
475 real_updated_size += size;
476 continue;
477 }
478
479
480 final_start = max(start, ei->addr);
481 final_end = min(end, ei_end);
482 if (final_start >= final_end)
483 continue;
484
485 __e820_add_region(e820x, final_start, final_end - final_start,
486 new_type);
487
488 real_updated_size += final_end - final_start;
489
490
491
492
493
494 ei->size -= final_end - final_start;
495 if (ei->addr < final_start)
496 continue;
497 ei->addr = final_end;
498 }
499 return real_updated_size;
500}
501
502u64 __init e820_update_range(u64 start, u64 size, unsigned old_type,
503 unsigned new_type)
504{
505 return __e820_update_range(&e820, start, size, old_type, new_type);
506}
507
508static u64 __init e820_update_range_saved(u64 start, u64 size,
509 unsigned old_type, unsigned new_type)
510{
511 return __e820_update_range(&e820_saved, start, size, old_type,
512 new_type);
513}
514
515
516u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
517 int checktype)
518{
519 int i;
520 u64 real_removed_size = 0;
521
522 if (size > (ULLONG_MAX - start))
523 size = ULLONG_MAX - start;
524
525 for (i = 0; i < e820.nr_map; i++) {
526 struct e820entry *ei = &e820.map[i];
527 u64 final_start, final_end;
528
529 if (checktype && ei->type != old_type)
530 continue;
531
532 if (ei->addr >= start &&
533 (ei->addr + ei->size) <= (start + size)) {
534 real_removed_size += ei->size;
535 memset(ei, 0, sizeof(struct e820entry));
536 continue;
537 }
538
539 final_start = max(start, ei->addr);
540 final_end = min(start + size, ei->addr + ei->size);
541 if (final_start >= final_end)
542 continue;
543 real_removed_size += final_end - final_start;
544
545 ei->size -= final_end - final_start;
546 if (ei->addr < final_start)
547 continue;
548 ei->addr = final_end;
549 }
550 return real_removed_size;
551}
552
553void __init update_e820(void)
554{
555 u32 nr_map;
556
557 nr_map = e820.nr_map;
558 if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr_map))
559 return;
560 e820.nr_map = nr_map;
561 printk(KERN_INFO "modified physical RAM map:\n");
562 e820_print_map("modified");
563}
564static void __init update_e820_saved(void)
565{
566 u32 nr_map;
567
568 nr_map = e820_saved.nr_map;
569 if (sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map), &nr_map))
570 return;
571 e820_saved.nr_map = nr_map;
572}
573#define MAX_GAP_END 0x100000000ull
574
575
576
577__init int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
578 unsigned long start_addr, unsigned long long end_addr)
579{
580 unsigned long long last;
581 int i = e820.nr_map;
582 int found = 0;
583
584 last = (end_addr && end_addr < MAX_GAP_END) ? end_addr : MAX_GAP_END;
585
586 while (--i >= 0) {
587 unsigned long long start = e820.map[i].addr;
588 unsigned long long end = start + e820.map[i].size;
589
590 if (end < start_addr)
591 continue;
592
593
594
595
596
597 if (last > end) {
598 unsigned long gap = last - end;
599
600 if (gap >= *gapsize) {
601 *gapsize = gap;
602 *gapstart = end;
603 found = 1;
604 }
605 }
606 if (start < last)
607 last = start;
608 }
609 return found;
610}
611
612
613
614
615
616
617
618__init void e820_setup_gap(void)
619{
620 unsigned long gapstart, gapsize;
621 int found;
622
623 gapstart = 0x10000000;
624 gapsize = 0x400000;
625 found = e820_search_gap(&gapstart, &gapsize, 0, MAX_GAP_END);
626
627#ifdef CONFIG_X86_64
628 if (!found) {
629 gapstart = (max_pfn << PAGE_SHIFT) + 1024*1024;
630 printk(KERN_ERR
631 "PCI: Warning: Cannot find a gap in the 32bit address range\n"
632 "PCI: Unassigned devices with 32bit resource registers may break!\n");
633 }
634#endif
635
636
637
638
639 pci_mem_start = gapstart;
640
641 printk(KERN_INFO
642 "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
643 pci_mem_start, gapstart, gapsize);
644}
645
646
647
648
649
650
651
652void __init parse_e820_ext(struct setup_data *sdata, unsigned long pa_data)
653{
654 u32 map_len;
655 int entries;
656 struct e820entry *extmap;
657
658 entries = sdata->len / sizeof(struct e820entry);
659 map_len = sdata->len + sizeof(struct setup_data);
660 if (map_len > PAGE_SIZE)
661 sdata = early_ioremap(pa_data, map_len);
662 extmap = (struct e820entry *)(sdata->data);
663 __append_e820_map(extmap, entries);
664 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
665 if (map_len > PAGE_SIZE)
666 early_iounmap(sdata, map_len);
667 printk(KERN_INFO "extended physical RAM map:\n");
668 e820_print_map("extended");
669}
670
671#if defined(CONFIG_X86_64) || \
672 (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
673
674
675
676
677
678
679
680
681void __init e820_mark_nosave_regions(unsigned long limit_pfn)
682{
683 int i;
684 unsigned long pfn;
685
686 pfn = PFN_DOWN(e820.map[0].addr + e820.map[0].size);
687 for (i = 1; i < e820.nr_map; i++) {
688 struct e820entry *ei = &e820.map[i];
689
690 if (pfn < PFN_UP(ei->addr))
691 register_nosave_region(pfn, PFN_UP(ei->addr));
692
693 pfn = PFN_DOWN(ei->addr + ei->size);
694 if (ei->type != E820_RAM && ei->type != E820_RESERVED_KERN)
695 register_nosave_region(PFN_UP(ei->addr), pfn);
696
697 if (pfn >= limit_pfn)
698 break;
699 }
700}
701#endif
702
703#ifdef CONFIG_HIBERNATION
704
705
706
707
708static int __init e820_mark_nvs_memory(void)
709{
710 int i;
711
712 for (i = 0; i < e820.nr_map; i++) {
713 struct e820entry *ei = &e820.map[i];
714
715 if (ei->type == E820_NVS)
716 hibernate_nvs_register(ei->addr, ei->size);
717 }
718
719 return 0;
720}
721core_initcall(e820_mark_nvs_memory);
722#endif
723
724
725
726
727#define MAX_EARLY_RES 20
728
729struct early_res {
730 u64 start, end;
731 char name[16];
732 char overlap_ok;
733};
734static struct early_res early_res[MAX_EARLY_RES] __initdata = {
735 { 0, PAGE_SIZE, "BIOS data page" },
736 {}
737};
738
739static int __init find_overlapped_early(u64 start, u64 end)
740{
741 int i;
742 struct early_res *r;
743
744 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
745 r = &early_res[i];
746 if (end > r->start && start < r->end)
747 break;
748 }
749
750 return i;
751}
752
753
754
755
756
757
758static void __init drop_range(int i)
759{
760 int j;
761
762 for (j = i + 1; j < MAX_EARLY_RES && early_res[j].end; j++)
763 ;
764
765 memmove(&early_res[i], &early_res[i + 1],
766 (j - 1 - i) * sizeof(struct early_res));
767
768 early_res[j - 1].end = 0;
769}
770
771
772
773
774
775
776
777
778
779
780
781static void __init drop_overlaps_that_are_ok(u64 start, u64 end)
782{
783 int i;
784 struct early_res *r;
785 u64 lower_start, lower_end;
786 u64 upper_start, upper_end;
787 char name[16];
788
789 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
790 r = &early_res[i];
791
792
793 if (end <= r->start || start >= r->end)
794 continue;
795
796
797
798
799
800
801 if (!r->overlap_ok)
802 return;
803
804
805
806
807
808
809
810
811
812 strncpy(name, r->name, sizeof(name) - 1);
813
814 lower_start = lower_end = 0;
815 upper_start = upper_end = 0;
816 if (r->start < start) {
817 lower_start = r->start;
818 lower_end = start;
819 }
820 if (r->end > end) {
821 upper_start = end;
822 upper_end = r->end;
823 }
824
825
826 drop_range(i);
827
828 i--;
829
830
831 if (lower_end)
832 reserve_early_overlap_ok(lower_start, lower_end, name);
833 if (upper_end)
834 reserve_early_overlap_ok(upper_start, upper_end, name);
835 }
836}
837
838static void __init __reserve_early(u64 start, u64 end, char *name,
839 int overlap_ok)
840{
841 int i;
842 struct early_res *r;
843
844 i = find_overlapped_early(start, end);
845 if (i >= MAX_EARLY_RES)
846 panic("Too many early reservations");
847 r = &early_res[i];
848 if (r->end)
849 panic("Overlapping early reservations "
850 "%llx-%llx %s to %llx-%llx %s\n",
851 start, end - 1, name?name:"", r->start,
852 r->end - 1, r->name);
853 r->start = start;
854 r->end = end;
855 r->overlap_ok = overlap_ok;
856 if (name)
857 strncpy(r->name, name, sizeof(r->name) - 1);
858}
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880void __init reserve_early_overlap_ok(u64 start, u64 end, char *name)
881{
882 drop_overlaps_that_are_ok(start, end);
883 __reserve_early(start, end, name, 1);
884}
885
886
887
888
889
890
891
892
893
894void __init reserve_early(u64 start, u64 end, char *name)
895{
896 if (start >= end)
897 return;
898
899 drop_overlaps_that_are_ok(start, end);
900 __reserve_early(start, end, name, 0);
901}
902
903void __init free_early(u64 start, u64 end)
904{
905 struct early_res *r;
906 int i;
907
908 i = find_overlapped_early(start, end);
909 r = &early_res[i];
910 if (i >= MAX_EARLY_RES || r->end != end || r->start != start)
911 panic("free_early on not reserved area: %llx-%llx!",
912 start, end - 1);
913
914 drop_range(i);
915}
916
917void __init early_res_to_bootmem(u64 start, u64 end)
918{
919 int i, count;
920 u64 final_start, final_end;
921
922 count = 0;
923 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++)
924 count++;
925
926 printk(KERN_INFO "(%d early reservations) ==> bootmem [%010llx - %010llx]\n",
927 count, start, end);
928 for (i = 0; i < count; i++) {
929 struct early_res *r = &early_res[i];
930 printk(KERN_INFO " #%d [%010llx - %010llx] %16s", i,
931 r->start, r->end, r->name);
932 final_start = max(start, r->start);
933 final_end = min(end, r->end);
934 if (final_start >= final_end) {
935 printk(KERN_CONT "\n");
936 continue;
937 }
938 printk(KERN_CONT " ==> [%010llx - %010llx]\n",
939 final_start, final_end);
940 reserve_bootmem_generic(final_start, final_end - final_start,
941 BOOTMEM_DEFAULT);
942 }
943}
944
945
946static inline int __init bad_addr(u64 *addrp, u64 size, u64 align)
947{
948 int i;
949 u64 addr = *addrp;
950 int changed = 0;
951 struct early_res *r;
952again:
953 i = find_overlapped_early(addr, addr + size);
954 r = &early_res[i];
955 if (i < MAX_EARLY_RES && r->end) {
956 *addrp = addr = round_up(r->end, align);
957 changed = 1;
958 goto again;
959 }
960 return changed;
961}
962
963
964static inline int __init bad_addr_size(u64 *addrp, u64 *sizep, u64 align)
965{
966 int i;
967 u64 addr = *addrp, last;
968 u64 size = *sizep;
969 int changed = 0;
970again:
971 last = addr + size;
972 for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
973 struct early_res *r = &early_res[i];
974 if (last > r->start && addr < r->start) {
975 size = r->start - addr;
976 changed = 1;
977 goto again;
978 }
979 if (last > r->end && addr < r->end) {
980 addr = round_up(r->end, align);
981 size = last - addr;
982 changed = 1;
983 goto again;
984 }
985 if (last <= r->end && addr >= r->start) {
986 (*sizep)++;
987 return 0;
988 }
989 }
990 if (changed) {
991 *addrp = addr;
992 *sizep = size;
993 }
994 return changed;
995}
996
997
998
999
1000u64 __init find_e820_area(u64 start, u64 end, u64 size, u64 align)
1001{
1002 int i;
1003
1004 for (i = 0; i < e820.nr_map; i++) {
1005 struct e820entry *ei = &e820.map[i];
1006 u64 addr, last;
1007 u64 ei_last;
1008
1009 if (ei->type != E820_RAM)
1010 continue;
1011 addr = round_up(ei->addr, align);
1012 ei_last = ei->addr + ei->size;
1013 if (addr < start)
1014 addr = round_up(start, align);
1015 if (addr >= ei_last)
1016 continue;
1017 while (bad_addr(&addr, size, align) && addr+size <= ei_last)
1018 ;
1019 last = addr + size;
1020 if (last > ei_last)
1021 continue;
1022 if (last > end)
1023 continue;
1024 return addr;
1025 }
1026 return -1ULL;
1027}
1028
1029
1030
1031
1032u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align)
1033{
1034 int i;
1035
1036 for (i = 0; i < e820.nr_map; i++) {
1037 struct e820entry *ei = &e820.map[i];
1038 u64 addr, last;
1039 u64 ei_last;
1040
1041 if (ei->type != E820_RAM)
1042 continue;
1043 addr = round_up(ei->addr, align);
1044 ei_last = ei->addr + ei->size;
1045 if (addr < start)
1046 addr = round_up(start, align);
1047 if (addr >= ei_last)
1048 continue;
1049 *sizep = ei_last - addr;
1050 while (bad_addr_size(&addr, sizep, align) &&
1051 addr + *sizep <= ei_last)
1052 ;
1053 last = addr + *sizep;
1054 if (last > ei_last)
1055 continue;
1056 return addr;
1057 }
1058
1059 return -1ULL;
1060}
1061
1062
1063
1064
1065u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
1066{
1067 u64 size = 0;
1068 u64 addr;
1069 u64 start;
1070
1071 for (start = startt; ; start += size) {
1072 start = find_e820_area_size(start, &size, align);
1073 if (!(start + 1))
1074 return 0;
1075 if (size >= sizet)
1076 break;
1077 }
1078
1079#ifdef CONFIG_X86_32
1080 if (start >= MAXMEM)
1081 return 0;
1082 if (start + size > MAXMEM)
1083 size = MAXMEM - start;
1084#endif
1085
1086 addr = round_down(start + size - sizet, align);
1087 if (addr < start)
1088 return 0;
1089 e820_update_range(addr, sizet, E820_RAM, E820_RESERVED);
1090 e820_update_range_saved(addr, sizet, E820_RAM, E820_RESERVED);
1091 printk(KERN_INFO "update e820 for early_reserve_e820\n");
1092 update_e820();
1093 update_e820_saved();
1094
1095 return addr;
1096}
1097
1098#ifdef CONFIG_X86_32
1099# ifdef CONFIG_X86_PAE
1100# define MAX_ARCH_PFN (1ULL<<(36-PAGE_SHIFT))
1101# else
1102# define MAX_ARCH_PFN (1ULL<<(32-PAGE_SHIFT))
1103# endif
1104#else
1105# define MAX_ARCH_PFN MAXMEM>>PAGE_SHIFT
1106#endif
1107
1108
1109
1110
1111static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
1112{
1113 int i;
1114 unsigned long last_pfn = 0;
1115 unsigned long max_arch_pfn = MAX_ARCH_PFN;
1116
1117 for (i = 0; i < e820.nr_map; i++) {
1118 struct e820entry *ei = &e820.map[i];
1119 unsigned long start_pfn;
1120 unsigned long end_pfn;
1121
1122 if (ei->type != type)
1123 continue;
1124
1125 start_pfn = ei->addr >> PAGE_SHIFT;
1126 end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT;
1127
1128 if (start_pfn >= limit_pfn)
1129 continue;
1130 if (end_pfn > limit_pfn) {
1131 last_pfn = limit_pfn;
1132 break;
1133 }
1134 if (end_pfn > last_pfn)
1135 last_pfn = end_pfn;
1136 }
1137
1138 if (last_pfn > max_arch_pfn)
1139 last_pfn = max_arch_pfn;
1140
1141 printk(KERN_INFO "last_pfn = %#lx max_arch_pfn = %#lx\n",
1142 last_pfn, max_arch_pfn);
1143 return last_pfn;
1144}
1145unsigned long __init e820_end_of_ram_pfn(void)
1146{
1147 return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
1148}
1149
1150unsigned long __init e820_end_of_low_ram_pfn(void)
1151{
1152 return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
1153}
1154
1155
1156
1157
1158int __init e820_find_active_region(const struct e820entry *ei,
1159 unsigned long start_pfn,
1160 unsigned long last_pfn,
1161 unsigned long *ei_startpfn,
1162 unsigned long *ei_endpfn)
1163{
1164 u64 align = PAGE_SIZE;
1165
1166 *ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;
1167 *ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;
1168
1169
1170 if (*ei_startpfn >= *ei_endpfn)
1171 return 0;
1172
1173
1174 if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
1175 *ei_startpfn >= last_pfn)
1176 return 0;
1177
1178
1179 if (*ei_startpfn < start_pfn)
1180 *ei_startpfn = start_pfn;
1181 if (*ei_endpfn > last_pfn)
1182 *ei_endpfn = last_pfn;
1183
1184 return 1;
1185}
1186
1187
1188void __init e820_register_active_regions(int nid, unsigned long start_pfn,
1189 unsigned long last_pfn)
1190{
1191 unsigned long ei_startpfn;
1192 unsigned long ei_endpfn;
1193 int i;
1194
1195 for (i = 0; i < e820.nr_map; i++)
1196 if (e820_find_active_region(&e820.map[i],
1197 start_pfn, last_pfn,
1198 &ei_startpfn, &ei_endpfn))
1199 add_active_range(nid, ei_startpfn, ei_endpfn);
1200}
1201
1202
1203
1204
1205
1206
1207u64 __init e820_hole_size(u64 start, u64 end)
1208{
1209 unsigned long start_pfn = start >> PAGE_SHIFT;
1210 unsigned long last_pfn = end >> PAGE_SHIFT;
1211 unsigned long ei_startpfn, ei_endpfn, ram = 0;
1212 int i;
1213
1214 for (i = 0; i < e820.nr_map; i++) {
1215 if (e820_find_active_region(&e820.map[i],
1216 start_pfn, last_pfn,
1217 &ei_startpfn, &ei_endpfn))
1218 ram += ei_endpfn - ei_startpfn;
1219 }
1220 return end - start - ((u64)ram << PAGE_SHIFT);
1221}
1222
1223static void early_panic(char *msg)
1224{
1225 early_printk(msg);
1226 panic(msg);
1227}
1228
1229static int userdef __initdata;
1230
1231
1232static int __init parse_memopt(char *p)
1233{
1234 u64 mem_size;
1235
1236 if (!p)
1237 return -EINVAL;
1238
1239#ifdef CONFIG_X86_32
1240 if (!strcmp(p, "nopentium")) {
1241 setup_clear_cpu_cap(X86_FEATURE_PSE);
1242 return 0;
1243 }
1244#endif
1245
1246 userdef = 1;
1247 mem_size = memparse(p, &p);
1248 e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
1249
1250 return 0;
1251}
1252early_param("mem", parse_memopt);
1253
1254static int __init parse_memmap_opt(char *p)
1255{
1256 char *oldp;
1257 u64 start_at, mem_size;
1258
1259 if (!p)
1260 return -EINVAL;
1261
1262 if (!strncmp(p, "exactmap", 8)) {
1263#ifdef CONFIG_CRASH_DUMP
1264
1265
1266
1267
1268
1269 saved_max_pfn = e820_end_of_ram_pfn();
1270#endif
1271 e820.nr_map = 0;
1272 userdef = 1;
1273 return 0;
1274 }
1275
1276 oldp = p;
1277 mem_size = memparse(p, &p);
1278 if (p == oldp)
1279 return -EINVAL;
1280
1281 userdef = 1;
1282 if (*p == '@') {
1283 start_at = memparse(p+1, &p);
1284 e820_add_region(start_at, mem_size, E820_RAM);
1285 } else if (*p == '#') {
1286 start_at = memparse(p+1, &p);
1287 e820_add_region(start_at, mem_size, E820_ACPI);
1288 } else if (*p == '$') {
1289 start_at = memparse(p+1, &p);
1290 e820_add_region(start_at, mem_size, E820_RESERVED);
1291 } else
1292 e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1);
1293
1294 return *p == '\0' ? 0 : -EINVAL;
1295}
1296early_param("memmap", parse_memmap_opt);
1297
1298void __init finish_e820_parsing(void)
1299{
1300 if (userdef) {
1301 u32 nr = e820.nr_map;
1302
1303 if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0)
1304 early_panic("Invalid user supplied memory map");
1305 e820.nr_map = nr;
1306
1307 printk(KERN_INFO "user-defined physical RAM map:\n");
1308 e820_print_map("user");
1309 }
1310}
1311
1312static inline const char *e820_type_to_string(int e820_type)
1313{
1314 switch (e820_type) {
1315 case E820_RESERVED_KERN:
1316 case E820_RAM: return "System RAM";
1317 case E820_ACPI: return "ACPI Tables";
1318 case E820_NVS: return "ACPI Non-volatile Storage";
1319 case E820_UNUSABLE: return "Unusable memory";
1320 default: return "reserved";
1321 }
1322}
1323
1324
1325
1326
1327static struct resource __initdata *e820_res;
1328void __init e820_reserve_resources(void)
1329{
1330 int i;
1331 struct resource *res;
1332 u64 end;
1333
1334 res = alloc_bootmem(sizeof(struct resource) * e820.nr_map);
1335 e820_res = res;
1336 for (i = 0; i < e820.nr_map; i++) {
1337 end = e820.map[i].addr + e820.map[i].size - 1;
1338 if (end != (resource_size_t)end) {
1339 res++;
1340 continue;
1341 }
1342 res->name = e820_type_to_string(e820.map[i].type);
1343 res->start = e820.map[i].addr;
1344 res->end = end;
1345
1346 res->flags = IORESOURCE_MEM;
1347
1348
1349
1350
1351
1352
1353 if (e820.map[i].type != E820_RESERVED || res->start < (1ULL<<20)) {
1354 res->flags |= IORESOURCE_BUSY;
1355 insert_resource(&iomem_resource, res);
1356 }
1357 res++;
1358 }
1359
1360 for (i = 0; i < e820_saved.nr_map; i++) {
1361 struct e820entry *entry = &e820_saved.map[i];
1362 firmware_map_add_early(entry->addr,
1363 entry->addr + entry->size - 1,
1364 e820_type_to_string(entry->type));
1365 }
1366}
1367
1368
1369static unsigned long ram_alignment(resource_size_t pos)
1370{
1371 unsigned long mb = pos >> 20;
1372
1373
1374 if (!mb)
1375 return 64*1024;
1376
1377
1378 if (mb < 16)
1379 return 1024*1024;
1380
1381
1382 return 64*1024*1024;
1383}
1384
1385#define MAX_RESOURCE_SIZE ((resource_size_t)-1)
1386
1387void __init e820_reserve_resources_late(void)
1388{
1389 int i;
1390 struct resource *res;
1391
1392 res = e820_res;
1393 for (i = 0; i < e820.nr_map; i++) {
1394 if (!res->parent && res->end)
1395 insert_resource_expand_to_fit(&iomem_resource, res);
1396 res++;
1397 }
1398
1399
1400
1401
1402
1403 for (i = 0; i < e820.nr_map; i++) {
1404 struct e820entry *entry = &e820.map[i];
1405 u64 start, end;
1406
1407 if (entry->type != E820_RAM)
1408 continue;
1409 start = entry->addr + entry->size;
1410 end = round_up(start, ram_alignment(start)) - 1;
1411 if (end > MAX_RESOURCE_SIZE)
1412 end = MAX_RESOURCE_SIZE;
1413 if (start >= end)
1414 continue;
1415 reserve_region_with_split(&iomem_resource, start, end,
1416 "RAM buffer");
1417 }
1418}
1419
1420char *__init default_machine_specific_memory_setup(void)
1421{
1422 char *who = "BIOS-e820";
1423 u32 new_nr;
1424
1425
1426
1427
1428
1429
1430 new_nr = boot_params.e820_entries;
1431 sanitize_e820_map(boot_params.e820_map,
1432 ARRAY_SIZE(boot_params.e820_map),
1433 &new_nr);
1434 boot_params.e820_entries = new_nr;
1435 if (append_e820_map(boot_params.e820_map, boot_params.e820_entries)
1436 < 0) {
1437 u64 mem_size;
1438
1439
1440 if (boot_params.alt_mem_k
1441 < boot_params.screen_info.ext_mem_k) {
1442 mem_size = boot_params.screen_info.ext_mem_k;
1443 who = "BIOS-88";
1444 } else {
1445 mem_size = boot_params.alt_mem_k;
1446 who = "BIOS-e801";
1447 }
1448
1449 e820.nr_map = 0;
1450 e820_add_region(0, LOWMEMSIZE(), E820_RAM);
1451 e820_add_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
1452 }
1453
1454
1455 return who;
1456}
1457
1458void __init setup_memory_map(void)
1459{
1460 char *who;
1461
1462 who = x86_init.resources.memory_setup();
1463 memcpy(&e820_saved, &e820, sizeof(struct e820map));
1464 printk(KERN_INFO "BIOS-provided physical RAM map:\n");
1465 e820_print_map(who);
1466}
1467