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 #define BIOS_LOWMEM_KILOBYTES 0x413 9 10 /* 11 * The BIOS places the EBDA/XBDA at the top of conventional 12 * memory, and usually decreases the reported amount of 13 * conventional memory (int 0x12) too. This also contains a 14 * workaround for Dell systems that neglect to reserve EBDA. 15 * The same workaround also avoids a problem with the AMD768MPX 16 * chipset: reserve a page before VGA to prevent PCI prefetch 17 * into it (errata #56). Usually the page is reserved anyways, 18 * unless you have no PS/2 mouse plugged in. 19 */ reserve_ebda_region(void)20void __init reserve_ebda_region(void) 21 { 22 unsigned int lowmem, ebda_addr; 23 24 /* To determine the position of the EBDA and the */ 25 /* end of conventional memory, we need to look at */ 26 /* the BIOS data area. In a paravirtual environment */ 27 /* that area is absent. We'll just have to assume */ 28 /* that the paravirt case can handle memory setup */ 29 /* correctly, without our help. */ 30 if (paravirt_enabled()) 31 return; 32 33 /* end of low (conventional) memory */ 34 lowmem = *(unsigned short *)__va(BIOS_LOWMEM_KILOBYTES); 35 lowmem <<= 10; 36 37 /* start of EBDA area */ 38 ebda_addr = get_bios_ebda(); 39 40 /* Fixup: bios puts an EBDA in the top 64K segment */ 41 /* of conventional memory, but does not adjust lowmem. */ 42 if ((lowmem - ebda_addr) <= 0x10000) 43 lowmem = ebda_addr; 44 45 /* Fixup: bios does not report an EBDA at all. */ 46 /* Some old Dells seem to need 4k anyhow (bugzilla 2990) */ 47 if ((ebda_addr == 0) && (lowmem >= 0x9f000)) 48 lowmem = 0x9f000; 49 50 /* Paranoia: should never happen, but... */ 51 if ((lowmem == 0) || (lowmem >= 0x100000)) 52 lowmem = 0x9f000; 53 54 /* reserve all memory between lowmem and the 1MB mark */ 55 memblock_reserve(lowmem, 0x100000 - lowmem); 56 } 57