cstart64.S 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #include "apic-defs.h"
  2. .globl boot_idt
  3. boot_idt = 0
  4. .globl idt_descr
  5. .globl tss_descr
  6. .globl gdt64_desc
  7. ipi_vector = 0x20
  8. max_cpus = 64
  9. .bss
  10. . = . + 4096 * max_cpus
  11. .align 16
  12. stacktop:
  13. . = . + 4096
  14. .align 16
  15. ring0stacktop:
  16. .data
  17. .align 4096
  18. .globl ptl2
  19. ptl2:
  20. i = 0
  21. .rept 512 * 4
  22. .quad 0x1e7 | (i << 21)
  23. i = i + 1
  24. .endr
  25. .align 4096
  26. ptl3:
  27. .quad ptl2 + 7 + 0 * 4096
  28. .quad ptl2 + 7 + 1 * 4096
  29. .quad ptl2 + 7 + 2 * 4096
  30. .quad ptl2 + 7 + 3 * 4096
  31. .align 4096
  32. ptl4:
  33. .quad ptl3 + 7
  34. .align 4096
  35. gdt64_desc:
  36. .word gdt64_end - gdt64 - 1
  37. .quad gdt64
  38. gdt64:
  39. .quad 0
  40. .quad 0x00af9b000000ffff // 64-bit code segment
  41. .quad 0x00cf93000000ffff // 32/64-bit data segment
  42. .quad 0x00af1b000000ffff // 64-bit code segment, not present
  43. .quad 0x00cf9b000000ffff // 32-bit code segment
  44. .quad 0x008f9b000000FFFF // 16-bit code segment
  45. .quad 0x008f93000000FFFF // 16-bit data segment
  46. .quad 0x00cffb000000ffff // 32-bit code segment (user)
  47. .quad 0x00cff3000000ffff // 32/64-bit data segment (user)
  48. .quad 0x00affb000000ffff // 64-bit code segment (user)
  49. .quad 0 // 6 spare selectors
  50. .quad 0
  51. .quad 0
  52. .quad 0
  53. .quad 0
  54. .quad 0
  55. tss_descr:
  56. .rept max_cpus
  57. .quad 0x000089000000ffff // 64-bit avail tss
  58. .quad 0 // tss high addr
  59. .endr
  60. gdt64_end:
  61. i = 0
  62. .globl tss
  63. tss:
  64. .rept max_cpus
  65. .long 0
  66. .quad ring0stacktop - i * 4096
  67. .quad 0, 0
  68. .quad 0, 0, 0, 0, 0, 0, 0, 0
  69. .long 0, 0, 0
  70. i = i + 1
  71. .endr
  72. tss_end:
  73. mb_boot_info: .quad 0
  74. .section .init
  75. .code32
  76. mb_magic = 0x1BADB002
  77. mb_flags = 0x0
  78. # multiboot header
  79. .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags)
  80. mb_cmdline = 16
  81. MSR_GS_BASE = 0xc0000101
  82. .macro setup_percpu_area
  83. lea -4096(%esp), %eax
  84. mov $0, %edx
  85. mov $MSR_GS_BASE, %ecx
  86. wrmsr
  87. .endm
  88. .globl start
  89. start:
  90. mov %ebx, mb_boot_info
  91. mov $stacktop, %esp
  92. setup_percpu_area
  93. call prepare_64
  94. jmpl $8, $start64
  95. prepare_64:
  96. lgdt gdt64_desc
  97. mov %cr4, %eax
  98. bts $5, %eax // pae
  99. mov %eax, %cr4
  100. mov $ptl4, %eax
  101. mov %eax, %cr3
  102. efer = 0xc0000080
  103. mov $efer, %ecx
  104. rdmsr
  105. bts $8, %eax
  106. wrmsr
  107. mov %cr0, %eax
  108. bts $0, %eax
  109. bts $31, %eax
  110. mov %eax, %cr0
  111. ret
  112. smp_stacktop: .long 0xa0000
  113. .align 16
  114. gdt32:
  115. .quad 0
  116. .quad 0x00cf9b000000ffff // flat 32-bit code segment
  117. .quad 0x00cf93000000ffff // flat 32-bit data segment
  118. gdt32_end:
  119. .code16
  120. sipi_entry:
  121. mov %cr0, %eax
  122. or $1, %eax
  123. mov %eax, %cr0
  124. lgdtl gdt32_descr - sipi_entry
  125. ljmpl $8, $ap_start32
  126. gdt32_descr:
  127. .word gdt32_end - gdt32 - 1
  128. .long gdt32
  129. sipi_end:
  130. .code32
  131. ap_start32:
  132. mov $0x10, %ax
  133. mov %ax, %ds
  134. mov %ax, %es
  135. mov %ax, %fs
  136. mov %ax, %gs
  137. mov %ax, %ss
  138. mov $-4096, %esp
  139. lock/xaddl %esp, smp_stacktop
  140. setup_percpu_area
  141. call prepare_64
  142. ljmpl $8, $ap_start64
  143. .code64
  144. ap_start64:
  145. call load_tss
  146. call enable_apic
  147. call enable_x2apic
  148. sti
  149. nop
  150. lock incw cpu_online_count
  151. 1: hlt
  152. jmp 1b
  153. start64:
  154. call load_tss
  155. call mask_pic_interrupts
  156. call enable_apic
  157. call smp_init
  158. call enable_x2apic
  159. mov mb_boot_info(%rip), %rbx
  160. mov %rbx, %rdi
  161. call setup_get_initrd
  162. call setup_environ
  163. mov mb_cmdline(%rbx), %eax
  164. mov %rax, __args(%rip)
  165. call __setup_args
  166. mov __argc(%rip), %edi
  167. lea __argv(%rip), %rsi
  168. lea __environ(%rip), %rdx
  169. call main
  170. mov %eax, %edi
  171. call exit
  172. idt_descr:
  173. .word 16 * 256 - 1
  174. .quad boot_idt
  175. load_tss:
  176. lidtq idt_descr
  177. mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
  178. mov (%rax), %eax
  179. shr $24, %eax
  180. mov %eax, %ebx
  181. shl $4, %ebx
  182. mov $((tss_end - tss) / max_cpus), %edx
  183. imul %edx
  184. add $tss, %rax
  185. mov %ax, tss_descr+2(%rbx)
  186. shr $16, %rax
  187. mov %al, tss_descr+4(%rbx)
  188. shr $8, %rax
  189. mov %al, tss_descr+7(%rbx)
  190. shr $8, %rax
  191. mov %eax, tss_descr+8(%rbx)
  192. lea tss_descr-gdt64(%rbx), %rax
  193. ltr %ax
  194. ret
  195. smp_init:
  196. cld
  197. lea sipi_entry, %rsi
  198. xor %rdi, %rdi
  199. mov $(sipi_end - sipi_entry), %rcx
  200. rep/movsb
  201. mov $APIC_DEFAULT_PHYS_BASE, %eax
  202. movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%rax)
  203. movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%rax)
  204. movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%rax)
  205. call fwcfg_get_nb_cpus
  206. 1: pause
  207. cmpw %ax, cpu_online_count
  208. jne 1b
  209. smp_init_done:
  210. ret
  211. cpu_online_count: .word 1