diff options
| -rw-r--r-- | arch/x86_64/kernel/e820.c | 6 | ||||
| -rw-r--r-- | arch/x86_64/kernel/setup.c | 30 | ||||
| -rw-r--r-- | include/asm-x86_64/e820.h | 2 |
3 files changed, 30 insertions, 8 deletions
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 62776c07cff1..222b5b46d2b2 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c | |||
| @@ -76,6 +76,12 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size) | |||
| 76 | *addrp = __pa_symbol(&_end); | 76 | *addrp = __pa_symbol(&_end); |
| 77 | return 1; | 77 | return 1; |
| 78 | } | 78 | } |
| 79 | |||
| 80 | if (last >= ebda_addr && addr < ebda_addr + ebda_size) { | ||
| 81 | *addrp = ebda_addr + ebda_size; | ||
| 82 | return 1; | ||
| 83 | } | ||
| 84 | |||
| 79 | /* XXX ramdisk image here? */ | 85 | /* XXX ramdisk image here? */ |
| 80 | return 0; | 86 | return 0; |
| 81 | } | 87 | } |
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 |
| 574 | static void __init reserve_ebda_region(void) | 574 | |
| 575 | unsigned __initdata ebda_addr; | ||
| 576 | unsigned __initdata ebda_size; | ||
| 577 | |||
| 578 | static 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 | ||
| 587 | void __init setup_arch(char **cmdline_p) | 598 | void __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 | /* |
diff --git a/include/asm-x86_64/e820.h b/include/asm-x86_64/e820.h index 93b51df51687..670a3388e70a 100644 --- a/include/asm-x86_64/e820.h +++ b/include/asm-x86_64/e820.h | |||
| @@ -59,6 +59,8 @@ extern void __init parse_memopt(char *p, char **end); | |||
| 59 | extern void __init parse_memmapopt(char *p, char **end); | 59 | extern void __init parse_memmapopt(char *p, char **end); |
| 60 | 60 | ||
| 61 | extern struct e820map e820; | 61 | extern struct e820map e820; |
| 62 | |||
| 63 | extern unsigned ebda_addr, ebda_size; | ||
| 62 | #endif/*!__ASSEMBLY__*/ | 64 | #endif/*!__ASSEMBLY__*/ |
| 63 | 65 | ||
| 64 | #endif/*__E820_HEADER*/ | 66 | #endif/*__E820_HEADER*/ |
