Greg Kroah-Hartman | b244131 | 2017-11-01 15:07:57 +0100 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
Huang, Ying | 0c51a96 | 2008-06-02 14:26:23 +0800 | [diff] [blame] | 2 | #include <linux/kernel.h> |
| 3 | #include <linux/init.h> |
Yinghai Lu | 72d7c3b | 2010-08-25 13:39:17 -0700 | [diff] [blame] | 4 | #include <linux/memblock.h> |
Huang, Ying | 0c51a96 | 2008-06-02 14:26:23 +0800 | [diff] [blame] | 5 | |
| 6 | #include <asm/setup.h> |
| 7 | #include <asm/bios_ebda.h> |
| 8 | |
Huang, Ying | 0c51a96 | 2008-06-02 14:26:23 +0800 | [diff] [blame] | 9 | /* |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 10 | * This function reserves all conventional PC system BIOS related |
| 11 | * firmware memory areas (some of which are data, some of which |
| 12 | * are code), that must not be used by the kernel as available |
| 13 | * RAM. |
| 14 | * |
Huang, Ying | 0c51a96 | 2008-06-02 14:26:23 +0800 | [diff] [blame] | 15 | * The BIOS places the EBDA/XBDA at the top of conventional |
| 16 | * memory, and usually decreases the reported amount of |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 17 | * conventional memory (int 0x12) too. |
H. Peter Anvin | 7c10093 | 2013-02-27 12:46:40 -0800 | [diff] [blame] | 18 | * |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 19 | * This means that as a first approximation on most systems we can |
| 20 | * guess the reserved BIOS area by looking at the low BIOS RAM size |
| 21 | * value and assume that everything above that value (up to 1MB) is |
| 22 | * reserved. |
| 23 | * |
| 24 | * But life in firmware country is not that simple: |
| 25 | * |
| 26 | * - This code also contains a quirk for Dell systems that neglect |
| 27 | * to reserve the EBDA area in the 'RAM size' value ... |
| 28 | * |
| 29 | * - The same quirk also avoids a problem with the AMD768MPX |
| 30 | * chipset: reserve a page before VGA to prevent PCI prefetch |
| 31 | * into it (errata #56). (Usually the page is reserved anyways, |
| 32 | * unless you have no PS/2 mouse plugged in.) |
| 33 | * |
| 34 | * - Plus paravirt systems don't have a reliable value in the |
| 35 | * 'BIOS RAM size' pointer we can rely on, so we must quirk |
| 36 | * them too. |
| 37 | * |
| 38 | * Due to those various problems this function is deliberately |
| 39 | * very conservative and tries to err on the side of reserving |
| 40 | * too much, to not risk reserving too little. |
| 41 | * |
| 42 | * Losing a small amount of memory in the bottom megabyte is |
| 43 | * rarely a problem, as long as we have enough memory to install |
| 44 | * the SMP bootup trampoline which *must* be in this area. |
| 45 | * |
| 46 | * Using memory that is in use by the BIOS or by some DMA device |
| 47 | * the BIOS didn't shut down *is* a big problem to the kernel, |
| 48 | * obviously. |
Huang, Ying | 0c51a96 | 2008-06-02 14:26:23 +0800 | [diff] [blame] | 49 | */ |
H. Peter Anvin | 7c10093 | 2013-02-27 12:46:40 -0800 | [diff] [blame] | 50 | |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 51 | #define BIOS_RAM_SIZE_KB_PTR 0x413 |
H. Peter Anvin | 7c10093 | 2013-02-27 12:46:40 -0800 | [diff] [blame] | 52 | |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 53 | #define BIOS_START_MIN 0x20000U /* 128K, less than this is insane */ |
| 54 | #define BIOS_START_MAX 0x9f000U /* 640K, absolute maximum */ |
| 55 | |
| 56 | void __init reserve_bios_regions(void) |
Huang, Ying | 0c51a96 | 2008-06-02 14:26:23 +0800 | [diff] [blame] | 57 | { |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 58 | unsigned int bios_start, ebda_start; |
Huang, Ying | 0c51a96 | 2008-06-02 14:26:23 +0800 | [diff] [blame] | 59 | |
H. Peter Anvin | 7c10093 | 2013-02-27 12:46:40 -0800 | [diff] [blame] | 60 | /* |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 61 | * NOTE: In a paravirtual environment the BIOS reserved |
| 62 | * area is absent. We'll just have to assume that the |
| 63 | * paravirt case can handle memory setup correctly, |
| 64 | * without our help. |
H. Peter Anvin | 7c10093 | 2013-02-27 12:46:40 -0800 | [diff] [blame] | 65 | */ |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 66 | if (!x86_platform.legacy.reserve_bios_regions) |
Huang, Ying | 0c51a96 | 2008-06-02 14:26:23 +0800 | [diff] [blame] | 67 | return; |
| 68 | |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 69 | /* |
| 70 | * BIOS RAM size is encoded in kilobytes, convert it |
| 71 | * to bytes to get a first guess at where the BIOS |
| 72 | * firmware area starts: |
| 73 | */ |
| 74 | bios_start = *(unsigned short *)__va(BIOS_RAM_SIZE_KB_PTR); |
| 75 | bios_start <<= 10; |
Huang, Ying | 0c51a96 | 2008-06-02 14:26:23 +0800 | [diff] [blame] | 76 | |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 77 | /* |
| 78 | * If bios_start is less than 128K, assume it is bogus |
Andy Lutomirski | 6a79296 | 2016-07-21 14:16:52 -0700 | [diff] [blame] | 79 | * and bump it up to 640K. Similarly, if bios_start is above 640K, |
| 80 | * don't trust it. |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 81 | */ |
Andy Lutomirski | 6a79296 | 2016-07-21 14:16:52 -0700 | [diff] [blame] | 82 | if (bios_start < BIOS_START_MIN || bios_start > BIOS_START_MAX) |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 83 | bios_start = BIOS_START_MAX; |
H. Peter Anvin | 7c10093 | 2013-02-27 12:46:40 -0800 | [diff] [blame] | 84 | |
Andy Lutomirski | 6a79296 | 2016-07-21 14:16:52 -0700 | [diff] [blame] | 85 | /* Get the start address of the EBDA page: */ |
| 86 | ebda_start = get_bios_ebda(); |
| 87 | |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 88 | /* |
Andy Lutomirski | 6a79296 | 2016-07-21 14:16:52 -0700 | [diff] [blame] | 89 | * If the EBDA start address is sane and is below the BIOS region, |
| 90 | * then also reserve everything from the EBDA start address up to |
| 91 | * the BIOS region. |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 92 | */ |
Andy Lutomirski | 6a79296 | 2016-07-21 14:16:52 -0700 | [diff] [blame] | 93 | if (ebda_start >= BIOS_START_MIN && ebda_start < bios_start) |
| 94 | bios_start = ebda_start; |
Huang, Ying | 0c51a96 | 2008-06-02 14:26:23 +0800 | [diff] [blame] | 95 | |
Ingo Molnar | edce212 | 2016-07-21 09:53:52 +0200 | [diff] [blame] | 96 | /* Reserve all memory between bios_start and the 1MB mark: */ |
| 97 | memblock_reserve(bios_start, 0x100000 - bios_start); |
Huang, Ying | 0c51a96 | 2008-06-02 14:26:23 +0800 | [diff] [blame] | 98 | } |