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