1 2#include "apic-defs.h" 3 4.globl boot_idt 5boot_idt = 0 6 7ipi_vector = 0x20 8 9max_cpus = 4 10 11.bss 12 13 . = . + 4096 * max_cpus 14 .align 16 15stacktop: 16 17 . = . + 4096 18 .align 16 19ring0stacktop: 20 21.data 22 23.align 4096 24ptl2: 25i = 0 26 .rept 512 * 4 27 .quad 0x1e7 | (i << 21) 28 i = i + 1 29 .endr 30 31.align 4096 32ptl3: 33 .quad ptl2 + 7 + 0 * 4096 34 .quad ptl2 + 7 + 1 * 4096 35 .quad ptl2 + 7 + 2 * 4096 36 .quad ptl2 + 7 + 3 * 4096 37 38.align 4096 39ptl4: 40 .quad ptl3 + 7 41 42.align 4096 43 44gdt64_desc: 45 .word gdt64_end - gdt64 - 1 46 .quad gdt64 47 48gdt64: 49 .quad 0 50 .quad 0x00af9b000000ffff // 64-bit code segment 51 .quad 0x00cf93000000ffff // 64-bit data segment 52 .quad 0x00affb000000ffff // 64-bit code segment (user) 53 .quad 0x00cff3000000ffff // 64-bit data segment (user) 54 .quad 0x00cf9b000000ffff // 32-bit code segment 55 .quad 0x00cf92000000ffff // 32-bit code segment 56 .quad 0x008F9A000000FFFF // 16-bit code segment 57 .quad 0x008F92000000FFFF // 16-bit data segment 58 59tss_descr: 60 .rept max_cpus 61 .quad 0x000089000000ffff // 64-bit avail tss 62 .quad 0 // tss high addr 63 .endr 64gdt64_end: 65 66i = 0 67tss: 68 .rept max_cpus 69 .long 0 70 .quad ring0stacktop - i * 4096 71 .quad 0, 0, 0 72 .quad 0, 0, 0, 0, 0, 0, 0, 0 73 .long 0, 0, 0 74i = i + 1 75 .endr 76tss_end: 77 78.section .init 79 80.code32 81 82mb_magic = 0x1BADB002 83mb_flags = 0x0 84 85 # multiboot header 86 .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) 87 88MSR_GS_BASE = 0xc0000101 89 90.macro setup_percpu_area 91 lea -4096(%esp), %eax 92 mov $0, %edx 93 mov $MSR_GS_BASE, %ecx 94 wrmsr 95.endm 96 97.globl start 98start: 99 mov $stacktop, %esp 100 setup_percpu_area 101 call prepare_64 102 jmpl $8, $start64 103 104prepare_64: 105 lgdt gdt64_desc 106 107 mov %cr4, %eax 108 bts $5, %eax // pae 109 mov %eax, %cr4 110 111 mov $ptl4, %eax 112 mov %eax, %cr3 113 114efer = 0xc0000080 115 mov $efer, %ecx 116 rdmsr 117 bts $8, %eax 118 wrmsr 119 120 mov %cr0, %eax 121 bts $0, %eax 122 bts $31, %eax 123 mov %eax, %cr0 124 ret 125 126smp_stacktop: .long 0xa0000 127 128.align 16 129 130gdt32: 131 .quad 0 132 .quad 0x00cf9b000000ffff // flat 32-bit code segment 133 .quad 0x00cf93000000ffff // flat 32-bit data segment 134gdt32_end: 135 136.code16 137sipi_entry: 138 mov %cr0, %eax 139 or $1, %eax 140 mov %eax, %cr0 141 lgdtl gdt32_descr - sipi_entry 142 ljmpl $8, $ap_start32 143 144gdt32_descr: 145 .word gdt32_end - gdt32 - 1 146 .long gdt32 147 148sipi_end: 149 150.code32 151ap_start32: 152 mov $0x10, %ax 153 mov %ax, %ds 154 mov %ax, %es 155 mov %ax, %fs 156 mov %ax, %gs 157 mov %ax, %ss 158 mov $-4096, %esp 159 lock/xaddl %esp, smp_stacktop 160 setup_percpu_area 161 call prepare_64 162 ljmpl $8, $ap_start64 163 164.code64 165ap_start64: 166 call load_tss 167 call enable_apic 168 call enable_x2apic 169 sti 170 nop 171 lock incw cpu_online_count 172 1731: hlt 174 jmp 1b 175 176start64: 177 call load_tss 178 call mask_pic_interrupts 179 call enable_apic 180 call smp_init 181 call enable_x2apic 182 call main 183 mov %eax, %edi 184 call exit 185 186idt_descr: 187 .word 16 * 256 - 1 188 .quad boot_idt 189 190load_tss: 191 lidtq idt_descr 192 mov $0, %eax 193 mov %ax, %ss 194 mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 195 mov (%rax), %eax 196 shr $24, %eax 197 mov %eax, %ebx 198 shl $4, %ebx 199 mov $((tss_end - tss) / max_cpus), %edx 200 imul %edx 201 add $tss, %rax 202 mov %ax, tss_descr+2(%rbx) 203 shr $16, %rax 204 mov %al, tss_descr+4(%rbx) 205 shr $8, %rax 206 mov %al, tss_descr+7(%rbx) 207 shr $8, %rax 208 mov %eax, tss_descr+8(%rbx) 209 lea tss_descr-gdt64(%rbx), %rax 210 ltr %ax 211 ret 212 213smp_init: 214 cld 215 lea sipi_entry, %rsi 216 xor %rdi, %rdi 217 mov $(sipi_end - sipi_entry), %rcx 218 rep/movsb 219 mov $APIC_DEFAULT_PHYS_BASE, %eax 220 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%rax) 221 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%rax) 222 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%rax) 223 call fwcfg_get_nb_cpus 2241: pause 225 cmpw %ax, cpu_online_count 226 jne 1b 227smp_init_done: 228 ret 229 230cpu_online_count: .word 1 231