17d36db35SAvi Kivity 2dfe6cb66SJason Wang#include "apic-defs.h" 3dfe6cb66SJason Wang 418a34cceSNadav Amit.global online_cpus 518a34cceSNadav Amit 6dfe6cb66SJason Wangipi_vector = 0x20 7dfe6cb66SJason Wang 818a34cceSNadav Amitmax_cpus = MAX_TEST_CPUS 97d36db35SAvi Kivity 107d36db35SAvi Kivity.bss 117d36db35SAvi Kivity 12dfe6cb66SJason Wang . = . + 4096 * max_cpus 13dfe6cb66SJason Wang .align 16 14dfe6cb66SJason Wangstacktop: 15dfe6cb66SJason Wang 16dfe6cb66SJason Wang . = . + 4096 17dfe6cb66SJason Wang .align 16 18dfe6cb66SJason Wangring0stacktop: 19dfe6cb66SJason Wang 20dfe6cb66SJason Wang.data 21dfe6cb66SJason Wang 22dfe6cb66SJason Wang.align 4096 23dfe6cb66SJason Wangpt: 24dfe6cb66SJason Wangi = 0 25dfe6cb66SJason Wang .rept 1024 26dfe6cb66SJason Wang .long 0x1e7 | (i << 22) 27dfe6cb66SJason Wang i = i + 1 28dfe6cb66SJason Wang .endr 29dfe6cb66SJason Wang 30*5ed10141SPaolo Bonzini.globl gdt 31*5ed10141SPaolo Bonzinigdt: 32dfe6cb66SJason Wang .quad 0 33dfe6cb66SJason Wang .quad 0x00cf9b000000ffff // flat 32-bit code segment 34dfe6cb66SJason Wang .quad 0x00cf93000000ffff // flat 32-bit data segment 358f4755faSPaolo Bonzini .quad 0x00cf1b000000ffff // flat 32-bit code segment, not present 3610594e42SPaolo Bonzini .quad 0 // TSS for task gates 3710594e42SPaolo Bonzini .quad 0x008f9b000000FFFF // 16-bit code segment 3810594e42SPaolo Bonzini .quad 0x008f93000000FFFF // 16-bit data segment 3910594e42SPaolo Bonzini .quad 0x00cffb000000ffff // 32-bit code segment (user) 4010594e42SPaolo Bonzini .quad 0x00cff3000000ffff // 32-bit data segment (user) 4110594e42SPaolo Bonzini .quad 0 // unused 428f4755faSPaolo Bonzini 4310594e42SPaolo Bonzini .quad 0 // 6 spare selectors 448f4755faSPaolo Bonzini .quad 0 458f4755faSPaolo Bonzini .quad 0 468f4755faSPaolo Bonzini .quad 0 478f4755faSPaolo Bonzini .quad 0 488f4755faSPaolo Bonzini .quad 0 49dfe6cb66SJason Wang 50dfe6cb66SJason Wangtss_descr: 51dfe6cb66SJason Wang .rept max_cpus 52dfe6cb66SJason Wang .quad 0x000089000000ffff // 32-bit avail tss 53dfe6cb66SJason Wang .endr 549eef583dSPaolo Bonzinipercpu_descr: 559eef583dSPaolo Bonzini .rept max_cpus 569eef583dSPaolo Bonzini .quad 0x00cf93000000ffff // 32-bit data segment for perCPU area 579eef583dSPaolo Bonzini .endr 58*5ed10141SPaolo Bonzinigdt_end: 59dfe6cb66SJason Wang 60dfe6cb66SJason Wangi = 0 618f4755faSPaolo Bonzini.globl tss 62dfe6cb66SJason Wangtss: 63dfe6cb66SJason Wang .rept max_cpus 64dfe6cb66SJason Wang .long 0 65dfe6cb66SJason Wang .long ring0stacktop - i * 4096 66dfe6cb66SJason Wang .long 16 67dfe6cb66SJason Wang .quad 0, 0 68dfe6cb66SJason Wang .quad 0, 0, 0, 0, 0, 0, 0, 0 69dfe6cb66SJason Wang .long 0, 0, 0 70dfe6cb66SJason Wang i = i + 1 71dfe6cb66SJason Wang .endr 72dfe6cb66SJason Wangtss_end: 73dfe6cb66SJason Wang 747d36db35SAvi Kivity.section .init 757d36db35SAvi Kivity 76dfe6cb66SJason Wang.code32 77dfe6cb66SJason Wang 787d36db35SAvi Kivitymb_magic = 0x1BADB002 797d36db35SAvi Kivitymb_flags = 0x0 807d36db35SAvi Kivity 817d36db35SAvi Kivity # multiboot header 827d36db35SAvi Kivity .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) 83ea7d43d0SAvi Kivitymb_cmdline = 16 847d36db35SAvi Kivity 85dfe6cb66SJason Wang.macro setup_percpu_area 86dfe6cb66SJason Wang lea -4096(%esp), %eax 879eef583dSPaolo Bonzini 889eef583dSPaolo Bonzini /* fill GS_BASE in the GDT, do not clobber %ebx (multiboot info) */ 899eef583dSPaolo Bonzini mov (APIC_DEFAULT_PHYS_BASE + APIC_ID), %ecx 909eef583dSPaolo Bonzini shr $24, %ecx 919eef583dSPaolo Bonzini mov %ax, percpu_descr+2(,%ecx,8) 929eef583dSPaolo Bonzini 939eef583dSPaolo Bonzini shr $16, %eax 949eef583dSPaolo Bonzini mov %al, percpu_descr+4(,%ecx,8) 959eef583dSPaolo Bonzini mov %ah, percpu_descr+7(,%ecx,8) 969eef583dSPaolo Bonzini 97*5ed10141SPaolo Bonzini lea percpu_descr-gdt(,%ecx,8), %eax 989eef583dSPaolo Bonzini mov %ax, %gs 999eef583dSPaolo Bonzini 100dfe6cb66SJason Wang.endm 101dfe6cb66SJason Wang 102d68a795aSNadav Amit.macro setup_segments 103d68a795aSNadav Amit mov $0x10, %ax 104d68a795aSNadav Amit mov %ax, %ds 105d68a795aSNadav Amit mov %ax, %es 106d68a795aSNadav Amit mov %ax, %fs 107d68a795aSNadav Amit mov %ax, %gs 108d68a795aSNadav Amit mov %ax, %ss 109d68a795aSNadav Amit.endm 110d68a795aSNadav Amit 1117d36db35SAvi Kivity.globl start 1127d36db35SAvi Kivitystart: 113*5ed10141SPaolo Bonzini lgdtl gdt_descr 114ded41057SPaolo Bonzini setup_segments 115cae10b5bSClaudio Imbrenda mov $stacktop, %esp 116ded41057SPaolo Bonzini setup_percpu_area 117ded41057SPaolo Bonzini 11893dd2aa3SAndrew Jones push %ebx 119716cea8aSPaolo Bonzini call setup_multiboot 1204108903cSPaolo Bonzini addl $4, %esp 121716cea8aSPaolo Bonzini call setup_libcflat 122ea7d43d0SAvi Kivity mov mb_cmdline(%ebx), %eax 123ea7d43d0SAvi Kivity mov %eax, __args 124ea7d43d0SAvi Kivity call __setup_args 125dfe6cb66SJason Wang call prepare_32 126dfe6cb66SJason Wang jmpl $8, $start32 127dfe6cb66SJason Wang 128dfe6cb66SJason Wangprepare_32: 129b4f3421fSClaudio Imbrenda mov $(1 << 4), %eax // pse 130dfe6cb66SJason Wang mov %eax, %cr4 131dfe6cb66SJason Wang 132dfe6cb66SJason Wang mov $pt, %eax 133dfe6cb66SJason Wang mov %eax, %cr3 134dfe6cb66SJason Wang 135dfe6cb66SJason Wang mov %cr0, %eax 136dfe6cb66SJason Wang bts $0, %eax 137dfe6cb66SJason Wang bts $31, %eax 138dfe6cb66SJason Wang mov %eax, %cr0 139dfe6cb66SJason Wang ret 140dfe6cb66SJason Wang 141d589407fSNadav Amitsmp_stacktop: .long stacktop - 4096 142dfe6cb66SJason Wang 14318a34cceSNadav Amitsave_id: 14418a34cceSNadav Amit movl $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 14518a34cceSNadav Amit movl (%eax), %eax 14618a34cceSNadav Amit shrl $24, %eax 14718a34cceSNadav Amit lock btsl %eax, online_cpus 14818a34cceSNadav Amit retl 14918a34cceSNadav Amit 150dfe6cb66SJason Wangap_start32: 151d68a795aSNadav Amit setup_segments 152dfe6cb66SJason Wang mov $-4096, %esp 1532d331a4dSRoman Bolshakov lock xaddl %esp, smp_stacktop 154dfe6cb66SJason Wang setup_percpu_area 155dfe6cb66SJason Wang call prepare_32 156d6e8f863SNadav Amit call reset_apic 15718a34cceSNadav Amit call save_id 158dfe6cb66SJason Wang call load_tss 159dfe6cb66SJason Wang call enable_apic 160dfe6cb66SJason Wang call enable_x2apic 161dfe6cb66SJason Wang sti 162dfe6cb66SJason Wang nop 163dfe6cb66SJason Wang lock incw cpu_online_count 164dfe6cb66SJason Wang 165dfe6cb66SJason Wang1: hlt 166dfe6cb66SJason Wang jmp 1b 167dfe6cb66SJason Wang 168dfe6cb66SJason Wangstart32: 169d6e8f863SNadav Amit call reset_apic 17018a34cceSNadav Amit call save_id 171dfe6cb66SJason Wang call load_tss 172dfe6cb66SJason Wang call mask_pic_interrupts 173dfe6cb66SJason Wang call enable_apic 17431e68df7SPaolo Bonzini call ap_init 175dfe6cb66SJason Wang call enable_x2apic 17631e68df7SPaolo Bonzini call smp_init 1773c7d322eSAndrew Jones push $__environ 178dfe6cb66SJason Wang push $__argv 179dfe6cb66SJason Wang push __argc 1807d36db35SAvi Kivity call main 1817d36db35SAvi Kivity push %eax 1827d36db35SAvi Kivity call exit 1837d36db35SAvi Kivity 184dfe6cb66SJason Wangload_tss: 185dfe6cb66SJason Wang lidt idt_descr 186dfe6cb66SJason Wang mov $16, %eax 187dfe6cb66SJason Wang mov %ax, %ss 1889eef583dSPaolo Bonzini mov (APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 189dfe6cb66SJason Wang shr $24, %eax 190dfe6cb66SJason Wang mov %eax, %ebx 191dfe6cb66SJason Wang mov $((tss_end - tss) / max_cpus), %edx 192dfe6cb66SJason Wang imul %edx 193dfe6cb66SJason Wang add $tss, %eax 1949eef583dSPaolo Bonzini mov %ax, tss_descr+2(,%ebx,8) 195dfe6cb66SJason Wang shr $16, %eax 1969eef583dSPaolo Bonzini mov %al, tss_descr+4(,%ebx,8) 1979eef583dSPaolo Bonzini mov %ah, tss_descr+7(,%ebx,8) 198*5ed10141SPaolo Bonzini lea tss_descr-gdt(,%ebx,8), %eax 199dfe6cb66SJason Wang ltr %ax 200dfe6cb66SJason Wang ret 2017d36db35SAvi Kivity 20231e68df7SPaolo Bonziniap_init: 203dfe6cb66SJason Wang cld 204dfe6cb66SJason Wang lea sipi_entry, %esi 205dfe6cb66SJason Wang xor %edi, %edi 206dfe6cb66SJason Wang mov $(sipi_end - sipi_entry), %ecx 2072d331a4dSRoman Bolshakov rep movsb 208dfe6cb66SJason Wang mov $APIC_DEFAULT_PHYS_BASE, %eax 209dfe6cb66SJason Wang movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%eax) 210dfe6cb66SJason Wang movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%eax) 211dfe6cb66SJason Wang call fwcfg_get_nb_cpus 212dfe6cb66SJason Wang1: pause 213dfe6cb66SJason Wang cmpw %ax, cpu_online_count 214dfe6cb66SJason Wang jne 1b 215dfe6cb66SJason Wang ret 216dfe6cb66SJason Wang 21718a34cceSNadav Amitonline_cpus: 21818048d0fSSean Christopherson .fill (max_cpus + 7) / 8, 1, 0 21918a34cceSNadav Amit 220dfe6cb66SJason Wangcpu_online_count: .word 1 221dfe6cb66SJason Wang 222dfe6cb66SJason Wang.code16 223dfe6cb66SJason Wangsipi_entry: 224dfe6cb66SJason Wang mov %cr0, %eax 225dfe6cb66SJason Wang or $1, %eax 226dfe6cb66SJason Wang mov %eax, %cr0 227*5ed10141SPaolo Bonzini lgdtl gdt_descr - sipi_entry 228dfe6cb66SJason Wang ljmpl $8, $ap_start32 229dfe6cb66SJason Wang 230*5ed10141SPaolo Bonzinigdt_descr: 231*5ed10141SPaolo Bonzini .word gdt_end - gdt - 1 232*5ed10141SPaolo Bonzini .long gdt 233dfe6cb66SJason Wang 234dfe6cb66SJason Wangsipi_end: 235