1#include <linux/kernel.h> 2#include <linux/init.h> 3 4#include <asm/setup.h> 5#include <asm/bios_ebda.h> 6 7#define BIOS_LOWMEM_KILOBYTES 0x413 8 9/* 10 * The BIOS places the EBDA/XBDA at the top of conventional 11 * memory, and usually decreases the reported amount of 12 * conventional memory (int 0x12) too. This also contains a 13 * workaround for Dell systems that neglect to reserve EBDA. 14 * The same workaround also avoids a problem with the AMD768MPX 15 * chipset: reserve a page before VGA to prevent PCI prefetch 16 * into it (errata #56). Usually the page is reserved anyways, 17 * unless you have no PS/2 mouse plugged in. 18 */ 19void __init reserve_ebda_region(void) 20{ 21 unsigned int lowmem, ebda_addr; 22 23 /* To determine the position of the EBDA and the */ 24 /* end of conventional memory, we need to look at */ 25 /* the BIOS data area. In a paravirtual environment */ 26 /* that area is absent. We'll just have to assume */ 27 /* that the paravirt case can handle memory setup */ 28 /* correctly, without our help. */ 29 if (paravirt_enabled()) 30 return; 31 32 /* end of low (conventional) memory */ 33 lowmem = *(unsigned short *)__va(BIOS_LOWMEM_KILOBYTES); 34 lowmem <<= 10; 35 36 /* start of EBDA area */ 37 ebda_addr = get_bios_ebda(); 38 printk(KERN_INFO "BIOS EBDA/lowmem at: %08x/%08x\n", ebda_addr, lowmem); 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 reserve_early_overlap_ok(lowmem, 0x100000, "BIOS reserved"); 56} 57

