apu_boot.S 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include "../common/asm.h"
  2. .align 0x1000 // 按照4k对齐
  3. .text
  4. .code16
  5. ENTRY(_apu_boot_start)
  6. _apu_boot_base = .
  7. cli
  8. wbinvd // 将处理器缓存同步到内存中
  9. mov %cs, %ax
  10. mov %ax, %ds
  11. mov %ax, %es
  12. mov %ax, %ss
  13. mov %ax, %fs
  14. mov %ax, %gs
  15. // 设置栈指针
  16. movl $(_apu_boot_tmp_stack_end - _apu_boot_base), %esp
  17. // 计算ap处理器引导程序的基地址
  18. mov %cs, %ax
  19. movzx %ax, %esi
  20. shll $4, %esi
  21. // set gdt and 32bit/64bit code addr
  22. leal (_apu_code32 - _apu_boot_base)(%esi), %eax
  23. movl %eax, (_apu_code32_vector - _apu_boot_base)
  24. leal (_apu_code64 - _apu_boot_base)(%esi), %eax
  25. movl %eax, (_apu_code64_vector - _apu_boot_base)
  26. leal (_apu_tmp_gdt - _apu_boot_base)(%esi), %eax
  27. movl %eax, (_apu_tmp_gdt + 2 - _apu_boot_base)
  28. // 从实模式切换到保护模式
  29. lidtl _apu_tmp_idt - _apu_boot_base
  30. lgdtl _apu_tmp_gdt - _apu_boot_base
  31. // 操作cr0控制器,使能保护模式
  32. smsw %ax
  33. bts $0, %ax
  34. lmsw %ax
  35. // 转到保护模式
  36. ljmpl *(_apu_code32_vector - _apu_boot_base)
  37. .code32
  38. .align 0x1000
  39. _apu_code32:
  40. # 转到长模式
  41. mov $0x10, %ax
  42. mov %ax, %ds
  43. mov %ax, %es
  44. mov %ax, %ss
  45. mov %ax, %fs
  46. mov %ax, %gs
  47. // 设置栈指针
  48. leal (_apu_boot_tmp_stack_end - _apu_boot_base)(%esi), %eax
  49. movl %eax, %esp
  50. // 1. 允许 PAE
  51. mov %cr4, %eax
  52. or $(1<<5), %eax
  53. mov %eax, %cr4
  54. /*
  55. movl $enter_head_from_ap_boot, %eax
  56. jmpl *%eax
  57. hlt
  58. */
  59. // 设置页表
  60. movl $pml4, %eax // 复用bsp处理器初始化时的32位页表
  61. movl %eax, %cr3
  62. // enable long mode
  63. movl $0xC0000080, %ecx
  64. rdmsr
  65. bts $8, %eax
  66. wrmsr
  67. // enable PE and paging
  68. mov %cr0, %eax
  69. bts $0, %eax
  70. bts $31, %eax
  71. mov %eax, %cr0
  72. // 跳转到64位代码
  73. ljmp *(_apu_code64_vector - _apu_boot_base)(%esi)
  74. .code64
  75. .align 0x1000
  76. _apu_code64:
  77. movq $0x20, %rax
  78. movq %rax, %ds
  79. movq %rax, %es
  80. movq %rax, %ss
  81. movq %rax, %fs
  82. movq %rax, %gs
  83. //now enable SSE and the like
  84. movq %cr0, %rax
  85. and $0xFFFB, %ax //clear coprocessor emulation CR0.EM
  86. or $0x2, %ax //set coprocessor monitoring CR0.MP
  87. movq %rax, %cr0
  88. movq %cr4, %rax
  89. or $(3 << 9), %ax //set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
  90. movq %rax, %cr4
  91. // 跳转到地址1MB处执行
  92. movq $_start64, %rax
  93. jmpq *%rax
  94. hlt
  95. .align 0x1000
  96. _apu_tmp_idt:
  97. .word 0
  98. .word 0,0
  99. .align 0x1000
  100. _apu_tmp_gdt:
  101. .short _apu_tmp_gdt_end - _apu_tmp_gdt -1
  102. .long _apu_tmp_gdt - _apu_boot_base
  103. .short 0
  104. .quad 0x00cf9a000000ffff
  105. .quad 0x00cf92000000ffff
  106. .quad 0x0020980000000000
  107. .quad 0x0000920000000000
  108. _apu_tmp_gdt_end:
  109. .align 0x1000
  110. _apu_code32_vector:
  111. .long _apu_code32 - _apu_boot_base
  112. .word 0x08,0
  113. .align 0x1000
  114. _apu_code64_vector:
  115. .long _apu_code64 - _apu_boot_base
  116. .word 0x18,0
  117. .align 0x1000
  118. _apu_boot_tmp_stack_start:
  119. // .org 0x400
  120. _apu_boot_tmp_stack_end:
  121. ENTRY(_apu_boot_end)