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