1#include <linux/kernel.h>
2#include <linux/types.h>
3#include <linux/init.h>
4#include <linux/bootmem.h>
5#include <linux/ioport.h>
6#include <linux/string.h>
7#include <linux/kexec.h>
8#include <linux/module.h>
9#include <linux/mm.h>
10#include <linux/efi.h>
11#include <linux/pfn.h>
12#include <linux/uaccess.h>
13
14#include <asm/pgtable.h>
15#include <asm/page.h>
16#include <asm/e820.h>
17#include <asm/setup.h>
18
19#ifdef CONFIG_EFI
20int efi_enabled = 0;
21EXPORT_SYMBOL(efi_enabled);
22#endif
23
24struct e820map e820;
25struct change_member {
26 struct e820entry *pbios;
27 unsigned long long addr;
28};
29static struct change_member change_point_list[2*E820MAX] __initdata;
30static struct change_member *change_point[2*E820MAX] __initdata;
31static struct e820entry *overlap_list[E820MAX] __initdata;
32static struct e820entry new_bios[E820MAX] __initdata;
33
34unsigned long pci_mem_start = 0x10000000;
35#ifdef CONFIG_PCI
36EXPORT_SYMBOL(pci_mem_start);
37#endif
38extern int user_defined_memmap;
39struct resource data_resource = {
40 .name = "Kernel data",
41 .start = 0,
42 .end = 0,
43 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
44};
45
46struct resource code_resource = {
47 .name = "Kernel code",
48 .start = 0,
49 .end = 0,
50 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
51};
52
53static struct resource system_rom_resource = {
54 .name = "System ROM",
55 .start = 0xf0000,
56 .end = 0xfffff,
57 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
58};
59
60static struct resource extension_rom_resource = {
61 .name = "Extension ROM",
62 .start = 0xe0000,
63 .end = 0xeffff,
64 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
65};
66
67static struct resource adapter_rom_resources[] = { {
68 .name = "Adapter ROM",
69 .start = 0xc8000,
70 .end = 0,
71 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
72}, {
73 .name = "Adapter ROM",
74 .start = 0,
75 .end = 0,
76 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
77}, {
78 .name = "Adapter ROM",
79 .start = 0,
80 .end = 0,
81 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
82}, {
83 .name = "Adapter ROM",
84 .start = 0,
85 .end = 0,
86 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
87}, {
88 .name = "Adapter ROM",
89 .start = 0,
90 .end = 0,
91 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
92}, {
93 .name = "Adapter ROM",
94 .start = 0,
95 .end = 0,
96 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
97} };
98
99static struct resource video_rom_resource = {
100 .name = "Video ROM",
101 .start = 0xc0000,
102 .end = 0xc7fff,
103 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
104};
105
106static struct resource video_ram_resource = {
107 .name = "Video RAM area",
108 .start = 0xa0000,
109 .end = 0xbffff,
110 .flags = IORESOURCE_BUSY | IORESOURCE_MEM
111};
112
113static struct resource standard_io_resources[] = { {
114 .name = "dma1",
115 .start = 0x0000,
116 .end = 0x001f,
117 .flags = IORESOURCE_BUSY | IORESOURCE_IO
118}, {
119 .name = "pic1",
120 .start = 0x0020,
121 .end = 0x0021,
122 .flags = IORESOURCE_BUSY | IORESOURCE_IO
123}, {
124 .name = "timer0",
125 .start = 0x0040,
126 .end = 0x0043,
127 .flags = IORESOURCE_BUSY | IORESOURCE_IO
128}, {
129 .name = "timer1",
130 .start = 0x0050,
131 .end = 0x0053,
132 .flags = IORESOURCE_BUSY | IORESOURCE_IO
133}, {
134 .name = "keyboard",
135 .start = 0x0060,
136 .end = 0x006f,
137 .flags = IORESOURCE_BUSY | IORESOURCE_IO
138}, {
139 .name = "dma page reg",
140 .start = 0x0080,
141 .end = 0x008f,
142 .flags = IORESOURCE_BUSY | IORESOURCE_IO
143}, {
144 .name = "pic2",
145 .start = 0x00a0,
146 .end = 0x00a1,
147 .flags = IORESOURCE_BUSY | IORESOURCE_IO
148}, {
149 .name = "dma2",
150 .start = 0x00c0,
151 .end = 0x00df,
152 .flags = IORESOURCE_BUSY | IORESOURCE_IO
153}, {
154 .name = "fpu",
155 .start = 0x00f0,
156 .end = 0x00ff,
157 .flags = IORESOURCE_BUSY | IORESOURCE_IO
158} };
159
160#define ROMSIGNATURE 0xaa55
161
162static int __init romsignature(const unsigned char *rom)
163{
164 const unsigned short * const ptr = (const unsigned short *)rom;
165 unsigned short sig;
166
167 return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE;
168}
169
170static int __init romchecksum(const unsigned char *rom, unsigned long length)
171{
172 unsigned char sum, c;
173
174 for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--)
175 sum += c;
176 return !length && !sum;
177}
178
179static void __init probe_roms(void)
180{
181 const unsigned char *rom;
182 unsigned long start, length, upper;
183 unsigned char c;
184 int i;
185
186
187 upper = adapter_rom_resources[0].start;
188 for (start = video_rom_resource.start; start < upper; start += 2048) {
189 rom = isa_bus_to_virt(start);
190 if (!romsignature(rom))
191 continue;
192
193 video_rom_resource.start = start;
194
195 if (probe_kernel_address(rom + 2, c) != 0)
196 continue;
197
198
199 length = c * 512;
200
201
202 if (length && romchecksum(rom, length))
203 video_rom_resource.end = start + length - 1;
204
205 request_resource(&iomem_resource, &video_rom_resource);
206 break;
207 }
208
209 start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
210 if (start < upper)
211 start = upper;
212
213
214 request_resource(&iomem_resource, &system_rom_resource);
215 upper = system_rom_resource.start;
216
217
218 rom = isa_bus_to_virt(extension_rom_resource.start);
219 if (romsignature(rom)) {
220 length = extension_rom_resource.end - extension_rom_resource.start + 1;
221 if (romchecksum(rom, length)) {
222 request_resource(&iomem_resource, &extension_rom_resource);
223 upper = extension_rom_resource.start;
224 }
225 }
226
227
228 for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
229 rom = isa_bus_to_virt(start);
230 if (!romsignature(rom))
231 continue;
232
233 if (probe_kernel_address(rom + 2, c) != 0)
234 continue;
235
236
237 length = c * 512;
238
239
240 if (!length || start + length > upper || !romchecksum(rom, length))
241 continue;
242
243 adapter_rom_resources[i].start = start;
244 adapter_rom_resources[i].end = start + length - 1;
245 request_resource(&iomem_resource, &adapter_rom_resources[i]);
246
247 start = adapter_rom_resources[i++].end & ~2047UL;
248 }
249}
250
251
252
253
254
255static void __init
256legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
257{
258 int i;
259
260 probe_roms();
261 for (i = 0; i < e820.nr_map; i++) {
262 struct resource *res;
263#ifndef CONFIG_RESOURCES_64BIT
264 if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
265 continue;
266#endif
267 res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
268 switch (e820.map[i].type) {
269 case E820_RAM: res->name = "System RAM"; break;
270 case E820_ACPI: res->name = "ACPI Tables"; break;
271 case E820_NVS: res->name = "ACPI Non-volatile Storage"; break;
272 default: res->name = "reserved";
273 }
274 res->start = e820.map[i].addr;
275 res->end = res->start + e820.map[i].size - 1;
276 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
277 if (request_resource(&iomem_resource, res)) {
278 kfree(res);
279 continue;
280 }
281 if (e820.map[i].type == E820_RAM) {
282
283
284
285
286
287 request_resource(res, code_resource);
288 request_resource(res, data_resource);
289#ifdef CONFIG_KEXEC
290 request_resource(res, &crashk_res);
291#endif
292 }
293 }
294}
295
296
297
298
299
300
301
302static int __init request_standard_resources(void)
303{
304 int i;
305
306 printk("Setting up standard PCI resources\n");
307 if (efi_enabled)
308 efi_initialize_iomem_resources(&code_resource, &data_resource);
309 else
310 legacy_init_iomem_resources(&code_resource, &data_resource);
311
312
313 request_resource(&iomem_resource, &video_ram_resource);
314
315
316 for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
317 request_resource(&ioport_resource, &standard_io_resources[i]);
318 return 0;
319}
320
321subsys_initcall(request_standard_resources);
322
323void __init add_memory_region(unsigned long long start,
324 unsigned long long size, int type)
325{
326 int x;
327
328 if (!efi_enabled) {
329 x = e820.nr_map;
330
331 if (x == E820MAX) {
332 printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
333 return;
334 }
335
336 e820.map[x].addr = start;
337 e820.map[x].size = size;
338 e820.map[x].type = type;
339 e820.nr_map++;
340 }
341}
342
343
344
345
346
347
348
349
350int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
351{
352 struct change_member *change_tmp;
353 unsigned long current_type, last_type;
354 unsigned long long last_addr;
355 int chgidx, still_changing;
356 int overlap_entries;
357 int new_bios_entry;
358 int old_nr, new_nr, chg_nr;
359 int i;
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397 if (*pnr_map < 2) {
398 return -1;
399 }
400
401 old_nr = *pnr_map;
402
403
404 for (i=0; i<old_nr; i++)
405 if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr) {
406 return -1;
407 }
408
409
410 for (i=0; i < 2*old_nr; i++)
411 change_point[i] = &change_point_list[i];
412
413
414
415 chgidx = 0;
416 for (i=0; i < old_nr; i++) {
417 if (biosmap[i].size != 0) {
418 change_point[chgidx]->addr = biosmap[i].addr;
419 change_point[chgidx++]->pbios = &biosmap[i];
420 change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
421 change_point[chgidx++]->pbios = &biosmap[i];
422 }
423 }
424 chg_nr = chgidx;
425
426
427 still_changing = 1;
428 while (still_changing) {
429 still_changing = 0;
430 for (i=1; i < chg_nr; i++) {
431
432
433 if ((change_point[i]->addr < change_point[i-1]->addr) ||
434 ((change_point[i]->addr == change_point[i-1]->addr) &&
435 (change_point[i]->addr == change_point[i]->pbios->addr) &&
436 (change_point[i-1]->addr != change_point[i-1]->pbios->addr))
437 )
438 {
439 change_tmp = change_point[i];
440 change_point[i] = change_point[i-1];
441 change_point[i-1] = change_tmp;
442 still_changing=1;
443 }
444 }
445 }
446
447
448 overlap_entries=0;
449 new_bios_entry=0;
450 last_type = 0;
451 last_addr = 0;
452
453 for (chgidx=0; chgidx < chg_nr; chgidx++)
454 {
455
456 if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)
457 {
458
459 overlap_list[overlap_entries++]=change_point[chgidx]->pbios;
460 }
461 else
462 {
463
464 for (i=0; i<overlap_entries; i++)
465 {
466 if (overlap_list[i] == change_point[chgidx]->pbios)
467 overlap_list[i] = overlap_list[overlap_entries-1];
468 }
469 overlap_entries--;
470 }
471
472
473 current_type = 0;
474 for (i=0; i<overlap_entries; i++)
475 if (overlap_list[i]->type > current_type)
476 current_type = overlap_list[i]->type;
477
478 if (current_type != last_type) {
479 if (last_type != 0) {
480 new_bios[new_bios_entry].size =
481 change_point[chgidx]->addr - last_addr;
482
483 if (new_bios[new_bios_entry].size != 0)
484 if (++new_bios_entry >= E820MAX)
485 break;
486 }
487 if (current_type != 0) {
488 new_bios[new_bios_entry].addr = change_point[chgidx]->addr;
489 new_bios[new_bios_entry].type = current_type;
490 last_addr=change_point[chgidx]->addr;
491 }
492 last_type = current_type;
493 }
494 }
495 new_nr = new_bios_entry;
496
497
498 memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry));
499 *pnr_map = new_nr;
500
501 return 0;
502}
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
521{
522
523 if (nr_map < 2)
524 return -1;
525
526 do {
527 unsigned long long start = biosmap->addr;
528 unsigned long long size = biosmap->size;
529 unsigned long long end = start + size;
530 unsigned long type = biosmap->type;
531
532
533 if (start > end)
534 return -1;
535
536
537
538
539
540 if (type == E820_RAM) {
541 if (start < 0x100000ULL && end > 0xA0000ULL) {
542 if (start < 0xA0000ULL)
543 add_memory_region(start, 0xA0000ULL-start, type);
544 if (end <= 0x100000ULL)
545 continue;
546 start = 0x100000ULL;
547 size = end - start;
548 }
549 }
550 add_memory_region(start, size, type);
551 } while (biosmap++,--nr_map);
552 return 0;
553}
554
555
556
557
558static int __init
559efi_find_max_pfn(unsigned long start, unsigned long end, void *arg)
560{
561 unsigned long *max_pfn = arg, pfn;
562
563 if (start < end) {
564 pfn = PFN_UP(end -1);
565 if (pfn > *max_pfn)
566 *max_pfn = pfn;
567 }
568 return 0;
569}
570
571static int __init
572efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
573{
574 memory_present(0, PFN_UP(start), PFN_DOWN(end));
575 return 0;
576}
577
578
579
580
581void __init find_max_pfn(void)
582{
583 int i;
584
585 max_pfn = 0;
586 if (efi_enabled) {
587 efi_memmap_walk(efi_find_max_pfn, &max_pfn);
588 efi_memmap_walk(efi_memory_present_wrapper, NULL);
589 return;
590 }
591
592 for (i = 0; i < e820.nr_map; i++) {
593 unsigned long start, end;
594
595 if (e820.map[i].type != E820_RAM)
596 continue;
597 start = PFN_UP(e820.map[i].addr);
598 end = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
599 if (start >= end)
600 continue;
601 if (end > max_pfn)
602 max_pfn = end;
603 memory_present(0, start, end);
604 }
605}
606
607
608
609
610
611
612static int __init
613free_available_memory(unsigned long start, unsigned long end, void *arg)
614{
615
616 if (start >= (max_low_pfn << PAGE_SHIFT))
617 return 0;
618 if (end >= (max_low_pfn << PAGE_SHIFT))
619 end = max_low_pfn << PAGE_SHIFT;
620 if (start < end)
621 free_bootmem(start, end - start);
622
623 return 0;
624}
625
626
627
628void __init register_bootmem_low_pages(unsigned long max_low_pfn)
629{
630 int i;
631
632 if (efi_enabled) {
633 efi_memmap_walk(free_available_memory, NULL);
634 return;
635 }
636 for (i = 0; i < e820.nr_map; i++) {
637 unsigned long curr_pfn, last_pfn, size;
638
639
640
641 if (e820.map[i].type != E820_RAM)
642 continue;
643
644
645
646 curr_pfn = PFN_UP(e820.map[i].addr);
647 if (curr_pfn >= max_low_pfn)
648 continue;
649
650
651
652 last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
653
654 if (last_pfn > max_low_pfn)
655 last_pfn = max_low_pfn;
656
657
658
659
660
661 if (last_pfn <= curr_pfn)
662 continue;
663
664 size = last_pfn - curr_pfn;
665 free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
666 }
667}
668
669void __init e820_register_memory(void)
670{
671 unsigned long gapstart, gapsize, round;
672 unsigned long long last;
673 int i;
674
675
676
677
678
679 last = 0x100000000ull;
680 gapstart = 0x10000000;
681 gapsize = 0x400000;
682 i = e820.nr_map;
683 while (--i >= 0) {
684 unsigned long long start = e820.map[i].addr;
685 unsigned long long end = start + e820.map[i].size;
686
687
688
689
690
691 if (last > end) {
692 unsigned long gap = last - end;
693
694 if (gap > gapsize) {
695 gapsize = gap;
696 gapstart = end;
697 }
698 }
699 if (start < last)
700 last = start;
701 }
702
703
704
705
706
707 round = 0x100000;
708 while ((gapsize >> 4) > round)
709 round += round;
710
711 pci_mem_start = (gapstart + round) & -round;
712
713 printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
714 pci_mem_start, gapstart, gapsize);
715}
716
717void __init print_memory_map(char *who)
718{
719 int i;
720
721 for (i = 0; i < e820.nr_map; i++) {
722 printk(" %s: %016Lx - %016Lx ", who,
723 e820.map[i].addr,
724 e820.map[i].addr + e820.map[i].size);
725 switch (e820.map[i].type) {
726 case E820_RAM: printk("(usable)\n");
727 break;
728 case E820_RESERVED:
729 printk("(reserved)\n");
730 break;
731 case E820_ACPI:
732 printk("(ACPI data)\n");
733 break;
734 case E820_NVS:
735 printk("(ACPI NVS)\n");
736 break;
737 default: printk("type %lu\n", e820.map[i].type);
738 break;
739 }
740 }
741}
742
743static __init __always_inline void efi_limit_regions(unsigned long long size)
744{
745 unsigned long long current_addr = 0;
746 efi_memory_desc_t *md, *next_md;
747 void *p, *p1;
748 int i, j;
749
750 j = 0;
751 p1 = memmap.map;
752 for (p = p1, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) {
753 md = p;
754 next_md = p1;
755 current_addr = md->phys_addr +
756 PFN_PHYS(md->num_pages);
757 if (is_available_memory(md)) {
758 if (md->phys_addr >= size) continue;
759 memcpy(next_md, md, memmap.desc_size);
760 if (current_addr >= size) {
761 next_md->num_pages -=
762 PFN_UP(current_addr-size);
763 }
764 p1 += memmap.desc_size;
765 next_md = p1;
766 j++;
767 } else if ((md->attribute & EFI_MEMORY_RUNTIME) ==
768 EFI_MEMORY_RUNTIME) {
769
770
771
772 memcpy(next_md, md, memmap.desc_size);
773 p1 += memmap.desc_size;
774 next_md = p1;
775 j++;
776 }
777 }
778 memmap.nr_map = j;
779 memmap.map_end = memmap.map +
780 (memmap.nr_map * memmap.desc_size);
781}
782
783void __init limit_regions(unsigned long long size)
784{
785 unsigned long long current_addr;
786 int i;
787
788 print_memory_map("limit_regions start");
789 if (efi_enabled) {
790 efi_limit_regions(size);
791 return;
792 }
793 for (i = 0; i < e820.nr_map; i++) {
794 current_addr = e820.map[i].addr + e820.map[i].size;
795 if (current_addr < size)
796 continue;
797
798 if (e820.map[i].type != E820_RAM)
799 continue;
800
801 if (e820.map[i].addr >= size) {
802
803
804
805
806 e820.nr_map = i;
807 } else {
808 e820.nr_map = i + 1;
809 e820.map[i].size -= current_addr - size;
810 }
811 print_memory_map("limit_regions endfor");
812 return;
813 }
814 print_memory_map("limit_regions endfunc");
815}
816
817
818
819
820
821int
822e820_any_mapped(u64 start, u64 end, unsigned type)
823{
824 int i;
825 for (i = 0; i < e820.nr_map; i++) {
826 const struct e820entry *ei = &e820.map[i];
827 if (type && ei->type != type)
828 continue;
829 if (ei->addr >= end || ei->addr + ei->size <= start)
830 continue;
831 return 1;
832 }
833 return 0;
834}
835EXPORT_SYMBOL_GPL(e820_any_mapped);
836
837
838
839
840
841
842
843int __init
844e820_all_mapped(unsigned long s, unsigned long e, unsigned type)
845{
846 u64 start = s;
847 u64 end = e;
848 int i;
849 for (i = 0; i < e820.nr_map; i++) {
850 struct e820entry *ei = &e820.map[i];
851 if (type && ei->type != type)
852 continue;
853
854 if (ei->addr >= end || ei->addr + ei->size <= start)
855 continue;
856
857
858
859 if (ei->addr <= start)
860 start = ei->addr + ei->size;
861
862
863 if (start >= end)
864 return 1;
865 }
866 return 0;
867}
868
869static int __init parse_memmap(char *arg)
870{
871 if (!arg)
872 return -EINVAL;
873
874 if (strcmp(arg, "exactmap") == 0) {
875#ifdef CONFIG_CRASH_DUMP
876
877
878
879
880
881 find_max_pfn();
882 saved_max_pfn = max_pfn;
883#endif
884 e820.nr_map = 0;
885 user_defined_memmap = 1;
886 } else {
887
888
889
890
891
892
893 unsigned long long start_at, mem_size;
894
895 mem_size = memparse(arg, &arg);
896 if (*arg == '@') {
897 start_at = memparse(arg+1, &arg);
898 add_memory_region(start_at, mem_size, E820_RAM);
899 } else if (*arg == '#') {
900 start_at = memparse(arg+1, &arg);
901 add_memory_region(start_at, mem_size, E820_ACPI);
902 } else if (*arg == '$') {
903 start_at = memparse(arg+1, &arg);
904 add_memory_region(start_at, mem_size, E820_RESERVED);
905 } else {
906 limit_regions(mem_size);
907 user_defined_memmap = 1;
908 }
909 }
910 return 0;
911}
912early_param("memmap", parse_memmap);
913