aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/kernel/setup.c')
-rw-r--r--arch/x86_64/kernel/setup.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index ebc3c33b1c6c..f0870bef24d1 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -571,17 +571,28 @@ static inline void copy_edd(void)
571#endif 571#endif
572 572
573#define EBDA_ADDR_POINTER 0x40E 573#define EBDA_ADDR_POINTER 0x40E
574static void __init reserve_ebda_region(void) 574
575unsigned __initdata ebda_addr;
576unsigned __initdata ebda_size;
577
578static void discover_ebda(void)
575{ 579{
576 unsigned int addr; 580 /*
577 /**
578 * there is a real-mode segmented pointer pointing to the 581 * there is a real-mode segmented pointer pointing to the
579 * 4K EBDA area at 0x40E 582 * 4K EBDA area at 0x40E
580 */ 583 */
581 addr = *(unsigned short *)phys_to_virt(EBDA_ADDR_POINTER); 584 ebda_addr = *(unsigned short *)EBDA_ADDR_POINTER;
582 addr <<= 4; 585 ebda_addr <<= 4;
583 if (addr) 586
584 reserve_bootmem_generic(addr, PAGE_SIZE); 587 ebda_size = *(unsigned short *)(unsigned long)ebda_addr;
588
589 /* Round EBDA up to pages */
590 if (ebda_size == 0)
591 ebda_size = 1;
592 ebda_size <<= 10;
593 ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE);
594 if (ebda_size > 64*1024)
595 ebda_size = 64*1024;
585} 596}
586 597
587void __init setup_arch(char **cmdline_p) 598void __init setup_arch(char **cmdline_p)
@@ -627,6 +638,8 @@ void __init setup_arch(char **cmdline_p)
627 638
628 check_efer(); 639 check_efer();
629 640
641 discover_ebda();
642
630 init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT)); 643 init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
631 644
632 dmi_scan_machine(); 645 dmi_scan_machine();
@@ -669,7 +682,8 @@ void __init setup_arch(char **cmdline_p)
669 reserve_bootmem_generic(0, PAGE_SIZE); 682 reserve_bootmem_generic(0, PAGE_SIZE);
670 683
671 /* reserve ebda region */ 684 /* reserve ebda region */
672 reserve_ebda_region(); 685 if (ebda_addr)
686 reserve_bootmem_generic(ebda_addr, ebda_size);
673 687
674#ifdef CONFIG_SMP 688#ifdef CONFIG_SMP
675 /* 689 /*