0001
0002 #include <linux/ioport.h>
0003 #include <linux/printk.h>
0004 #include <asm/e820/api.h>
0005 #include <asm/pci_x86.h>
0006
0007 static void resource_clip(struct resource *res, resource_size_t start,
0008 resource_size_t end)
0009 {
0010 resource_size_t low = 0, high = 0;
0011
0012 if (res->end < start || res->start > end)
0013 return;
0014
0015 if (res->start < start)
0016 low = start - res->start;
0017
0018 if (res->end > end)
0019 high = res->end - end;
0020
0021
0022 if (low > high)
0023 res->end = start - 1;
0024 else
0025 res->start = end + 1;
0026 }
0027
0028 static void remove_e820_regions(struct resource *avail)
0029 {
0030 int i;
0031 struct e820_entry *entry;
0032 u64 e820_start, e820_end;
0033 struct resource orig = *avail;
0034
0035 if (!pci_use_e820)
0036 return;
0037
0038 for (i = 0; i < e820_table->nr_entries; i++) {
0039 entry = &e820_table->entries[i];
0040 e820_start = entry->addr;
0041 e820_end = entry->addr + entry->size - 1;
0042
0043 resource_clip(avail, e820_start, e820_end);
0044 if (orig.start != avail->start || orig.end != avail->end) {
0045 pr_info("clipped %pR to %pR for e820 entry [mem %#010Lx-%#010Lx]\n",
0046 &orig, avail, e820_start, e820_end);
0047 orig = *avail;
0048 }
0049 }
0050 }
0051
0052 void arch_remove_reservations(struct resource *avail)
0053 {
0054
0055
0056
0057
0058
0059 if (avail->flags & IORESOURCE_MEM) {
0060 resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END);
0061
0062 remove_e820_regions(avail);
0063 }
0064 }