diff options
Diffstat (limited to 'arch/x86_64/kernel/e820.c')
-rw-r--r-- | arch/x86_64/kernel/e820.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 657003e461e6..56516ac92e5d 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c | |||
@@ -511,3 +511,62 @@ void __init parse_memopt(char *p, char **from) | |||
511 | end_user_pfn >>= PAGE_SHIFT; | 511 | end_user_pfn >>= PAGE_SHIFT; |
512 | } | 512 | } |
513 | 513 | ||
514 | unsigned long pci_mem_start = 0xaeedbabe; | ||
515 | |||
516 | /* | ||
517 | * Search for the biggest gap in the low 32 bits of the e820 | ||
518 | * memory space. We pass this space to PCI to assign MMIO resources | ||
519 | * for hotplug or unconfigured devices in. | ||
520 | * Hopefully the BIOS let enough space left. | ||
521 | */ | ||
522 | __init void e820_setup_gap(void) | ||
523 | { | ||
524 | unsigned long gapstart, gapsize; | ||
525 | unsigned long last; | ||
526 | int i; | ||
527 | int found = 0; | ||
528 | |||
529 | last = 0x100000000ull; | ||
530 | gapstart = 0x10000000; | ||
531 | gapsize = 0x400000; | ||
532 | i = e820.nr_map; | ||
533 | while (--i >= 0) { | ||
534 | unsigned long long start = e820.map[i].addr; | ||
535 | unsigned long long end = start + e820.map[i].size; | ||
536 | |||
537 | /* | ||
538 | * Since "last" is at most 4GB, we know we'll | ||
539 | * fit in 32 bits if this condition is true | ||
540 | */ | ||
541 | if (last > end) { | ||
542 | unsigned long gap = last - end; | ||
543 | |||
544 | if (gap > gapsize) { | ||
545 | gapsize = gap; | ||
546 | gapstart = end; | ||
547 | found = 1; | ||
548 | } | ||
549 | } | ||
550 | if (start < last) | ||
551 | last = start; | ||
552 | } | ||
553 | |||
554 | if (!found) { | ||
555 | gapstart = (end_pfn << PAGE_SHIFT) + 1024*1024; | ||
556 | printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit address range\n" | ||
557 | KERN_ERR "PCI: Unassigned devices with 32bit resource registers may break!\n"); | ||
558 | } | ||
559 | |||
560 | /* | ||
561 | * Start allocating dynamic PCI memory a bit into the gap, | ||
562 | * aligned up to the nearest megabyte. | ||
563 | * | ||
564 | * Question: should we try to pad it up a bit (do something | ||
565 | * like " + (gapsize >> 3)" in there too?). We now have the | ||
566 | * technology. | ||
567 | */ | ||
568 | pci_mem_start = (gapstart + 0xfffff) & ~0xfffff; | ||
569 | |||
570 | printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n", | ||
571 | pci_mem_start, gapstart, gapsize); | ||
572 | } | ||