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), %rbx 201 mov %rbx, %rdi 202 call setup_get_initrd 203 call setup_environ 204 mov mb_cmdline(%rbx), %eax 205 mov %rax, __args(%rip) 206 call __setup_args 207 mov __argc(%rip), %edi 208 lea __argv(%rip), %rsi 209 lea __environ(%rip), %rdx 210 call main 211 mov %eax, %edi 212 call exit 213 214idt_descr: 215 .word 16 * 256 - 1 216 .quad boot_idt 217 218load_tss: 219 lidtq idt_descr 220 mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 221 mov (%rax), %eax 222 shr $24, %eax 223 mov %eax, %ebx 224 shl $4, %ebx 225 mov $((tss_end - tss) / max_cpus), %edx 226 imul %edx 227 add $tss, %rax 228 mov %ax, tss_descr+2(%rbx) 229 shr $16, %rax 230 mov %al, tss_descr+4(%rbx) 231 shr $8, %rax 232 mov %al, tss_descr+7(%rbx) 233 shr $8, %rax 234 mov %eax, tss_descr+8(%rbx) 235 lea tss_descr-gdt64(%rbx), %rax 236 ltr %ax 237 ret 238 239smp_init: 240 cld 241 lea sipi_entry, %rsi 242 xor %rdi, %rdi 243 mov $(sipi_end - sipi_entry), %rcx 244 rep/movsb 245 mov $APIC_DEFAULT_PHYS_BASE, %eax 246 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%rax) 247 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%rax) 248 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%rax) 249 call fwcfg_get_nb_cpus 2501: pause 251 cmpw %ax, cpu_online_count 252 jne 1b 253smp_init_done: 254 ret 255 256cpu_online_count: .word 1 257