1#include <linux/io.h> 2 3#include <asm/trampoline.h> 4#include <asm/pgtable.h> 5#include <asm/e820.h> 6 7#if defined(CONFIG_X86_64) && defined(CONFIG_ACPI_SLEEP) 8#define __trampinit 9#define __trampinitdata 10#else 11#define __trampinit __cpuinit 12#define __trampinitdata __cpuinitdata 13#endif 14 15/* ready for x86_64 and x86 */ 16unsigned char *__trampinitdata trampoline_base; 17 18void __init reserve_trampoline_memory(void) 19{ 20 unsigned long mem; 21 22 /* Has to be in very low memory so we can execute real-mode AP code. */ 23 mem = find_e820_area(0, 1<<20, TRAMPOLINE_SIZE, PAGE_SIZE); 24 if (mem == -1L) 25 panic("Cannot allocate trampoline\n"); 26 27 trampoline_base = __va(mem); 28 reserve_early(mem, mem + TRAMPOLINE_SIZE, "TRAMPOLINE"); 29} 30 31/* 32 * Currently trivial. Write the real->protected mode 33 * bootstrap into the page concerned. The caller 34 * has made sure it's suitably aligned. 35 */ 36unsigned long __trampinit setup_trampoline(void) 37{ 38 memcpy(trampoline_base, trampoline_data, TRAMPOLINE_SIZE); 39 return virt_to_phys(trampoline_base); 40} 41 42void __init setup_trampoline_page_table(void) 43{ 44#ifdef CONFIG_X86_32 45 /* Copy kernel address range */ 46 clone_pgd_range(trampoline_pg_dir + KERNEL_PGD_BOUNDARY, 47 swapper_pg_dir + KERNEL_PGD_BOUNDARY, 48 KERNEL_PGD_PTRS); 49 50 /* Initialize low mappings */ 51 clone_pgd_range(trampoline_pg_dir, 52 swapper_pg_dir + KERNEL_PGD_BOUNDARY, 53 min_t(unsigned long, KERNEL_PGD_PTRS, 54 KERNEL_PGD_BOUNDARY)); 55#endif 56} 57