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 61percpu_descr: 62 .rept max_cpus 63 .quad 0x00cf93000000ffff // 32-bit data segment for perCPU area 64 .endr 65gdt32_end: 66 67i = 0 68.globl tss 69tss: 70 .rept max_cpus 71 .long 0 72 .long ring0stacktop - i * 4096 73 .long 16 74 .quad 0, 0 75 .quad 0, 0, 0, 0, 0, 0, 0, 0 76 .long 0, 0, 0 77 i = i + 1 78 .endr 79tss_end: 80 81idt_descr: 82 .word end_boot_idt - boot_idt - 1 83 .long boot_idt 84 85.section .init 86 87.code32 88 89mb_magic = 0x1BADB002 90mb_flags = 0x0 91 92 # multiboot header 93 .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) 94mb_cmdline = 16 95 96.macro setup_percpu_area 97 lea -4096(%esp), %eax 98 99 /* fill GS_BASE in the GDT, do not clobber %ebx (multiboot info) */ 100 mov (APIC_DEFAULT_PHYS_BASE + APIC_ID), %ecx 101 shr $24, %ecx 102 mov %ax, percpu_descr+2(,%ecx,8) 103 104 shr $16, %eax 105 mov %al, percpu_descr+4(,%ecx,8) 106 mov %ah, percpu_descr+7(,%ecx,8) 107 108 lea percpu_descr-gdt32(,%ecx,8), %eax 109 mov %ax, %gs 110 111.endm 112 113.macro setup_segments 114 mov $0x10, %ax 115 mov %ax, %ds 116 mov %ax, %es 117 mov %ax, %fs 118 mov %ax, %gs 119 mov %ax, %ss 120.endm 121 122.globl start 123start: 124 lgdtl gdt32_descr 125 setup_segments 126 mov $stacktop, %esp 127 setup_percpu_area 128 129 push %ebx 130 call setup_multiboot 131 addl $4, %esp 132 call setup_libcflat 133 mov mb_cmdline(%ebx), %eax 134 mov %eax, __args 135 call __setup_args 136 call prepare_32 137 jmpl $8, $start32 138 139prepare_32: 140 mov $(1 << 4), %eax // pse 141 mov %eax, %cr4 142 143 mov $pt, %eax 144 mov %eax, %cr3 145 146 mov %cr0, %eax 147 bts $0, %eax 148 bts $31, %eax 149 mov %eax, %cr0 150 ret 151 152smp_stacktop: .long stacktop - 4096 153 154save_id: 155 movl $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 156 movl (%eax), %eax 157 shrl $24, %eax 158 lock btsl %eax, online_cpus 159 retl 160 161ap_start32: 162 setup_segments 163 mov $-4096, %esp 164 lock xaddl %esp, smp_stacktop 165 setup_percpu_area 166 call prepare_32 167 call reset_apic 168 call save_id 169 call load_tss 170 call enable_apic 171 call enable_x2apic 172 sti 173 nop 174 lock incw cpu_online_count 175 1761: hlt 177 jmp 1b 178 179start32: 180 call reset_apic 181 call save_id 182 call load_tss 183 call mask_pic_interrupts 184 call enable_apic 185 call ap_init 186 call enable_x2apic 187 call smp_init 188 push $__environ 189 push $__argv 190 push __argc 191 call main 192 push %eax 193 call exit 194 195load_tss: 196 lidt idt_descr 197 mov $16, %eax 198 mov %ax, %ss 199 mov (APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 200 shr $24, %eax 201 mov %eax, %ebx 202 mov $((tss_end - tss) / max_cpus), %edx 203 imul %edx 204 add $tss, %eax 205 mov %ax, tss_descr+2(,%ebx,8) 206 shr $16, %eax 207 mov %al, tss_descr+4(,%ebx,8) 208 mov %ah, tss_descr+7(,%ebx,8) 209 lea tss_descr-gdt32(,%ebx,8), %eax 210 ltr %ax 211 ret 212 213ap_init: 214 cld 215 lea sipi_entry, %esi 216 xor %edi, %edi 217 mov $(sipi_end - sipi_entry), %ecx 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(%eax) 221 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%eax) 222 call fwcfg_get_nb_cpus 2231: pause 224 cmpw %ax, cpu_online_count 225 jne 1b 226 ret 227 228online_cpus: 229 .fill (max_cpus + 7) / 8, 1, 0 230 231cpu_online_count: .word 1 232 233.code16 234sipi_entry: 235 mov %cr0, %eax 236 or $1, %eax 237 mov %eax, %cr0 238 lgdtl gdt32_descr - sipi_entry 239 ljmpl $8, $ap_start32 240 241gdt32_descr: 242 .word gdt32_end - gdt32 - 1 243 .long gdt32 244 245sipi_end: 246