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/setup_64.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/setup_64.c')
-rw-r--r-- | arch/x86/kernel/setup_64.c | 67 |
1 files changed, 3 insertions, 64 deletions
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index 4a3f00b49236..6cbd15625dce 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c | |||
@@ -245,41 +245,6 @@ static inline void __init reserve_crashkernel(void) | |||
245 | {} | 245 | {} |
246 | #endif | 246 | #endif |
247 | 247 | ||
248 | #define EBDA_ADDR_POINTER 0x40E | ||
249 | |||
250 | unsigned __initdata ebda_addr; | ||
251 | unsigned __initdata ebda_size; | ||
252 | |||
253 | static void __init discover_ebda(void) | ||
254 | { | ||
255 | /* | ||
256 | * there is a real-mode segmented pointer pointing to the | ||
257 | * 4K EBDA area at 0x40E | ||
258 | */ | ||
259 | ebda_addr = *(unsigned short *)__va(EBDA_ADDR_POINTER); | ||
260 | /* | ||
261 | * There can be some situations, like paravirtualized guests, | ||
262 | * in which there is no available ebda information. In such | ||
263 | * case, just skip it | ||
264 | */ | ||
265 | if (!ebda_addr) { | ||
266 | ebda_size = 0; | ||
267 | return; | ||
268 | } | ||
269 | |||
270 | ebda_addr <<= 4; | ||
271 | |||
272 | ebda_size = *(unsigned short *)__va(ebda_addr); | ||
273 | |||
274 | /* Round EBDA up to pages */ | ||
275 | if (ebda_size == 0) | ||
276 | ebda_size = 1; | ||
277 | ebda_size <<= 10; | ||
278 | ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE); | ||
279 | if (ebda_size > 64*1024) | ||
280 | ebda_size = 64*1024; | ||
281 | } | ||
282 | |||
283 | /* Overridden in paravirt.c if CONFIG_PARAVIRT */ | 248 | /* Overridden in paravirt.c if CONFIG_PARAVIRT */ |
284 | void __attribute__((weak)) __init memory_setup(void) | 249 | void __attribute__((weak)) __init memory_setup(void) |
285 | { | 250 | { |
@@ -349,8 +314,6 @@ void __init setup_arch(char **cmdline_p) | |||
349 | 314 | ||
350 | check_efer(); | 315 | check_efer(); |
351 | 316 | ||
352 | discover_ebda(); | ||
353 | |||
354 | init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT)); | 317 | init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT)); |
355 | if (efi_enabled) | 318 | if (efi_enabled) |
356 | efi_init(); | 319 | efi_init(); |
@@ -397,33 +360,7 @@ void __init setup_arch(char **cmdline_p) | |||
397 | contig_initmem_init(0, end_pfn); | 360 | contig_initmem_init(0, end_pfn); |
398 | #endif | 361 | #endif |
399 | 362 | ||
400 | /* Reserve direct mapping */ | 363 | early_res_to_bootmem(); |
401 | reserve_bootmem_generic(table_start << PAGE_SHIFT, | ||
402 | (table_end - table_start) << PAGE_SHIFT); | ||
403 | |||
404 | /* reserve kernel */ | ||
405 | reserve_bootmem_generic(__pa_symbol(&_text), | ||
406 | __pa_symbol(&_end) - __pa_symbol(&_text)); | ||
407 | |||
408 | /* | ||
409 | * reserve physical page 0 - it's a special BIOS page on many boxes, | ||
410 | * enabling clean reboots, SMP operation, laptop functions. | ||
411 | */ | ||
412 | reserve_bootmem_generic(0, PAGE_SIZE); | ||
413 | |||
414 | /* reserve ebda region */ | ||
415 | if (ebda_addr) | ||
416 | reserve_bootmem_generic(ebda_addr, ebda_size); | ||
417 | #ifdef CONFIG_NUMA | ||
418 | /* reserve nodemap region */ | ||
419 | if (nodemap_addr) | ||
420 | reserve_bootmem_generic(nodemap_addr, nodemap_size); | ||
421 | #endif | ||
422 | |||
423 | #ifdef CONFIG_SMP | ||
424 | /* Reserve SMP trampoline */ | ||
425 | reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, 2*PAGE_SIZE); | ||
426 | #endif | ||
427 | 364 | ||
428 | #ifdef CONFIG_ACPI_SLEEP | 365 | #ifdef CONFIG_ACPI_SLEEP |
429 | /* | 366 | /* |
@@ -453,6 +390,8 @@ void __init setup_arch(char **cmdline_p) | |||
453 | initrd_start = ramdisk_image + PAGE_OFFSET; | 390 | initrd_start = ramdisk_image + PAGE_OFFSET; |
454 | initrd_end = initrd_start+ramdisk_size; | 391 | initrd_end = initrd_start+ramdisk_size; |
455 | } else { | 392 | } else { |
393 | /* Assumes everything on node 0 */ | ||
394 | free_bootmem(ramdisk_image, ramdisk_size); | ||
456 | printk(KERN_ERR "initrd extends beyond end of memory " | 395 | printk(KERN_ERR "initrd extends beyond end of memory " |
457 | "(0x%08lx > 0x%08lx)\ndisabling initrd\n", | 396 | "(0x%08lx > 0x%08lx)\ndisabling initrd\n", |
458 | ramdisk_end, end_of_mem); | 397 | ramdisk_end, end_of_mem); |