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