apu_boot.S 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. // 1. 允许 PAE
  48. mov %cr4, %eax
  49. or $(1<<5), %eax
  50. mov %eax, %cr4
  51. movl $enter_head_from_ap_boot, %eax
  52. jmpl *%eax
  53. hlt
  54. // 设置栈指针
  55. leal (_apu_boot_tmp_stack_end - _apu_boot_base)(%esi), %eax
  56. movl %eax, %esp
  57. // open PAE
  58. movl %cr4, %eax
  59. bts $5, %eax
  60. movl %eax, %cr4
  61. // 设置页表
  62. movl $pml4, %eax // 复用bsp处理器初始化时的32位页表
  63. movl %eax, %cr3
  64. movl $0xC0000080, %ecx
  65. rdmsr
  66. bts $8, %eax
  67. wrmsr
  68. // enable PE and paging
  69. mov %cr0, %eax
  70. or $(1<<31), %eax
  71. or $(1<<0), %eax
  72. mov %eax, %cr0
  73. // 跳转到64位代码
  74. ljmp *(_apu_code64_vector - _apu_boot_base)(%esi)
  75. .code64
  76. .align 0x1000
  77. _apu_code64:
  78. movq $0x20, %rax
  79. movq %rax, %ds
  80. movq %rax, %es
  81. movq %rax, %ss
  82. movq %rax, %fs
  83. movq %rax, %gs
  84. //now enable SSE and the like
  85. movq %cr0, %rax
  86. and $0xFFFB, %ax //clear coprocessor emulation CR0.EM
  87. or $0x2, %ax //set coprocessor monitoring CR0.MP
  88. movq %rax, %cr0
  89. movq %cr4, %rax
  90. or $(3 << 9), %ax //set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
  91. movq %rax, %cr4
  92. // 跳转到地址1MB处执行
  93. movq $_start64, %rax
  94. jmpq *%rax
  95. hlt
  96. .align 0x1000
  97. _apu_tmp_idt:
  98. .word 0
  99. .word 0,0
  100. .align 0x1000
  101. _apu_tmp_gdt:
  102. .short _apu_tmp_gdt_end - _apu_tmp_gdt -1
  103. .long _apu_tmp_gdt - _apu_boot_base
  104. .short 0
  105. .quad 0x00cf9a000000ffff
  106. .quad 0x00cf92000000ffff
  107. .quad 0x0020980000000000
  108. .quad 0x0000920000000000
  109. _apu_tmp_gdt_end:
  110. .align 0x1000
  111. _apu_code32_vector:
  112. .long _apu_code32 - _apu_boot_base
  113. .word 0x08,0
  114. .align 0x1000
  115. _apu_code64_vector:
  116. .long _apu_code64 - _apu_boot_base
  117. .word 0x18,0
  118. .align 0x1000
  119. _apu_boot_tmp_stack_start:
  120. // .org 0x400
  121. _apu_boot_tmp_stack_end:
  122. ENTRY(_apu_boot_end)