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 /* Trim out BIOS areas (low 1MB and high 2MB) and E820 regions */ 41 if (avail->flags & IORESOURCE_MEM) { 42 if (avail->start < BIOS_END) 43 avail->start = BIOS_END; 44 resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END); 45 46 remove_e820_regions(avail); 47 } 48 } 49