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 0x00cffb000000ffff // 64-bit code segment (user) 38 .quad 0x00cff3000000ffff // 64-bit data segment (user) 39 40 .quad 0 // 10 spare selectors 41 .quad 0 42 .quad 0 43 .quad 0 44 .quad 0 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 mov mb_cmdline(%ebx), %eax 98 mov %eax, __args 99 call __setup_args 100 mov $stacktop, %esp 101 setup_percpu_area 102 call prepare_32 103 jmpl $8, $start32 104 105prepare_32: 106 lgdtl gdt32_descr 107 108 mov %cr4, %eax 109 bts $4, %eax // pse 110 mov %eax, %cr4 111 112 mov $pt, %eax 113 mov %eax, %cr3 114 115 mov %cr0, %eax 116 bts $0, %eax 117 bts $31, %eax 118 mov %eax, %cr0 119 ret 120 121smp_stacktop: .long 0xa0000 122 123ap_start32: 124 mov $0x10, %ax 125 mov %ax, %ds 126 mov %ax, %es 127 mov %ax, %fs 128 mov %ax, %gs 129 mov %ax, %ss 130 mov $-4096, %esp 131 lock/xaddl %esp, smp_stacktop 132 setup_percpu_area 133 call prepare_32 134 call load_tss 135 call enable_apic 136 call enable_x2apic 137 sti 138 nop 139 lock incw cpu_online_count 140 1411: hlt 142 jmp 1b 143 144start32: 145 call load_tss 146 call mask_pic_interrupts 147 call enable_apic 148 call smp_init 149 call enable_x2apic 150 push $__argv 151 push __argc 152 call main 153 push %eax 154 call exit 155 156load_tss: 157 lidt idt_descr 158 mov $16, %eax 159 mov %ax, %ss 160 mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 161 mov (%eax), %eax 162 shr $24, %eax 163 mov %eax, %ebx 164 shl $3, %ebx 165 mov $((tss_end - tss) / max_cpus), %edx 166 imul %edx 167 add $tss, %eax 168 mov %ax, tss_descr+2(%ebx) 169 shr $16, %eax 170 mov %al, tss_descr+4(%ebx) 171 shr $8, %eax 172 mov %al, tss_descr+7(%ebx) 173 lea tss_descr-gdt32(%ebx), %eax 174 ltr %ax 175 ret 176 177smp_init: 178 cld 179 lea sipi_entry, %esi 180 xor %edi, %edi 181 mov $(sipi_end - sipi_entry), %ecx 182 rep/movsb 183 mov $APIC_DEFAULT_PHYS_BASE, %eax 184 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%eax) 185 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%eax) 186 movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%eax) 187 call fwcfg_get_nb_cpus 1881: pause 189 cmpw %ax, cpu_online_count 190 jne 1b 191smp_init_done: 192 ret 193 194cpu_online_count: .word 1 195 196.code16 197sipi_entry: 198 mov %cr0, %eax 199 or $1, %eax 200 mov %eax, %cr0 201 lgdtl gdt32_descr - sipi_entry 202 ljmpl $8, $ap_start32 203 204gdt32_descr: 205 .word gdt32_end - gdt32 - 1 206 .long gdt32 207 208sipi_end: 209