Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/kernel.h>
0003 #include <linux/init.h>
0004 #include <linux/memblock.h>
0005 
0006 #include <asm/setup.h>
0007 #include <asm/bios_ebda.h>
0008 
0009 /*
0010  * This function reserves all conventional PC system BIOS related
0011  * firmware memory areas (some of which are data, some of which
0012  * are code), that must not be used by the kernel as available
0013  * RAM.
0014  *
0015  * The BIOS places the EBDA/XBDA at the top of conventional
0016  * memory, and usually decreases the reported amount of
0017  * conventional memory (int 0x12) too.
0018  *
0019  * This means that as a first approximation on most systems we can
0020  * guess the reserved BIOS area by looking at the low BIOS RAM size
0021  * value and assume that everything above that value (up to 1MB) is
0022  * reserved.
0023  *
0024  * But life in firmware country is not that simple:
0025  *
0026  * - This code also contains a quirk for Dell systems that neglect
0027  *   to reserve the EBDA area in the 'RAM size' value ...
0028  *
0029  * - The same quirk also avoids a problem with the AMD768MPX
0030  *   chipset: reserve a page before VGA to prevent PCI prefetch
0031  *   into it (errata #56). (Usually the page is reserved anyways,
0032  *   unless you have no PS/2 mouse plugged in.)
0033  *
0034  * - Plus paravirt systems don't have a reliable value in the
0035  *   'BIOS RAM size' pointer we can rely on, so we must quirk
0036  *   them too.
0037  *
0038  * Due to those various problems this function is deliberately
0039  * very conservative and tries to err on the side of reserving
0040  * too much, to not risk reserving too little.
0041  *
0042  * Losing a small amount of memory in the bottom megabyte is
0043  * rarely a problem, as long as we have enough memory to install
0044  * the SMP bootup trampoline which *must* be in this area.
0045  *
0046  * Using memory that is in use by the BIOS or by some DMA device
0047  * the BIOS didn't shut down *is* a big problem to the kernel,
0048  * obviously.
0049  */
0050 
0051 #define BIOS_RAM_SIZE_KB_PTR    0x413
0052 
0053 #define BIOS_START_MIN      0x20000U    /* 128K, less than this is insane */
0054 #define BIOS_START_MAX      0x9f000U    /* 640K, absolute maximum */
0055 
0056 void __init reserve_bios_regions(void)
0057 {
0058     unsigned int bios_start, ebda_start;
0059 
0060     /*
0061      * NOTE: In a paravirtual environment the BIOS reserved
0062      * area is absent. We'll just have to assume that the
0063      * paravirt case can handle memory setup correctly,
0064      * without our help.
0065      */
0066     if (!x86_platform.legacy.reserve_bios_regions)
0067         return;
0068 
0069     /*
0070      * BIOS RAM size is encoded in kilobytes, convert it
0071      * to bytes to get a first guess at where the BIOS
0072      * firmware area starts:
0073      */
0074     bios_start = *(unsigned short *)__va(BIOS_RAM_SIZE_KB_PTR);
0075     bios_start <<= 10;
0076 
0077     /*
0078      * If bios_start is less than 128K, assume it is bogus
0079      * and bump it up to 640K.  Similarly, if bios_start is above 640K,
0080      * don't trust it.
0081      */
0082     if (bios_start < BIOS_START_MIN || bios_start > BIOS_START_MAX)
0083         bios_start = BIOS_START_MAX;
0084 
0085     /* Get the start address of the EBDA page: */
0086     ebda_start = get_bios_ebda();
0087 
0088     /*
0089      * If the EBDA start address is sane and is below the BIOS region,
0090      * then also reserve everything from the EBDA start address up to
0091      * the BIOS region.
0092      */
0093     if (ebda_start >= BIOS_START_MIN && ebda_start < bios_start)
0094         bios_start = ebda_start;
0095 
0096     /* Reserve all memory between bios_start and the 1MB mark: */
0097     memblock_reserve(bios_start, 0x100000 - bios_start);
0098 }