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