wakeup.S 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * ACPI wakeup real mode startup stub
  3. */
  4. #include <asm/segment.h>
  5. #include <asm/msr-index.h>
  6. #include <asm/page.h>
  7. #include <asm/pgtable.h>
  8. .code16
  9. .section ".header", "a"
  10. /* This should match the structure in wakeup.h */
  11. .globl wakeup_header
  12. wakeup_header:
  13. video_mode: .short 0 /* Video mode number */
  14. pmode_return: .byte 0x66, 0xea /* ljmpl */
  15. .long 0 /* offset goes here */
  16. .short __KERNEL_CS
  17. pmode_cr0: .long 0 /* Saved %cr0 */
  18. pmode_cr3: .long 0 /* Saved %cr3 */
  19. pmode_cr4: .long 0 /* Saved %cr4 */
  20. pmode_efer: .quad 0 /* Saved EFER */
  21. pmode_gdt: .quad 0
  22. realmode_flags: .long 0
  23. real_magic: .long 0
  24. trampoline_segment: .word 0
  25. signature: .long 0x51ee1111
  26. .text
  27. .globl _start
  28. .code16
  29. wakeup_code:
  30. _start:
  31. cli
  32. cld
  33. /* Set up segments */
  34. movw %cs, %ax
  35. movw %ax, %ds
  36. movw %ax, %es
  37. movw %ax, %ss
  38. movl $wakeup_stack_end, %esp
  39. /* Clear the EFLAGS */
  40. pushl $0
  41. popfl
  42. /* Check header signature... */
  43. movl signature, %eax
  44. cmpl $0x51ee1111, %eax
  45. jne bogus_real_magic
  46. /* Check we really have everything... */
  47. movl end_signature, %eax
  48. cmpl $0x65a22c82, %eax
  49. jne bogus_real_magic
  50. /* Call the C code */
  51. calll main
  52. /* Do any other stuff... */
  53. #ifndef CONFIG_64BIT
  54. /* This could also be done in C code... */
  55. movl pmode_cr3, %eax
  56. movl %eax, %cr3
  57. movl pmode_cr4, %ecx
  58. jecxz 1f
  59. movl %ecx, %cr4
  60. 1:
  61. movl pmode_efer, %eax
  62. movl pmode_efer + 4, %edx
  63. movl %eax, %ecx
  64. orl %edx, %ecx
  65. jz 1f
  66. movl $0xc0000080, %ecx
  67. wrmsr
  68. 1:
  69. lgdtl pmode_gdt
  70. /* This really couldn't... */
  71. movl pmode_cr0, %eax
  72. movl %eax, %cr0
  73. jmp pmode_return
  74. #else
  75. pushw $0
  76. pushw trampoline_segment
  77. pushw $0
  78. lret
  79. #endif
  80. bogus_real_magic:
  81. 1:
  82. hlt
  83. jmp 1b
  84. .data
  85. .balign 4
  86. .globl HEAP, heap_end
  87. HEAP:
  88. .long wakeup_heap
  89. heap_end:
  90. .long wakeup_stack
  91. .bss
  92. wakeup_heap:
  93. .space 2048
  94. wakeup_stack:
  95. .space 2048
  96. wakeup_stack_end: