xref: /kvm-unit-tests/x86/cstart.S (revision 5ed101410fa8defca8f00cf090e5392ea86a8e6b)
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