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