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