]>
Commit | Line | Data |
---|---|---|
1 | #include <linux/kernel.h> | |
2 | #include <linux/init.h> | |
3 | #include <linux/memblock.h> | |
4 | ||
5 | #include <asm/setup.h> | |
6 | #include <asm/bios_ebda.h> | |
7 | ||
8 | /* | |
9 | * The BIOS places the EBDA/XBDA at the top of conventional | |
10 | * memory, and usually decreases the reported amount of | |
11 | * conventional memory (int 0x12) too. This also contains a | |
12 | * workaround for Dell systems that neglect to reserve EBDA. | |
13 | * The same workaround also avoids a problem with the AMD768MPX | |
14 | * chipset: reserve a page before VGA to prevent PCI prefetch | |
15 | * into it (errata #56). Usually the page is reserved anyways, | |
16 | * unless you have no PS/2 mouse plugged in. | |
17 | * | |
18 | * This functions is deliberately very conservative. Losing | |
19 | * memory in the bottom megabyte is rarely a problem, as long | |
20 | * as we have enough memory to install the trampoline. Using | |
21 | * memory that is in use by the BIOS or by some DMA device | |
22 | * the BIOS didn't shut down *is* a big problem. | |
23 | */ | |
24 | ||
25 | #define BIOS_LOWMEM_KILOBYTES 0x413 | |
26 | #define LOWMEM_CAP 0x9f000U /* Absolute maximum */ | |
27 | #define INSANE_CUTOFF 0x20000U /* Less than this = insane */ | |
28 | ||
29 | void __init reserve_ebda_region(void) | |
30 | { | |
31 | unsigned int lowmem, ebda_addr; | |
32 | ||
33 | /* | |
34 | * To determine the position of the EBDA and the | |
35 | * end of conventional memory, we need to look at | |
36 | * the BIOS data area. In a paravirtual environment | |
37 | * that area is absent. We'll just have to assume | |
38 | * that the paravirt case can handle memory setup | |
39 | * correctly, without our help. | |
40 | */ | |
41 | if (paravirt_enabled()) | |
42 | return; | |
43 | ||
44 | /* end of low (conventional) memory */ | |
45 | lowmem = *(unsigned short *)__va(BIOS_LOWMEM_KILOBYTES); | |
46 | lowmem <<= 10; | |
47 | ||
48 | /* start of EBDA area */ | |
49 | ebda_addr = get_bios_ebda(); | |
50 | ||
51 | /* | |
52 | * Note: some old Dells seem to need 4k EBDA without | |
53 | * reporting so, so just consider the memory above 0x9f000 | |
54 | * to be off limits (bugzilla 2990). | |
55 | */ | |
56 | ||
57 | /* If the EBDA address is below 128K, assume it is bogus */ | |
58 | if (ebda_addr < INSANE_CUTOFF) | |
59 | ebda_addr = LOWMEM_CAP; | |
60 | ||
61 | /* If lowmem is less than 128K, assume it is bogus */ | |
62 | if (lowmem < INSANE_CUTOFF) | |
63 | lowmem = LOWMEM_CAP; | |
64 | ||
65 | /* Use the lower of the lowmem and EBDA markers as the cutoff */ | |
66 | lowmem = min(lowmem, ebda_addr); | |
67 | lowmem = min(lowmem, LOWMEM_CAP); /* Absolute cap */ | |
68 | ||
69 | /* reserve all memory between lowmem and the 1MB mark */ | |
70 | memblock_reserve(lowmem, 0x100000 - lowmem); | |
71 | } |