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 48 49gdt64_desc: 50 .word gdt64_end - gdt64 - 1 51 .quad gdt64 52 53gdt64: 54 .quad 0 55 .quad 0x00af9b000000ffff // 64-bit code segment 56 .quad 0x00cf93000000ffff // 64-bit data segment 57 .quad 0x00af1b000000ffff // 64-bit code segment, not present 58 .quad 0x00affb000000ffff // 64-bit code segment (user) 59 .quad 0x00cff3000000ffff // 64-bit data segment (user) 60 .quad 0x00cf9b000000ffff // 32-bit code segment 61 .quad 0x00cf92000000ffff // 32-bit data segment 62 .quad 0x008F9A000000FFFF // 16-bit code segment 63 .quad 0x008F92000000FFFF // 16-bit data segment 64 65 .quad 0 // 6 spare selectors 66 .quad 0 67 .quad 0 68 .quad 0 69 .quad 0 70 .quad 0 71 72tss_descr: 73 .rept max_cpus 74 .quad 0x000089000000ffff // 64-bit avail tss 75 .quad 0 // tss high addr 76 .endr 77gdt64_end: 78 79i = 0 80.globl tss 81tss: 82 .rept max_cpus 83 .long 0 84 .quad ring0stacktop - i * 4096 85 .quad 0, 0 86 .quad 0, 0, 0, 0, 0, 0, 0, 0 87 .long 0, 0, 0 88i = i + 1 89 .endr 90tss_end: 91 92mb_boot_info: .quad 0 93 94.section .init 95 96.code32 97 98mb_magic = 0x1BADB002 99mb_flags = 0x0 100 101 # multiboot header 102 .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) 103mb_cmdline = 16 104 105MSR_GS_BASE = 0xc0000101 106 107.macro setup_percpu_area 108 lea -4096(%esp), %eax 109 mov $0, %edx 110 mov $MSR_GS_BASE, %ecx 111 wrmsr 112.endm 113 114.globl start 115start: 116 mov %ebx, mb_boot_info 117 mov $stacktop, %esp 118 setup_percpu_area 119 call prepare_64 120 jmpl $8, $start64 121 122prepare_64: 123 lgdt gdt64_desc 124 125 mov %cr4, %eax 126 bts $5, %eax // pae 127 mov %eax, %cr4 128 129 mov $ptl4, %eax 130 mov %eax, %cr3 131 132efer = 0xc0000080 133 mov $efer, %ecx 134 rdmsr 135 bts $8, %eax 136 wrmsr 137 138 mov %cr0, %eax 139 bts $0, %eax 140 bts $31, %eax 141 mov %eax, %cr0 142 ret 143 144smp_stacktop: .long 0xa0000 145 146.align 16 147 148gdt32: 149 .quad 0 150 .quad 0x00cf9b000000ffff // flat 32-bit code segment 151 .quad 0x00cf93000000ffff // flat 32-bit data segment 152gdt32_end: 153 154.code16 155sipi_entry: 156 mov %cr0, %eax 157 or $1, %eax 158 mov %eax, %cr0 159 lgdtl gdt32_descr - sipi_entry 160 ljmpl $8, $ap_start32 161 162gdt32_descr: 163 .word gdt32_end - gdt32 - 1 164 .long gdt32 165 166sipi_end: 167 168.code32 169ap_start32: 170 mov $0x10, %ax 171 mov %ax, %ds 172 mov %ax, %es 173 mov %ax, %fs 174 mov %ax, %gs 175 mov %ax, %ss 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 183ap_start64: 184 call load_tss 185 call enable_apic 186 call enable_x2apic 187 sti 188 nop 189 lock incw cpu_online_count 190 1911: hlt 192 jmp 1b 193 194start64: 195 call load_tss 196 call mask_pic_interrupts 197 call enable_apic 198 call smp_init 199 call enable_x2apic 200 mov mb_boot_info(%rip), %rax 201 mov mb_cmdline(%rax), %rax 202 mov %rax, __args(%rip) 203 call __setup_args 204 mov __argc(%rip), %edi 205 lea __argv(%rip), %rsi 206 call main 207 mov %eax, %edi 208 call exit 209 210idt_descr: 211 .word 16 * 256 - 1 212 .quad boot_idt 213 214load_tss: 215 lidtq idt_descr 216 mov $0, %eax 217 mov %ax, %ss 218 mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 219 mov (%rax), %eax 220 shr $24, %eax 221 mov %eax, %ebx 222 shl $4, %ebx 223 mov $((tss_end - tss) / max_cpus), %edx 224 imul %edx 225 add $tss, %rax 226 mov %ax, tss_descr+2(%rbx) 227 shr $16, %rax 228 mov %al, tss_descr+4(%rbx) 229 shr $8, %rax 230 mov %al, tss_descr+7(%rbx) 231 shr $8, %rax 232 mov %eax, tss_descr+8(%rbx) 233 lea tss_descr-gdt64(%rbx), %rax 234 ltr %ax 235 ret 236 237smp_init: 238 cld 239 lea sipi_entry, %rsi 240 xor %rdi, %rdi 241 mov $(sipi_end - sipi_entry), %rcx 242 rep/movsb 243 mov $APIC_DEFAULT_PHYS_BASE, %eax 244 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%rax) 245 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%rax) 246 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%rax) 247 call fwcfg_get_nb_cpus 2481: pause 249 cmpw %ax, cpu_online_count 250 jne 1b 251smp_init_done: 252 ret 253 254cpu_online_count: .word 1 255