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 call enter_long_mode 163 jmpl $8, $lvl5 164 165prepare_64: 166 lgdt gdt64_desc 167 setup_segments 168 169enter_long_mode: 170 mov %cr4, %eax 171 bts $5, %eax // pae 172 mov %eax, %cr4 173 174 mov pt_root, %eax 175 mov %eax, %cr3 176 177efer = 0xc0000080 178 mov $efer, %ecx 179 rdmsr 180 bts $8, %eax 181 wrmsr 182 183 mov %cr0, %eax 184 bts $0, %eax 185 bts $31, %eax 186 mov %eax, %cr0 187 ret 188 189smp_stacktop: .long stacktop - 4096 190 191.align 16 192 193gdt32: 194 .quad 0 195 .quad 0x00cf9b000000ffff // flat 32-bit code segment 196 .quad 0x00cf93000000ffff // flat 32-bit data segment 197gdt32_end: 198 199.code16 200sipi_entry: 201 mov %cr0, %eax 202 or $1, %eax 203 mov %eax, %cr0 204 lgdtl gdt32_descr - sipi_entry 205 ljmpl $8, $ap_start32 206 207gdt32_descr: 208 .word gdt32_end - gdt32 - 1 209 .long gdt32 210 211sipi_end: 212 213.code32 214ap_start32: 215 setup_segments 216 mov $-4096, %esp 217 lock/xaddl %esp, smp_stacktop 218 setup_percpu_area 219 call prepare_64 220 ljmpl $8, $ap_start64 221 222.code64 223save_id: 224 movl $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 225 movl (%rax), %eax 226 shrl $24, %eax 227 lock btsl %eax, online_cpus 228 retq 229 230ap_start64: 231 call reset_apic 232 call load_tss 233 call enable_apic 234 call save_id 235 call enable_x2apic 236 sti 237 nop 238 lock incw cpu_online_count 239 2401: hlt 241 jmp 1b 242 243start64: 244 call reset_apic 245 call load_tss 246 call mask_pic_interrupts 247 call enable_apic 248 call save_id 249 mov mb_boot_info(%rip), %rbx 250 mov %rbx, %rdi 251 call setup_multiboot 252 call setup_libcflat 253 mov mb_cmdline(%rbx), %eax 254 mov %rax, __args(%rip) 255 call __setup_args 256 257 /* Read the configuration before running smp_init */ 258 call read_cfg_override 259 call smp_init 260 call enable_x2apic 261 262 mov __argc(%rip), %edi 263 lea __argv(%rip), %rsi 264 lea __environ(%rip), %rdx 265 call main 266 mov %eax, %edi 267 call exit 268 269.globl setup_5level_page_table 270setup_5level_page_table: 271 /* Check if 5-level paging has already enabled */ 272 mov %cr4, %rax 273 test $0x1000, %eax 274 jnz lvl5 275 276 pushq $32 277 pushq $switch_to_5level 278 lretq 279lvl5: 280 retq 281 282idt_descr: 283 .word 16 * 256 - 1 284 .quad boot_idt 285 286online_cpus: 287 .quad 0 288 289load_tss: 290 lidtq idt_descr 291 mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 292 mov (%rax), %eax 293 shr $24, %eax 294 mov %eax, %ebx 295 shl $4, %ebx 296 mov $((tss_end - tss) / max_cpus), %edx 297 imul %edx 298 add $tss, %rax 299 mov %ax, tss_descr+2(%rbx) 300 shr $16, %rax 301 mov %al, tss_descr+4(%rbx) 302 shr $8, %rax 303 mov %al, tss_descr+7(%rbx) 304 shr $8, %rax 305 mov %eax, tss_descr+8(%rbx) 306 lea tss_descr-gdt64(%rbx), %rax 307 ltr %ax 308 ret 309 310smp_init: 311 cld 312 lea sipi_entry, %rsi 313 xor %rdi, %rdi 314 mov $(sipi_end - sipi_entry), %rcx 315 rep/movsb 316 mov $APIC_DEFAULT_PHYS_BASE, %eax 317 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%rax) 318 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%rax) 319 call fwcfg_get_nb_cpus 3201: pause 321 cmpw %ax, cpu_online_count 322 jne 1b 323smp_init_done: 324 ret 325 326cpu_online_count: .word 1 327