cstart.S 3.6 KB

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