17d36db35SAvi Kivity 2dfe6cb66SJason Wang#include "apic-defs.h" 3dfe6cb66SJason Wang 4dfe6cb66SJason Wang.globl boot_idt 518a34cceSNadav Amit.global online_cpus 618a34cceSNadav Amit 7dfe6cb66SJason Wangipi_vector = 0x20 8dfe6cb66SJason Wang 918a34cceSNadav Amitmax_cpus = MAX_TEST_CPUS 107d36db35SAvi Kivity 117d36db35SAvi Kivity.bss 127d36db35SAvi Kivity 13dfe6cb66SJason Wang . = . + 4096 * max_cpus 14dfe6cb66SJason Wang .align 16 15dfe6cb66SJason Wangstacktop: 16dfe6cb66SJason Wang 17dfe6cb66SJason Wang . = . + 4096 18dfe6cb66SJason Wang .align 16 19dfe6cb66SJason Wangring0stacktop: 20dfe6cb66SJason Wang 21dfe6cb66SJason Wang.data 22dfe6cb66SJason Wang 23dfe6cb66SJason Wang.align 4096 24dfe6cb66SJason Wangpt: 25dfe6cb66SJason Wangi = 0 26dfe6cb66SJason Wang .rept 1024 27dfe6cb66SJason Wang .long 0x1e7 | (i << 22) 28dfe6cb66SJason Wang i = i + 1 29dfe6cb66SJason Wang .endr 30dfe6cb66SJason Wang 31f8203b59SPaolo Bonziniboot_idt: 32f8203b59SPaolo Bonzini .rept 256 33f8203b59SPaolo Bonzini .quad 0 34f8203b59SPaolo Bonzini .endr 35f8203b59SPaolo Bonziniend_boot_idt: 36f8203b59SPaolo Bonzini 378f4755faSPaolo Bonzini.globl gdt32 38dfe6cb66SJason Wanggdt32: 39dfe6cb66SJason Wang .quad 0 40dfe6cb66SJason Wang .quad 0x00cf9b000000ffff // flat 32-bit code segment 41dfe6cb66SJason Wang .quad 0x00cf93000000ffff // flat 32-bit data segment 428f4755faSPaolo Bonzini .quad 0x00cf1b000000ffff // flat 32-bit code segment, not present 4310594e42SPaolo Bonzini .quad 0 // TSS for task gates 4410594e42SPaolo Bonzini .quad 0x008f9b000000FFFF // 16-bit code segment 4510594e42SPaolo Bonzini .quad 0x008f93000000FFFF // 16-bit data segment 4610594e42SPaolo Bonzini .quad 0x00cffb000000ffff // 32-bit code segment (user) 4710594e42SPaolo Bonzini .quad 0x00cff3000000ffff // 32-bit data segment (user) 4810594e42SPaolo Bonzini .quad 0 // unused 498f4755faSPaolo Bonzini 5010594e42SPaolo Bonzini .quad 0 // 6 spare selectors 518f4755faSPaolo Bonzini .quad 0 528f4755faSPaolo Bonzini .quad 0 538f4755faSPaolo Bonzini .quad 0 548f4755faSPaolo Bonzini .quad 0 558f4755faSPaolo Bonzini .quad 0 56dfe6cb66SJason Wang 57dfe6cb66SJason Wangtss_descr: 58dfe6cb66SJason Wang .rept max_cpus 59dfe6cb66SJason Wang .quad 0x000089000000ffff // 32-bit avail tss 60dfe6cb66SJason Wang .endr 61dfe6cb66SJason Wanggdt32_end: 62dfe6cb66SJason Wang 63dfe6cb66SJason Wangi = 0 648f4755faSPaolo Bonzini.globl tss 65dfe6cb66SJason Wangtss: 66dfe6cb66SJason Wang .rept max_cpus 67dfe6cb66SJason Wang .long 0 68dfe6cb66SJason Wang .long ring0stacktop - i * 4096 69dfe6cb66SJason Wang .long 16 70dfe6cb66SJason Wang .quad 0, 0 71dfe6cb66SJason Wang .quad 0, 0, 0, 0, 0, 0, 0, 0 72dfe6cb66SJason Wang .long 0, 0, 0 73dfe6cb66SJason Wang i = i + 1 74dfe6cb66SJason Wang .endr 75dfe6cb66SJason Wangtss_end: 76dfe6cb66SJason Wang 77dfe6cb66SJason Wangidt_descr: 78f8203b59SPaolo Bonzini .word end_boot_idt - boot_idt - 1 79dfe6cb66SJason Wang .long boot_idt 80dfe6cb66SJason Wang 817d36db35SAvi Kivity.section .init 827d36db35SAvi Kivity 83dfe6cb66SJason Wang.code32 84dfe6cb66SJason Wang 857d36db35SAvi Kivitymb_magic = 0x1BADB002 867d36db35SAvi Kivitymb_flags = 0x0 877d36db35SAvi Kivity 887d36db35SAvi Kivity # multiboot header 897d36db35SAvi Kivity .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) 90ea7d43d0SAvi Kivitymb_cmdline = 16 917d36db35SAvi Kivity 92dfe6cb66SJason WangMSR_GS_BASE = 0xc0000101 93dfe6cb66SJason Wang 94dfe6cb66SJason Wang.macro setup_percpu_area 95dfe6cb66SJason Wang lea -4096(%esp), %eax 96dfe6cb66SJason Wang mov $0, %edx 97dfe6cb66SJason Wang mov $MSR_GS_BASE, %ecx 98dfe6cb66SJason Wang wrmsr 99dfe6cb66SJason Wang.endm 100dfe6cb66SJason Wang 101d68a795aSNadav Amit.macro setup_segments 102d68a795aSNadav Amit mov $0x10, %ax 103d68a795aSNadav Amit mov %ax, %ds 104d68a795aSNadav Amit mov %ax, %es 105d68a795aSNadav Amit mov %ax, %fs 106d68a795aSNadav Amit mov %ax, %gs 107d68a795aSNadav Amit mov %ax, %ss 108d68a795aSNadav Amit.endm 109d68a795aSNadav Amit 1107d36db35SAvi Kivity.globl start 1117d36db35SAvi Kivitystart: 112cae10b5bSClaudio Imbrenda mov $stacktop, %esp 11393dd2aa3SAndrew Jones push %ebx 114716cea8aSPaolo Bonzini call setup_multiboot 115*4108903cSPaolo Bonzini addl $4, %esp 116716cea8aSPaolo Bonzini call setup_libcflat 117ea7d43d0SAvi Kivity mov mb_cmdline(%ebx), %eax 118ea7d43d0SAvi Kivity mov %eax, __args 119ea7d43d0SAvi Kivity call __setup_args 120dfe6cb66SJason Wang setup_percpu_area 121dfe6cb66SJason Wang call prepare_32 122dfe6cb66SJason Wang jmpl $8, $start32 123dfe6cb66SJason Wang 124dfe6cb66SJason Wangprepare_32: 125dfe6cb66SJason Wang lgdtl gdt32_descr 126d68a795aSNadav Amit setup_segments 127dfe6cb66SJason Wang 128dfe6cb66SJason Wang mov %cr4, %eax 129dfe6cb66SJason Wang bts $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 141dfe6cb66SJason Wangsmp_stacktop: .long 0xa0000 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 153dfe6cb66SJason Wang 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 188dfe6cb66SJason Wang mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax 189dfe6cb66SJason Wang mov (%eax), %eax 190dfe6cb66SJason Wang shr $24, %eax 191dfe6cb66SJason Wang mov %eax, %ebx 192dfe6cb66SJason Wang shl $3, %ebx 193dfe6cb66SJason Wang mov $((tss_end - tss) / max_cpus), %edx 194dfe6cb66SJason Wang imul %edx 195dfe6cb66SJason Wang add $tss, %eax 196dfe6cb66SJason Wang mov %ax, tss_descr+2(%ebx) 197dfe6cb66SJason Wang shr $16, %eax 198dfe6cb66SJason Wang mov %al, tss_descr+4(%ebx) 199dfe6cb66SJason Wang shr $8, %eax 200dfe6cb66SJason Wang mov %al, tss_descr+7(%ebx) 201dfe6cb66SJason Wang lea tss_descr-gdt32(%ebx), %eax 202dfe6cb66SJason Wang ltr %ax 203dfe6cb66SJason Wang ret 2047d36db35SAvi Kivity 20531e68df7SPaolo Bonziniap_init: 206dfe6cb66SJason Wang cld 207dfe6cb66SJason Wang lea sipi_entry, %esi 208dfe6cb66SJason Wang xor %edi, %edi 209dfe6cb66SJason Wang mov $(sipi_end - sipi_entry), %ecx 210dfe6cb66SJason Wang rep/movsb 211dfe6cb66SJason Wang mov $APIC_DEFAULT_PHYS_BASE, %eax 212dfe6cb66SJason Wang movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%eax) 213dfe6cb66SJason Wang movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%eax) 214dfe6cb66SJason Wang call fwcfg_get_nb_cpus 215dfe6cb66SJason Wang1: pause 216dfe6cb66SJason Wang cmpw %ax, cpu_online_count 217dfe6cb66SJason Wang jne 1b 218dfe6cb66SJason Wang ret 219dfe6cb66SJason Wang 22018a34cceSNadav Amitonline_cpus: 22118048d0fSSean Christopherson .fill (max_cpus + 7) / 8, 1, 0 22218a34cceSNadav Amit 223dfe6cb66SJason Wangcpu_online_count: .word 1 224dfe6cb66SJason Wang 225dfe6cb66SJason Wang.code16 226dfe6cb66SJason Wangsipi_entry: 227dfe6cb66SJason Wang mov %cr0, %eax 228dfe6cb66SJason Wang or $1, %eax 229dfe6cb66SJason Wang mov %eax, %cr0 230dfe6cb66SJason Wang lgdtl gdt32_descr - sipi_entry 231dfe6cb66SJason Wang ljmpl $8, $ap_start32 232dfe6cb66SJason Wang 233dfe6cb66SJason Wanggdt32_descr: 234dfe6cb66SJason Wang .word gdt32_end - gdt32 - 1 235dfe6cb66SJason Wang .long gdt32 236dfe6cb66SJason Wang 237dfe6cb66SJason Wangsipi_end: 238