17d36db35SAvi Kivity 2dfe6cb66SJason Wang#include "apic-defs.h" 3dfe6cb66SJason Wang 4dfe6cb66SJason Wang.globl boot_idt 518a34cceSNadav Amit.global online_cpus 618a34cceSNadav Amit 7dfe6cb66SJason Wangboot_idt = 0 8dfe6cb66SJason Wang 9dfe6cb66SJason Wangipi_vector = 0x20 10dfe6cb66SJason Wang 1118a34cceSNadav Amitmax_cpus = MAX_TEST_CPUS 127d36db35SAvi Kivity 137d36db35SAvi Kivity.bss 147d36db35SAvi Kivity 15dfe6cb66SJason Wang . = . + 4096 * max_cpus 16dfe6cb66SJason Wang .align 16 17dfe6cb66SJason Wangstacktop: 18dfe6cb66SJason Wang 19dfe6cb66SJason Wang . = . + 4096 20dfe6cb66SJason Wang .align 16 21dfe6cb66SJason Wangring0stacktop: 22dfe6cb66SJason Wang 23dfe6cb66SJason Wang.data 24dfe6cb66SJason Wang 25dfe6cb66SJason Wang.align 4096 26dfe6cb66SJason Wangpt: 27dfe6cb66SJason Wangi = 0 28dfe6cb66SJason Wang .rept 1024 29dfe6cb66SJason Wang .long 0x1e7 | (i << 22) 30dfe6cb66SJason Wang i = i + 1 31dfe6cb66SJason Wang .endr 32dfe6cb66SJason Wang 338f4755faSPaolo Bonzini.globl gdt32 34dfe6cb66SJason Wanggdt32: 35dfe6cb66SJason Wang .quad 0 36dfe6cb66SJason Wang .quad 0x00cf9b000000ffff // flat 32-bit code segment 37dfe6cb66SJason Wang .quad 0x00cf93000000ffff // flat 32-bit data segment 388f4755faSPaolo Bonzini .quad 0x00cf1b000000ffff // flat 32-bit code segment, not present 3910594e42SPaolo Bonzini .quad 0 // TSS for task gates 4010594e42SPaolo Bonzini .quad 0x008f9b000000FFFF // 16-bit code segment 4110594e42SPaolo Bonzini .quad 0x008f93000000FFFF // 16-bit data segment 4210594e42SPaolo Bonzini .quad 0x00cffb000000ffff // 32-bit code segment (user) 4310594e42SPaolo Bonzini .quad 0x00cff3000000ffff // 32-bit data segment (user) 4410594e42SPaolo Bonzini .quad 0 // unused 458f4755faSPaolo Bonzini 4610594e42SPaolo Bonzini .quad 0 // 6 spare selectors 478f4755faSPaolo Bonzini .quad 0 488f4755faSPaolo Bonzini .quad 0 498f4755faSPaolo Bonzini .quad 0 508f4755faSPaolo Bonzini .quad 0 518f4755faSPaolo Bonzini .quad 0 52dfe6cb66SJason Wang 53dfe6cb66SJason Wangtss_descr: 54dfe6cb66SJason Wang .rept max_cpus 55dfe6cb66SJason Wang .quad 0x000089000000ffff // 32-bit avail tss 56dfe6cb66SJason Wang .endr 57dfe6cb66SJason Wanggdt32_end: 58dfe6cb66SJason Wang 59dfe6cb66SJason Wangi = 0 608f4755faSPaolo Bonzini.globl tss 61dfe6cb66SJason Wangtss: 62dfe6cb66SJason Wang .rept max_cpus 63dfe6cb66SJason Wang .long 0 64dfe6cb66SJason Wang .long ring0stacktop - i * 4096 65dfe6cb66SJason Wang .long 16 66dfe6cb66SJason Wang .quad 0, 0 67dfe6cb66SJason Wang .quad 0, 0, 0, 0, 0, 0, 0, 0 68dfe6cb66SJason Wang .long 0, 0, 0 69dfe6cb66SJason Wang i = i + 1 70dfe6cb66SJason Wang .endr 71dfe6cb66SJason Wangtss_end: 72dfe6cb66SJason Wang 73dfe6cb66SJason Wangidt_descr: 74dfe6cb66SJason Wang .word 16 * 256 - 1 75dfe6cb66SJason Wang .long boot_idt 76dfe6cb66SJason Wang 777d36db35SAvi Kivity.section .init 787d36db35SAvi Kivity 79dfe6cb66SJason Wang.code32 80dfe6cb66SJason Wang 817d36db35SAvi Kivitymb_magic = 0x1BADB002 827d36db35SAvi Kivitymb_flags = 0x0 837d36db35SAvi Kivity 847d36db35SAvi Kivity # multiboot header 857d36db35SAvi Kivity .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) 86ea7d43d0SAvi Kivitymb_cmdline = 16 877d36db35SAvi Kivity 88dfe6cb66SJason WangMSR_GS_BASE = 0xc0000101 89dfe6cb66SJason Wang 90dfe6cb66SJason Wang.macro setup_percpu_area 91dfe6cb66SJason Wang lea -4096(%esp), %eax 92dfe6cb66SJason Wang mov $0, %edx 93dfe6cb66SJason Wang mov $MSR_GS_BASE, %ecx 94dfe6cb66SJason Wang wrmsr 95dfe6cb66SJason Wang.endm 96dfe6cb66SJason Wang 977d36db35SAvi Kivity.globl start 987d36db35SAvi Kivitystart: 99*cae10b5bSClaudio Imbrenda mov $stacktop, %esp 10093dd2aa3SAndrew Jones push %ebx 101716cea8aSPaolo Bonzini call setup_multiboot 102716cea8aSPaolo Bonzini call setup_libcflat 103ea7d43d0SAvi Kivity mov mb_cmdline(%ebx), %eax 104ea7d43d0SAvi Kivity mov %eax, __args 105ea7d43d0SAvi Kivity call __setup_args 106dfe6cb66SJason Wang setup_percpu_area 107dfe6cb66SJason Wang call prepare_32 108dfe6cb66SJason Wang jmpl $8, $start32 109dfe6cb66SJason Wang 110dfe6cb66SJason Wangprepare_32: 111dfe6cb66SJason Wang lgdtl gdt32_descr 112dfe6cb66SJason Wang 113dfe6cb66SJason Wang mov %cr4, %eax 114dfe6cb66SJason Wang bts $4, %eax // pse 115dfe6cb66SJason Wang mov %eax, %cr4 116dfe6cb66SJason Wang 117dfe6cb66SJason Wang mov $pt, %eax 118dfe6cb66SJason Wang mov %eax, %cr3 119dfe6cb66SJason Wang 120dfe6cb66SJason Wang mov %cr0, %eax 121dfe6cb66SJason Wang bts $0, %eax 122dfe6cb66SJason Wang bts $31, %eax 123dfe6cb66SJason Wang mov %eax, %cr0 124dfe6cb66SJason Wang ret 125dfe6cb66SJason Wang 126dfe6cb66SJason Wangsmp_stacktop: .long 0xa0000 127dfe6cb66SJason Wang 12818a34cceSNadav Amitsave_id: 12918a34cceSNadav Amit movl $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 13018a34cceSNadav Amit movl (%eax), %eax 13118a34cceSNadav Amit shrl $24, %eax 13218a34cceSNadav Amit lock btsl %eax, online_cpus 13318a34cceSNadav Amit retl 13418a34cceSNadav Amit 135dfe6cb66SJason Wangap_start32: 136dfe6cb66SJason Wang mov $0x10, %ax 137dfe6cb66SJason Wang mov %ax, %ds 138dfe6cb66SJason Wang mov %ax, %es 139dfe6cb66SJason Wang mov %ax, %fs 140dfe6cb66SJason Wang mov %ax, %gs 141dfe6cb66SJason Wang mov %ax, %ss 142dfe6cb66SJason Wang mov $-4096, %esp 143dfe6cb66SJason Wang lock/xaddl %esp, smp_stacktop 144dfe6cb66SJason Wang setup_percpu_area 145dfe6cb66SJason Wang call prepare_32 146d6e8f863SNadav Amit call reset_apic 14718a34cceSNadav Amit call save_id 148dfe6cb66SJason Wang call load_tss 149dfe6cb66SJason Wang call enable_apic 150dfe6cb66SJason Wang call enable_x2apic 151dfe6cb66SJason Wang sti 152dfe6cb66SJason Wang nop 153dfe6cb66SJason Wang lock incw cpu_online_count 154dfe6cb66SJason Wang 155dfe6cb66SJason Wang1: hlt 156dfe6cb66SJason Wang jmp 1b 157dfe6cb66SJason Wang 158dfe6cb66SJason Wangstart32: 159d6e8f863SNadav Amit call reset_apic 16018a34cceSNadav Amit call save_id 161dfe6cb66SJason Wang call load_tss 162dfe6cb66SJason Wang call mask_pic_interrupts 163dfe6cb66SJason Wang call enable_apic 16431e68df7SPaolo Bonzini call ap_init 165dfe6cb66SJason Wang call enable_x2apic 16631e68df7SPaolo Bonzini call smp_init 1673c7d322eSAndrew Jones push $__environ 168dfe6cb66SJason Wang push $__argv 169dfe6cb66SJason Wang push __argc 1707d36db35SAvi Kivity call main 1717d36db35SAvi Kivity push %eax 1727d36db35SAvi Kivity call exit 1737d36db35SAvi Kivity 174dfe6cb66SJason Wangload_tss: 175dfe6cb66SJason Wang lidt idt_descr 176dfe6cb66SJason Wang mov $16, %eax 177dfe6cb66SJason Wang mov %ax, %ss 178dfe6cb66SJason Wang mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 179dfe6cb66SJason Wang mov (%eax), %eax 180dfe6cb66SJason Wang shr $24, %eax 181dfe6cb66SJason Wang mov %eax, %ebx 182dfe6cb66SJason Wang shl $3, %ebx 183dfe6cb66SJason Wang mov $((tss_end - tss) / max_cpus), %edx 184dfe6cb66SJason Wang imul %edx 185dfe6cb66SJason Wang add $tss, %eax 186dfe6cb66SJason Wang mov %ax, tss_descr+2(%ebx) 187dfe6cb66SJason Wang shr $16, %eax 188dfe6cb66SJason Wang mov %al, tss_descr+4(%ebx) 189dfe6cb66SJason Wang shr $8, %eax 190dfe6cb66SJason Wang mov %al, tss_descr+7(%ebx) 191dfe6cb66SJason Wang lea tss_descr-gdt32(%ebx), %eax 192dfe6cb66SJason Wang ltr %ax 193dfe6cb66SJason Wang ret 1947d36db35SAvi Kivity 19531e68df7SPaolo Bonziniap_init: 196dfe6cb66SJason Wang cld 197dfe6cb66SJason Wang lea sipi_entry, %esi 198dfe6cb66SJason Wang xor %edi, %edi 199dfe6cb66SJason Wang mov $(sipi_end - sipi_entry), %ecx 200dfe6cb66SJason Wang rep/movsb 201dfe6cb66SJason Wang mov $APIC_DEFAULT_PHYS_BASE, %eax 202dfe6cb66SJason Wang movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%eax) 203dfe6cb66SJason Wang movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%eax) 204dfe6cb66SJason Wang call fwcfg_get_nb_cpus 205dfe6cb66SJason Wang1: pause 206dfe6cb66SJason Wang cmpw %ax, cpu_online_count 207dfe6cb66SJason Wang jne 1b 208dfe6cb66SJason Wang ret 209dfe6cb66SJason Wang 21018a34cceSNadav Amitonline_cpus: 21118048d0fSSean Christopherson .fill (max_cpus + 7) / 8, 1, 0 21218a34cceSNadav Amit 213dfe6cb66SJason Wangcpu_online_count: .word 1 214dfe6cb66SJason Wang 215dfe6cb66SJason Wang.code16 216dfe6cb66SJason Wangsipi_entry: 217dfe6cb66SJason Wang mov %cr0, %eax 218dfe6cb66SJason Wang or $1, %eax 219dfe6cb66SJason Wang mov %eax, %cr0 220dfe6cb66SJason Wang lgdtl gdt32_descr - sipi_entry 221dfe6cb66SJason Wang ljmpl $8, $ap_start32 222dfe6cb66SJason Wang 223dfe6cb66SJason Wanggdt32_descr: 224dfe6cb66SJason Wang .word gdt32_end - gdt32 - 1 225dfe6cb66SJason Wang .long gdt32 226dfe6cb66SJason Wang 227dfe6cb66SJason Wangsipi_end: 228