// SPDX-License-Identifier: GPL-2.0 #include <linux/kernel.h> #include <linux/init.h> #include <linux/memblock.h> #include <asm/setup.h> #include <asm/bios_ebda.h> /* * This function reserves all conventional PC system BIOS related * firmware memory areas (some of which are data, some of which * are code), that must not be used by the kernel as available * RAM. * * The BIOS places the EBDA/XBDA at the top of conventional * memory, and usually decreases the reported amount of * conventional memory (int 0x12) too. * * This means that as a first approximation on most systems we can * guess the reserved BIOS area by looking at the low BIOS RAM size * value and assume that everything above that value (up to 1MB) is * reserved. * * But life in firmware country is not that simple: * * - This code also contains a quirk for Dell systems that neglect * to reserve the EBDA area in the 'RAM size' value ... * * - The same quirk also avoids a problem with the AMD768MPX * chipset: reserve a page before VGA to prevent PCI prefetch * into it (errata #56). (Usually the page is reserved anyways, * unless you have no PS/2 mouse plugged in.) * * - Plus paravirt systems don't have a reliable value in the * 'BIOS RAM size' pointer we can rely on, so we must quirk * them too. * * Due to those various problems this function is deliberately * very conservative and tries to err on the side of reserving * too much, to not risk reserving too little. * * Losing a small amount of memory in the bottom megabyte is * rarely a problem, as long as we have enough memory to install * the SMP bootup trampoline which *must* be in this area. * * Using memory that is in use by the BIOS or by some DMA device * the BIOS didn't shut down *is* a big problem to the kernel, * obviously. */ #define BIOS_RAM_SIZE_KB_PTR … #define BIOS_START_MIN … #define BIOS_START_MAX … void __init reserve_bios_regions(void) { … }