1 #include <linux/ioport.h> 2 #include <asm/e820.h> 3 4 static void resource_clip(struct resource *res, resource_size_t start, 5 resource_size_t end) 6 { 7 resource_size_t low = 0, high = 0; 8 9 if (res->end < start || res->start > end) 10 return; /* no conflict */ 11 12 if (res->start < start) 13 low = start - res->start; 14 15 if (res->end > end) 16 high = res->end - end; 17 18 /* Keep the area above or below the conflict, whichever is larger */ 19 if (low > high) 20 res->end = start - 1; 21 else 22 res->start = end + 1; 23 } 24 25 static void remove_e820_regions(struct resource *avail) 26 { 27 int i; 28 struct e820entry *entry; 29 30 for (i = 0; i < e820.nr_map; i++) { 31 entry = &e820.map[i]; 32 33 resource_clip(avail, entry->addr, 34 entry->addr + entry->size - 1); 35 } 36 } 37 38 void arch_remove_reservations(struct resource *avail) 39 { 40 /* 41 * Trim out BIOS area (high 2MB) and E820 regions. We do not remove 42 * the low 1MB unconditionally, as this area is needed for some ISA 43 * cards requiring a memory range, e.g. the i82365 PCMCIA controller. 44 */ 45 if (avail->flags & IORESOURCE_MEM) { 46 resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END); 47 48 remove_e820_regions(avail); 49 } 50 } 51