trampoline.c 1.4 KB

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