Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 359254
b: refs/heads/master
c: 7c10093
h: refs/heads/master
v: v3
  • Loading branch information
H. Peter Anvin committed Feb 27, 2013
1 parent 2ceb9aa commit 4216e93
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 20 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 058e7b5814534461b0e2468fce5a8f8d2f43c38f
refs/heads/master: 7c10093692ed2e6f318387d96b829320aa0ca64c
53 changes: 34 additions & 19 deletions trunk/arch/x86/kernel/head.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
#include <asm/setup.h>
#include <asm/bios_ebda.h>

#define BIOS_LOWMEM_KILOBYTES 0x413

/*
* The BIOS places the EBDA/XBDA at the top of conventional
* memory, and usually decreases the reported amount of
Expand All @@ -16,17 +14,30 @@
* 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.
*
* This functions is deliberately very conservative. Losing
* memory in the bottom megabyte is rarely a problem, as long
* as we have enough memory to install the trampoline. Using
* memory that is in use by the BIOS or by some DMA device
* the BIOS didn't shut down *is* a big problem.
*/

#define BIOS_LOWMEM_KILOBYTES 0x413
#define LOWMEM_CAP 0x9f000U /* Absolute maximum */
#define INSANE_CUTOFF 0x20000U /* Less than this = insane */

void __init reserve_ebda_region(void)
{
unsigned int lowmem, ebda_addr;

/* To determine the position of the EBDA and the */
/* end of conventional memory, we need to look at */
/* the BIOS data area. In a paravirtual environment */
/* that area is absent. We'll just have to assume */
/* that the paravirt case can handle memory setup */
/* correctly, without our help. */
/*
* To determine the position of the EBDA and the
* end of conventional memory, we need to look at
* the BIOS data area. In a paravirtual environment
* that area is absent. We'll just have to assume
* that the paravirt case can handle memory setup
* correctly, without our help.
*/
if (paravirt_enabled())
return;

Expand All @@ -37,19 +48,23 @@ void __init reserve_ebda_region(void)
/* start of EBDA area */
ebda_addr = get_bios_ebda();

/* Fixup: bios puts an EBDA in the top 64K segment */
/* of conventional memory, but does not adjust lowmem. */
if ((lowmem - ebda_addr) <= 0x10000)
lowmem = ebda_addr;
/*
* Note: some old Dells seem to need 4k EBDA without
* reporting so, so just consider the memory above 0x9f000
* to be off limits (bugzilla 2990).
*/

/* If the EBDA address is below 128K, assume it is bogus */
if (ebda_addr < INSANE_CUTOFF)
ebda_addr = LOWMEM_CAP;

/* Fixup: bios does not report an EBDA at all. */
/* Some old Dells seem to need 4k anyhow (bugzilla 2990) */
if ((ebda_addr == 0) && (lowmem >= 0x9f000))
lowmem = 0x9f000;
/* If lowmem is less than 128K, assume it is bogus */
if (lowmem < INSANE_CUTOFF)
lowmem = LOWMEM_CAP;

/* Paranoia: should never happen, but... */
if ((lowmem == 0) || (lowmem >= 0x100000))
lowmem = 0x9f000;
/* Use the lower of the lowmem and EBDA markers as the cutoff */
lowmem = min(lowmem, ebda_addr);
lowmem = min(lowmem, LOWMEM_CAP); /* Absolute cap */

/* reserve all memory between lowmem and the 1MB mark */
memblock_reserve(lowmem, 0x100000 - lowmem);
Expand Down

0 comments on commit 4216e93

Please sign in to comment.