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