|
@@ -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
|
|
@@ -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;
|
|
|
|
|
@@ -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);
|