1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/ioport.h>
3 #include <linux/printk.h>
4 #include <asm/e820/api.h>
5 #include <asm/pci_x86.h>
7 static void resource_clip(struct resource
*res
, resource_size_t start
,
10 resource_size_t low
= 0, high
= 0;
12 if (res
->end
< start
|| res
->start
> end
)
13 return; /* no conflict */
15 if (res
->start
< start
)
16 low
= start
- res
->start
;
19 high
= res
->end
- end
;
21 /* Keep the area above or below the conflict, whichever is larger */
28 static void remove_e820_regions(struct resource
*avail
)
31 struct e820_entry
*entry
;
32 u64 e820_start
, e820_end
;
33 struct resource orig
= *avail
;
38 for (i
= 0; i
< e820_table
->nr_entries
; i
++) {
39 entry
= &e820_table
->entries
[i
];
40 e820_start
= entry
->addr
;
41 e820_end
= entry
->addr
+ entry
->size
- 1;
43 resource_clip(avail
, e820_start
, e820_end
);
44 if (orig
.start
!= avail
->start
|| orig
.end
!= avail
->end
) {
45 pr_info("resource: avoiding allocation from e820 entry [mem %#010Lx-%#010Lx]\n",
46 e820_start
, e820_end
);
47 if (avail
->end
> avail
->start
)
49 * Use %pa instead of %pR because "avail"
50 * is typically IORESOURCE_UNSET, so %pR
51 * shows the size instead of addresses.
53 pr_info("resource: remaining [mem %pa-%pa] available\n",
54 &avail
->start
, &avail
->end
);
60 void arch_remove_reservations(struct resource
*avail
)
63 * Trim out BIOS area (high 2MB) and E820 regions. We do not remove
64 * the low 1MB unconditionally, as this area is needed for some ISA
65 * cards requiring a memory range, e.g. the i82365 PCMCIA controller.
67 if (avail
->flags
& IORESOURCE_MEM
) {
68 resource_clip(avail
, BIOS_ROM_BASE
, BIOS_ROM_END
);
70 remove_e820_regions(avail
);