1 2#include "apic-defs.h" 3 4.globl boot_idt 5.global online_cpus 6 7ipi_vector = 0x20 8 9max_cpus = MAX_TEST_CPUS 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 24pt: 25i = 0 26 .rept 1024 27 .long 0x1e7 | (i << 22) 28 i = i + 1 29 .endr 30 31boot_idt: 32 .rept 256 33 .quad 0 34 .endr 35end_boot_idt: 36 37.globl gdt32 38gdt32: 39 .quad 0 40 .quad 0x00cf9b000000ffff // flat 32-bit code segment 41 .quad 0x00cf93000000ffff // flat 32-bit data segment 42 .quad 0x00cf1b000000ffff // flat 32-bit code segment, not present 43 .quad 0 // TSS for task gates 44 .quad 0x008f9b000000FFFF // 16-bit code segment 45 .quad 0x008f93000000FFFF // 16-bit data segment 46 .quad 0x00cffb000000ffff // 32-bit code segment (user) 47 .quad 0x00cff3000000ffff // 32-bit data segment (user) 48 .quad 0 // unused 49 50 .quad 0 // 6 spare selectors 51 .quad 0 52 .quad 0 53 .quad 0 54 .quad 0 55 .quad 0 56 57tss_descr: 58 .rept max_cpus 59 .quad 0x000089000000ffff // 32-bit avail tss 60 .endr 61gdt32_end: 62 63i = 0 64.globl tss 65tss: 66 .rept max_cpus 67 .long 0 68 .long ring0stacktop - i * 4096 69 .long 16 70 .quad 0, 0 71 .quad 0, 0, 0, 0, 0, 0, 0, 0 72 .long 0, 0, 0 73 i = i + 1 74 .endr 75tss_end: 76 77idt_descr: 78 .word end_boot_idt - boot_idt - 1 79 .long boot_idt 80 81.section .init 82 83.code32 84 85mb_magic = 0x1BADB002 86mb_flags = 0x0 87 88 # multiboot header 89 .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) 90mb_cmdline = 16 91 92MSR_GS_BASE = 0xc0000101 93 94.macro setup_percpu_area 95 lea -4096(%esp), %eax 96 mov $0, %edx 97 mov $MSR_GS_BASE, %ecx 98 wrmsr 99.endm 100 101.macro setup_segments 102 mov $0x10, %ax 103 mov %ax, %ds 104 mov %ax, %es 105 mov %ax, %fs 106 mov %ax, %gs 107 mov %ax, %ss 108.endm 109 110.globl start 111start: 112 lgdtl gdt32_descr 113 setup_segments 114 mov $stacktop, %esp 115 setup_percpu_area 116 117 push %ebx 118 call setup_multiboot 119 addl $4, %esp 120 call setup_libcflat 121 mov mb_cmdline(%ebx), %eax 122 mov %eax, __args 123 call __setup_args 124 call prepare_32 125 jmpl $8, $start32 126 127prepare_32: 128 mov $(1 << 4), %eax // pse 129 mov %eax, %cr4 130 131 mov $pt, %eax 132 mov %eax, %cr3 133 134 mov %cr0, %eax 135 bts $0, %eax 136 bts $31, %eax 137 mov %eax, %cr0 138 ret 139 140smp_stacktop: .long stacktop - 4096 141 142save_id: 143 movl $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 144 movl (%eax), %eax 145 shrl $24, %eax 146 lock btsl %eax, online_cpus 147 retl 148 149ap_start32: 150 setup_segments 151 mov $-4096, %esp 152 lock xaddl %esp, smp_stacktop 153 setup_percpu_area 154 call prepare_32 155 call reset_apic 156 call save_id 157 call load_tss 158 call enable_apic 159 call enable_x2apic 160 sti 161 nop 162 lock incw cpu_online_count 163 1641: hlt 165 jmp 1b 166 167start32: 168 call reset_apic 169 call save_id 170 call load_tss 171 call mask_pic_interrupts 172 call enable_apic 173 call ap_init 174 call enable_x2apic 175 call smp_init 176 push $__environ 177 push $__argv 178 push __argc 179 call main 180 push %eax 181 call exit 182 183load_tss: 184 lidt idt_descr 185 mov $16, %eax 186 mov %ax, %ss 187 mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 188 mov (%eax), %eax 189 shr $24, %eax 190 mov %eax, %ebx 191 shl $3, %ebx 192 mov $((tss_end - tss) / max_cpus), %edx 193 imul %edx 194 add $tss, %eax 195 mov %ax, tss_descr+2(%ebx) 196 shr $16, %eax 197 mov %al, tss_descr+4(%ebx) 198 shr $8, %eax 199 mov %al, tss_descr+7(%ebx) 200 lea tss_descr-gdt32(%ebx), %eax 201 ltr %ax 202 ret 203 204ap_init: 205 cld 206 lea sipi_entry, %esi 207 xor %edi, %edi 208 mov $(sipi_end - sipi_entry), %ecx 209 rep movsb 210 mov $APIC_DEFAULT_PHYS_BASE, %eax 211 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%eax) 212 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%eax) 213 call fwcfg_get_nb_cpus 2141: pause 215 cmpw %ax, cpu_online_count 216 jne 1b 217 ret 218 219online_cpus: 220 .fill (max_cpus + 7) / 8, 1, 0 221 222cpu_online_count: .word 1 223 224.code16 225sipi_entry: 226 mov %cr0, %eax 227 or $1, %eax 228 mov %eax, %cr0 229 lgdtl gdt32_descr - sipi_entry 230 ljmpl $8, $ap_start32 231 232gdt32_descr: 233 .word gdt32_end - gdt32 - 1 234 .long gdt32 235 236sipi_end: 237