aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/setup_32.c
diff options
context:
space:
mode:
authorAlexander van Heukelum <heukelum@mailshack.com>2008-03-01 11:09:12 -0500
committerIngo Molnar <mingo@elte.hu>2008-04-17 11:40:51 -0400
commitdedd04be71cea3d5adb14c8f674e801911c89a2f (patch)
tree616250e345885a6f43dba0f407280d0304997ae3 /arch/x86/kernel/setup_32.c
parent823c248e7cc75b4f22da914b01f8e5433cff197e (diff)
x86: reserve end-of-conventional-memory to 1MB on 32-bit
This patch adds explicit detection of the EBDA and reservation of the rom and adapter address space 0xa0000-0x100000 to the i386 kernels. Before this patch, the EBDA size was hardcoded as 4Kb. Also, the reservation of the adapter range was done by modifying the e820 map which is now not necessary any longer, and that code is removed from copy_e820_map. The amount of conventional memory and the start of the EBDA are detected by reading the BIOS data area directly. Paravirtual environments do not provide this area, so we bail out early in that case. They will just have to set up a correct memory map to start with. Signed-off-by: Alexander van Heukelum <heukelum@fastmail.fm> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/setup_32.c')
-rw-r--r--arch/x86/kernel/setup_32.c64
1 files changed, 51 insertions, 13 deletions
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index 2b3e5d45176b..14e293edd23f 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -385,15 +385,60 @@ unsigned long __init find_max_low_pfn(void)
385 return max_low_pfn; 385 return max_low_pfn;
386} 386}
387 387
388#define BIOS_EBDA_SEGMENT 0x40E
389#define BIOS_LOWMEM_KILOBYTES 0x413
390
388/* 391/*
389 * workaround for Dell systems that neglect to reserve EBDA 392 * The BIOS places the EBDA/XBDA at the top of conventional
393 * memory, and usually decreases the reported amount of
394 * conventional memory (int 0x12) too. This also contains a
395 * workaround for Dell systems that neglect to reserve EBDA.
396 * The same workaround also avoids a problem with the AMD768MPX
397 * chipset: reserve a page before VGA to prevent PCI prefetch
398 * into it (errata #56). Usually the page is reserved anyways,
399 * unless you have no PS/2 mouse plugged in.
390 */ 400 */
391static void __init reserve_ebda_region(void) 401static void __init reserve_ebda_region(void)
392{ 402{
393 unsigned int addr; 403 unsigned int lowmem, ebda_addr;
394 addr = get_bios_ebda(); 404
395 if (addr) 405 /* To determine the position of the EBDA and the */
396 reserve_bootmem(addr, PAGE_SIZE, BOOTMEM_DEFAULT); 406 /* end of conventional memory, we need to look at */
407 /* the BIOS data area. In a paravirtual environment */
408 /* that area is absent. We'll just have to assume */
409 /* that the paravirt case can handle memory setup */
410 /* correctly, without our help. */
411#ifdef CONFIG_PARAVIRT
412 if ((boot_params.hdr.version >= 0x207) &&
413 (boot_params.hdr.hardware_subarch != 0)) {
414 return;
415 }
416#endif
417
418 /* end of low (conventional) memory */
419 lowmem = *(unsigned short *)__va(BIOS_LOWMEM_KILOBYTES);
420 lowmem <<= 10;
421
422 /* start of EBDA area */
423 ebda_addr = *(unsigned short *)__va(BIOS_EBDA_SEGMENT);
424 ebda_addr <<= 4;
425
426 /* Fixup: bios puts an EBDA in the top 64K segment */
427 /* of conventional memory, but does not adjust lowmem. */
428 if ((lowmem - ebda_addr) <= 0x10000)
429 lowmem = ebda_addr;
430
431 /* Fixup: bios does not report an EBDA at all. */
432 /* Some old Dells seem to need 4k anyhow (bugzilla 2990) */
433 if ((ebda_addr == 0) && (lowmem >= 0x9f000))
434 lowmem = 0x9f000;
435
436 /* Paranoia: should never happen, but... */
437 if ((lowmem == 0) || (lowmem >= 0x100000))
438 lowmem = 0x9f000;
439
440 /* reserve all memory between lowmem and the 1MB mark */
441 reserve_bootmem(lowmem, 0x100000 - lowmem, BOOTMEM_DEFAULT);
397} 442}
398 443
399#ifndef CONFIG_NEED_MULTIPLE_NODES 444#ifndef CONFIG_NEED_MULTIPLE_NODES
@@ -617,16 +662,9 @@ void __init setup_bootmem_allocator(void)
617 */ 662 */
618 reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT); 663 reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT);
619 664
620 /* reserve EBDA region, it's a 4K region */ 665 /* reserve EBDA region */
621 reserve_ebda_region(); 666 reserve_ebda_region();
622 667
623 /* could be an AMD 768MPX chipset. Reserve a page before VGA to prevent
624 PCI prefetch into it (errata #56). Usually the page is reserved anyways,
625 unless you have no PS/2 mouse plugged in. */
626 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
627 boot_cpu_data.x86 == 6)
628 reserve_bootmem(0xa0000 - 4096, 4096, BOOTMEM_DEFAULT);
629
630#ifdef CONFIG_SMP 668#ifdef CONFIG_SMP
631 /* 669 /*
632 * But first pinch a few for the stack/trampoline stuff 670 * But first pinch a few for the stack/trampoline stuff