diff options
author | Andi Kleen <ak@suse.de> | 2008-01-30 07:33:17 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:33:17 -0500 |
commit | 751752789162fde69474edfa15935d0a77c0bc17 (patch) | |
tree | 43eef77784989bc25979da1cc128e31fc46b3cea /arch/x86/kernel/head64.c | |
parent | edcd81199dbad5db11ae91b507cec1d46dd94a49 (diff) |
x86: replace hard coded reservations in 64-bit early boot code with dynamic table
On x86-64 there are several memory allocations before bootmem. To avoid
them stomping on each other they used to be all hard coded in bad_area().
Replace this with an array that is filled as needed.
This cleans up the code considerably and allows to expand its use.
Cc: peterz@infradead.org
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/head64.c')
-rw-r--r-- | arch/x86/kernel/head64.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 87e031d4abf1..58438bafedca 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/tlbflush.h> | 21 | #include <asm/tlbflush.h> |
22 | #include <asm/sections.h> | 22 | #include <asm/sections.h> |
23 | #include <asm/kdebug.h> | 23 | #include <asm/kdebug.h> |
24 | #include <asm/e820.h> | ||
24 | 25 | ||
25 | static void __init zap_identity_mappings(void) | 26 | static void __init zap_identity_mappings(void) |
26 | { | 27 | { |
@@ -48,6 +49,35 @@ static void __init copy_bootdata(char *real_mode_data) | |||
48 | } | 49 | } |
49 | } | 50 | } |
50 | 51 | ||
52 | #define EBDA_ADDR_POINTER 0x40E | ||
53 | |||
54 | static __init void reserve_ebda(void) | ||
55 | { | ||
56 | unsigned ebda_addr, ebda_size; | ||
57 | |||
58 | /* | ||
59 | * there is a real-mode segmented pointer pointing to the | ||
60 | * 4K EBDA area at 0x40E | ||
61 | */ | ||
62 | ebda_addr = *(unsigned short *)__va(EBDA_ADDR_POINTER); | ||
63 | ebda_addr <<= 4; | ||
64 | |||
65 | if (!ebda_addr) | ||
66 | return; | ||
67 | |||
68 | ebda_size = *(unsigned short *)__va(ebda_addr); | ||
69 | |||
70 | /* Round EBDA up to pages */ | ||
71 | if (ebda_size == 0) | ||
72 | ebda_size = 1; | ||
73 | ebda_size <<= 10; | ||
74 | ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE); | ||
75 | if (ebda_size > 64*1024) | ||
76 | ebda_size = 64*1024; | ||
77 | |||
78 | reserve_early(ebda_addr, ebda_addr + ebda_size); | ||
79 | } | ||
80 | |||
51 | void __init x86_64_start_kernel(char * real_mode_data) | 81 | void __init x86_64_start_kernel(char * real_mode_data) |
52 | { | 82 | { |
53 | int i; | 83 | int i; |
@@ -75,5 +105,23 @@ void __init x86_64_start_kernel(char * real_mode_data) | |||
75 | pda_init(0); | 105 | pda_init(0); |
76 | copy_bootdata(__va(real_mode_data)); | 106 | copy_bootdata(__va(real_mode_data)); |
77 | 107 | ||
108 | reserve_early(__pa_symbol(&_text), __pa_symbol(&_end)); | ||
109 | |||
110 | /* Reserve INITRD */ | ||
111 | if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { | ||
112 | unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; | ||
113 | unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; | ||
114 | unsigned long ramdisk_end = ramdisk_image + ramdisk_size; | ||
115 | reserve_early(ramdisk_image, ramdisk_end); | ||
116 | } | ||
117 | |||
118 | reserve_ebda(); | ||
119 | |||
120 | /* | ||
121 | * At this point everything still needed from the boot loader | ||
122 | * or BIOS or kernel text should be early reserved or marked not | ||
123 | * RAM in e820. All other memory is free game. | ||
124 | */ | ||
125 | |||
78 | start_kernel(); | 126 | start_kernel(); |
79 | } | 127 | } |