1 2#include "apic-defs.h" 3 4.globl boot_idt 5boot_idt = 0 6 7.globl idt_descr 8.globl tss_descr 9.globl gdt64_desc 10.globl online_cpus 11 12ipi_vector = 0x20 13 14max_cpus = MAX_TEST_CPUS 15 16.bss 17 18 . = . + 4096 * max_cpus 19 .align 16 20stacktop: 21 22 . = . + 4096 * max_cpus 23 .align 16 24ring0stacktop: 25 26.data 27 28.align 4096 29.globl ptl2 30ptl2: 31i = 0 32 .rept 512 * 4 33 .quad 0x1e7 | (i << 21) 34 i = i + 1 35 .endr 36 37.align 4096 38ptl3: 39 .quad ptl2 + 7 + 0 * 4096 40 .quad ptl2 + 7 + 1 * 4096 41 .quad ptl2 + 7 + 2 * 4096 42 .quad ptl2 + 7 + 3 * 4096 43 44.align 4096 45ptl4: 46 .quad ptl3 + 7 47 48.align 4096 49ptl5: 50 .quad ptl4 + 7 51 52.align 4096 53 54gdt64_desc: 55 .word gdt64_end - gdt64 - 1 56 .quad gdt64 57 58gdt64: 59 .quad 0 60 .quad 0x00af9b000000ffff // 64-bit code segment 61 .quad 0x00cf93000000ffff // 32/64-bit data segment 62 .quad 0x00af1b000000ffff // 64-bit code segment, not present 63 .quad 0x00cf9b000000ffff // 32-bit code segment 64 .quad 0x008f9b000000FFFF // 16-bit code segment 65 .quad 0x008f93000000FFFF // 16-bit data segment 66 .quad 0x00cffb000000ffff // 32-bit code segment (user) 67 .quad 0x00cff3000000ffff // 32/64-bit data segment (user) 68 .quad 0x00affb000000ffff // 64-bit code segment (user) 69 70 .quad 0 // 6 spare selectors 71 .quad 0 72 .quad 0 73 .quad 0 74 .quad 0 75 .quad 0 76 77tss_descr: 78 .rept max_cpus 79 .quad 0x000089000000ffff // 64-bit avail tss 80 .quad 0 // tss high addr 81 .endr 82gdt64_end: 83 84i = 0 85.globl tss 86tss: 87 .rept max_cpus 88 .long 0 89 .quad ring0stacktop - i * 4096 90 .quad 0, 0 91 .quad 0, 0, 0, 0, 0, 0, 0, 0 92 .long 0, 0, 0 93i = i + 1 94 .endr 95tss_end: 96 97mb_boot_info: .quad 0 98 99pt_root: .quad ptl4 100 101.section .init 102 103.code32 104 105mb_magic = 0x1BADB002 106mb_flags = 0x0 107 108 # multiboot header 109 .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) 110mb_cmdline = 16 111 112MSR_GS_BASE = 0xc0000101 113 114.macro setup_percpu_area 115 lea -4096(%esp), %eax 116 mov $0, %edx 117 mov $MSR_GS_BASE, %ecx 118 wrmsr 119.endm 120 121.macro setup_segments 122 mov $MSR_GS_BASE, %ecx 123 rdmsr 124 125 mov $0x10, %bx 126 mov %bx, %ds 127 mov %bx, %es 128 mov %bx, %fs 129 mov %bx, %gs 130 mov %bx, %ss 131 132 /* restore MSR_GS_BASE */ 133 wrmsr 134.endm 135 136.globl start 137start: 138 mov %ebx, mb_boot_info 139 mov $stacktop, %esp 140 setup_percpu_area 141 call prepare_64 142 jmpl $8, $start64 143 144switch_to_5level: 145 /* Disable CR4.PCIDE */ 146 mov %cr4, %eax 147 btr $17, %eax 148 mov %eax, %cr4 149 150 mov %cr0, %eax 151 btr $31, %eax 152 mov %eax, %cr0 153 154 mov $ptl5, %eax 155 mov %eax, pt_root 156 157 /* Enable CR4.LA57 */ 158 mov %cr4, %eax 159 bts $12, %eax 160 mov %eax, %cr4 161 162 mov $0x10, %ax 163 mov %ax, %ss 164 165 call enter_long_mode 166 jmpl $8, $lvl5 167 168prepare_64: 169 lgdt gdt64_desc 170 setup_segments 171 172enter_long_mode: 173 mov %cr4, %eax 174 bts $5, %eax // pae 175 mov %eax, %cr4 176 177 mov pt_root, %eax 178 mov %eax, %cr3 179 180efer = 0xc0000080 181 mov $efer, %ecx 182 rdmsr 183 bts $8, %eax 184 wrmsr 185 186 mov %cr0, %eax 187 bts $0, %eax 188 bts $31, %eax 189 mov %eax, %cr0 190 ret 191 192smp_stacktop: .long stacktop - 4096 193 194.align 16 195 196gdt32: 197 .quad 0 198 .quad 0x00cf9b000000ffff // flat 32-bit code segment 199 .quad 0x00cf93000000ffff // flat 32-bit data segment 200gdt32_end: 201 202.code16 203sipi_entry: 204 mov %cr0, %eax 205 or $1, %eax 206 mov %eax, %cr0 207 lgdtl gdt32_descr - sipi_entry 208 ljmpl $8, $ap_start32 209 210gdt32_descr: 211 .word gdt32_end - gdt32 - 1 212 .long gdt32 213 214sipi_end: 215 216.code32 217ap_start32: 218 setup_segments 219 mov $-4096, %esp 220 lock/xaddl %esp, smp_stacktop 221 setup_percpu_area 222 call prepare_64 223 ljmpl $8, $ap_start64 224 225.code64 226save_id: 227 movl $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 228 movl (%rax), %eax 229 shrl $24, %eax 230 lock btsl %eax, online_cpus 231 retq 232 233ap_start64: 234 call reset_apic 235 call load_tss 236 call enable_apic 237 call save_id 238 call enable_x2apic 239 sti 240 nop 241 lock incw cpu_online_count 242 2431: hlt 244 jmp 1b 245 246start64: 247 call reset_apic 248 call load_tss 249 call mask_pic_interrupts 250 call enable_apic 251 call save_id 252 mov mb_boot_info(%rip), %rbx 253 mov %rbx, %rdi 254 call setup_multiboot 255 call setup_libcflat 256 mov mb_cmdline(%rbx), %eax 257 mov %rax, __args(%rip) 258 call __setup_args 259 260 call ap_init 261 call enable_x2apic 262 call smp_init 263 264 mov __argc(%rip), %edi 265 lea __argv(%rip), %rsi 266 lea __environ(%rip), %rdx 267 call main 268 mov %eax, %edi 269 call exit 270 271.globl setup_5level_page_table 272setup_5level_page_table: 273 /* Check if 5-level paging has already enabled */ 274 mov %cr4, %rax 275 test $0x1000, %eax 276 jnz lvl5 277 278 pushq $32 279 pushq $switch_to_5level 280 lretq 281lvl5: 282 retq 283 284idt_descr: 285 .word 16 * 256 - 1 286 .quad boot_idt 287 288online_cpus: 289 .fill (max_cpus + 7) / 8, 1, 0 290 291load_tss: 292 lidtq idt_descr 293 mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 294 mov (%rax), %eax 295 shr $24, %eax 296 mov %eax, %ebx 297 shl $4, %ebx 298 mov $((tss_end - tss) / max_cpus), %edx 299 imul %edx 300 add $tss, %rax 301 mov %ax, tss_descr+2(%rbx) 302 shr $16, %rax 303 mov %al, tss_descr+4(%rbx) 304 shr $8, %rax 305 mov %al, tss_descr+7(%rbx) 306 shr $8, %rax 307 mov %eax, tss_descr+8(%rbx) 308 lea tss_descr-gdt64(%rbx), %rax 309 ltr %ax 310 ret 311 312ap_init: 313 cld 314 lea sipi_entry, %rsi 315 xor %rdi, %rdi 316 mov $(sipi_end - sipi_entry), %rcx 317 rep/movsb 318 mov $APIC_DEFAULT_PHYS_BASE, %eax 319 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%rax) 320 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%rax) 321 call fwcfg_get_nb_cpus 3221: pause 323 cmpw %ax, cpu_online_count 324 jne 1b 325 ret 326 327cpu_online_count: .word 1 328