17d36db35SAvi Kivity 2*dfe6cb66SJason Wang#include "apic-defs.h" 3*dfe6cb66SJason Wang 4*dfe6cb66SJason Wang.globl boot_idt 5*dfe6cb66SJason Wangboot_idt = 0 6*dfe6cb66SJason Wang 7*dfe6cb66SJason Wangipi_vector = 0x20 8*dfe6cb66SJason Wang 9*dfe6cb66SJason Wangmax_cpus = 4 107d36db35SAvi Kivity 117d36db35SAvi Kivity.bss 127d36db35SAvi Kivity 13*dfe6cb66SJason Wang . = . + 4096 * max_cpus 14*dfe6cb66SJason Wang .align 16 15*dfe6cb66SJason Wangstacktop: 16*dfe6cb66SJason Wang 17*dfe6cb66SJason Wang . = . + 4096 18*dfe6cb66SJason Wang .align 16 19*dfe6cb66SJason Wangring0stacktop: 20*dfe6cb66SJason Wang 21*dfe6cb66SJason Wang.data 22*dfe6cb66SJason Wang 23*dfe6cb66SJason Wang.align 4096 24*dfe6cb66SJason Wangpt: 25*dfe6cb66SJason Wangi = 0 26*dfe6cb66SJason Wang .rept 1024 27*dfe6cb66SJason Wang .long 0x1e7 | (i << 22) 28*dfe6cb66SJason Wang i = i + 1 29*dfe6cb66SJason Wang .endr 30*dfe6cb66SJason Wang 31*dfe6cb66SJason Wanggdt32: 32*dfe6cb66SJason Wang .quad 0 33*dfe6cb66SJason Wang .quad 0x00cf9b000000ffff // flat 32-bit code segment 34*dfe6cb66SJason Wang .quad 0x00cf93000000ffff // flat 32-bit data segment 35*dfe6cb66SJason Wang 36*dfe6cb66SJason Wangtss_descr: 37*dfe6cb66SJason Wang .rept max_cpus 38*dfe6cb66SJason Wang .quad 0x000089000000ffff // 32-bit avail tss 39*dfe6cb66SJason Wang .endr 40*dfe6cb66SJason Wanggdt32_end: 41*dfe6cb66SJason Wang 42*dfe6cb66SJason Wangi = 0 43*dfe6cb66SJason Wangtss: 44*dfe6cb66SJason Wang .rept max_cpus 45*dfe6cb66SJason Wang .long 0 46*dfe6cb66SJason Wang .long ring0stacktop - i * 4096 47*dfe6cb66SJason Wang .long 16 48*dfe6cb66SJason Wang .quad 0, 0 49*dfe6cb66SJason Wang .quad 0, 0, 0, 0, 0, 0, 0, 0 50*dfe6cb66SJason Wang .long 0, 0, 0 51*dfe6cb66SJason Wang i = i + 1 52*dfe6cb66SJason Wang .endr 53*dfe6cb66SJason Wangtss_end: 54*dfe6cb66SJason Wang 55*dfe6cb66SJason Wangidt_descr: 56*dfe6cb66SJason Wang .word 16 * 256 - 1 57*dfe6cb66SJason Wang .long boot_idt 58*dfe6cb66SJason Wang 597d36db35SAvi Kivity.section .init 607d36db35SAvi Kivity 61*dfe6cb66SJason Wang.code32 62*dfe6cb66SJason Wang 637d36db35SAvi Kivitymb_magic = 0x1BADB002 647d36db35SAvi Kivitymb_flags = 0x0 657d36db35SAvi Kivity 667d36db35SAvi Kivity # multiboot header 677d36db35SAvi Kivity .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) 68ea7d43d0SAvi Kivitymb_cmdline = 16 697d36db35SAvi Kivity 70*dfe6cb66SJason WangMSR_GS_BASE = 0xc0000101 71*dfe6cb66SJason Wang 72*dfe6cb66SJason Wang.macro setup_percpu_area 73*dfe6cb66SJason Wang lea -4096(%esp), %eax 74*dfe6cb66SJason Wang mov $0, %edx 75*dfe6cb66SJason Wang mov $MSR_GS_BASE, %ecx 76*dfe6cb66SJason Wang wrmsr 77*dfe6cb66SJason Wang.endm 78*dfe6cb66SJason Wang 797d36db35SAvi Kivity.globl start 807d36db35SAvi Kivitystart: 81ea7d43d0SAvi Kivity mov mb_cmdline(%ebx), %eax 82ea7d43d0SAvi Kivity mov %eax, __args 83ea7d43d0SAvi Kivity call __setup_args 84*dfe6cb66SJason Wang mov $stacktop, %esp 85*dfe6cb66SJason Wang setup_percpu_area 86*dfe6cb66SJason Wang call prepare_32 87*dfe6cb66SJason Wang jmpl $8, $start32 88*dfe6cb66SJason Wang 89*dfe6cb66SJason Wangprepare_32: 90*dfe6cb66SJason Wang lgdtl gdt32_descr 91*dfe6cb66SJason Wang 92*dfe6cb66SJason Wang mov %cr4, %eax 93*dfe6cb66SJason Wang bts $4, %eax // pse 94*dfe6cb66SJason Wang mov %eax, %cr4 95*dfe6cb66SJason Wang 96*dfe6cb66SJason Wang mov $pt, %eax 97*dfe6cb66SJason Wang mov %eax, %cr3 98*dfe6cb66SJason Wang 99*dfe6cb66SJason Wang mov %cr0, %eax 100*dfe6cb66SJason Wang bts $0, %eax 101*dfe6cb66SJason Wang bts $31, %eax 102*dfe6cb66SJason Wang mov %eax, %cr0 103*dfe6cb66SJason Wang ret 104*dfe6cb66SJason Wang 105*dfe6cb66SJason Wangsmp_stacktop: .long 0xa0000 106*dfe6cb66SJason Wang 107*dfe6cb66SJason Wangap_start32: 108*dfe6cb66SJason Wang mov $0x10, %ax 109*dfe6cb66SJason Wang mov %ax, %ds 110*dfe6cb66SJason Wang mov %ax, %es 111*dfe6cb66SJason Wang mov %ax, %fs 112*dfe6cb66SJason Wang mov %ax, %gs 113*dfe6cb66SJason Wang mov %ax, %ss 114*dfe6cb66SJason Wang mov $-4096, %esp 115*dfe6cb66SJason Wang lock/xaddl %esp, smp_stacktop 116*dfe6cb66SJason Wang setup_percpu_area 117*dfe6cb66SJason Wang call prepare_32 118*dfe6cb66SJason Wang call load_tss 119*dfe6cb66SJason Wang call enable_apic 120*dfe6cb66SJason Wang call enable_x2apic 121*dfe6cb66SJason Wang sti 122*dfe6cb66SJason Wang nop 123*dfe6cb66SJason Wang lock incw cpu_online_count 124*dfe6cb66SJason Wang 125*dfe6cb66SJason Wang1: hlt 126*dfe6cb66SJason Wang jmp 1b 127*dfe6cb66SJason Wang 128*dfe6cb66SJason Wangstart32: 129*dfe6cb66SJason Wang call load_tss 130*dfe6cb66SJason Wang call mask_pic_interrupts 131*dfe6cb66SJason Wang call enable_apic 132*dfe6cb66SJason Wang call smp_init 133*dfe6cb66SJason Wang call enable_x2apic 134*dfe6cb66SJason Wang push $__argv 135*dfe6cb66SJason Wang push __argc 1367d36db35SAvi Kivity call main 1377d36db35SAvi Kivity push %eax 1387d36db35SAvi Kivity call exit 1397d36db35SAvi Kivity 140*dfe6cb66SJason Wangload_tss: 141*dfe6cb66SJason Wang lidt idt_descr 142*dfe6cb66SJason Wang mov $16, %eax 143*dfe6cb66SJason Wang mov %ax, %ss 144*dfe6cb66SJason Wang mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 145*dfe6cb66SJason Wang mov (%eax), %eax 146*dfe6cb66SJason Wang shr $24, %eax 147*dfe6cb66SJason Wang mov %eax, %ebx 148*dfe6cb66SJason Wang shl $3, %ebx 149*dfe6cb66SJason Wang mov $((tss_end - tss) / max_cpus), %edx 150*dfe6cb66SJason Wang imul %edx 151*dfe6cb66SJason Wang add $tss, %eax 152*dfe6cb66SJason Wang mov %ax, tss_descr+2(%ebx) 153*dfe6cb66SJason Wang shr $16, %eax 154*dfe6cb66SJason Wang mov %al, tss_descr+4(%ebx) 155*dfe6cb66SJason Wang shr $8, %eax 156*dfe6cb66SJason Wang mov %al, tss_descr+7(%ebx) 157*dfe6cb66SJason Wang lea tss_descr-gdt32(%ebx), %eax 158*dfe6cb66SJason Wang ltr %ax 159*dfe6cb66SJason Wang ret 1607d36db35SAvi Kivity 161*dfe6cb66SJason Wangsmp_init: 162*dfe6cb66SJason Wang cld 163*dfe6cb66SJason Wang lea sipi_entry, %esi 164*dfe6cb66SJason Wang xor %edi, %edi 165*dfe6cb66SJason Wang mov $(sipi_end - sipi_entry), %ecx 166*dfe6cb66SJason Wang rep/movsb 167*dfe6cb66SJason Wang mov $APIC_DEFAULT_PHYS_BASE, %eax 168*dfe6cb66SJason Wang movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%eax) 169*dfe6cb66SJason Wang movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%eax) 170*dfe6cb66SJason Wang movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%eax) 171*dfe6cb66SJason Wang call fwcfg_get_nb_cpus 172*dfe6cb66SJason Wang1: pause 173*dfe6cb66SJason Wang cmpw %ax, cpu_online_count 174*dfe6cb66SJason Wang jne 1b 175*dfe6cb66SJason Wangsmp_init_done: 176*dfe6cb66SJason Wang ret 177*dfe6cb66SJason Wang 178*dfe6cb66SJason Wangcpu_online_count: .word 1 179*dfe6cb66SJason Wang 180*dfe6cb66SJason Wang.code16 181*dfe6cb66SJason Wangsipi_entry: 182*dfe6cb66SJason Wang mov %cr0, %eax 183*dfe6cb66SJason Wang or $1, %eax 184*dfe6cb66SJason Wang mov %eax, %cr0 185*dfe6cb66SJason Wang lgdtl gdt32_descr - sipi_entry 186*dfe6cb66SJason Wang ljmpl $8, $ap_start32 187*dfe6cb66SJason Wang 188*dfe6cb66SJason Wanggdt32_descr: 189*dfe6cb66SJason Wang .word gdt32_end - gdt32 - 1 190*dfe6cb66SJason Wang .long gdt32 191*dfe6cb66SJason Wang 192*dfe6cb66SJason Wangsipi_end: 193