aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/setup_64.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2008-01-30 07:33:17 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:33:17 -0500
commit751752789162fde69474edfa15935d0a77c0bc17 (patch)
tree43eef77784989bc25979da1cc128e31fc46b3cea /arch/x86/kernel/setup_64.c
parentedcd81199dbad5db11ae91b507cec1d46dd94a49 (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.c67
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
250unsigned __initdata ebda_addr;
251unsigned __initdata ebda_size;
252
253static 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 */
284void __attribute__((weak)) __init memory_setup(void) 249void __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);