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