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