xref: /kvm-unit-tests/x86/cstart.S (revision b4f3421ff02a7b8f70730d1eabb0ddd5f09ae5cf)
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:
112ded41057SPaolo Bonzini        lgdtl gdt32_descr
113ded41057SPaolo Bonzini        setup_segments
114cae10b5bSClaudio Imbrenda        mov $stacktop, %esp
115ded41057SPaolo Bonzini        setup_percpu_area
116ded41057SPaolo Bonzini
11793dd2aa3SAndrew Jones        push %ebx
118716cea8aSPaolo Bonzini        call setup_multiboot
1194108903cSPaolo Bonzini        addl $4, %esp
120716cea8aSPaolo Bonzini        call setup_libcflat
121ea7d43d0SAvi Kivity        mov mb_cmdline(%ebx), %eax
122ea7d43d0SAvi Kivity        mov %eax, __args
123ea7d43d0SAvi Kivity        call __setup_args
124dfe6cb66SJason Wang        call prepare_32
125dfe6cb66SJason Wang        jmpl $8, $start32
126dfe6cb66SJason Wang
127dfe6cb66SJason Wangprepare_32:
128*b4f3421fSClaudio Imbrenda	mov $(1 << 4), %eax // pse
129dfe6cb66SJason Wang	mov %eax, %cr4
130dfe6cb66SJason Wang
131dfe6cb66SJason Wang	mov $pt, %eax
132dfe6cb66SJason Wang	mov %eax, %cr3
133dfe6cb66SJason Wang
134dfe6cb66SJason Wang	mov %cr0, %eax
135dfe6cb66SJason Wang	bts $0, %eax
136dfe6cb66SJason Wang	bts $31, %eax
137dfe6cb66SJason Wang	mov %eax, %cr0
138dfe6cb66SJason Wang	ret
139dfe6cb66SJason Wang
140d589407fSNadav Amitsmp_stacktop:	.long stacktop - 4096
141dfe6cb66SJason Wang
14218a34cceSNadav Amitsave_id:
14318a34cceSNadav Amit	movl $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
14418a34cceSNadav Amit	movl (%eax), %eax
14518a34cceSNadav Amit	shrl $24, %eax
14618a34cceSNadav Amit	lock btsl %eax, online_cpus
14718a34cceSNadav Amit	retl
14818a34cceSNadav Amit
149dfe6cb66SJason Wangap_start32:
150d68a795aSNadav Amit	setup_segments
151dfe6cb66SJason Wang	mov $-4096, %esp
152dfe6cb66SJason Wang	lock/xaddl %esp, smp_stacktop
153dfe6cb66SJason Wang	setup_percpu_area
154dfe6cb66SJason Wang	call prepare_32
155d6e8f863SNadav Amit	call reset_apic
15618a34cceSNadav Amit	call save_id
157dfe6cb66SJason Wang	call load_tss
158dfe6cb66SJason Wang	call enable_apic
159dfe6cb66SJason Wang	call enable_x2apic
160dfe6cb66SJason Wang	sti
161dfe6cb66SJason Wang	nop
162dfe6cb66SJason Wang	lock incw cpu_online_count
163dfe6cb66SJason Wang
164dfe6cb66SJason Wang1:	hlt
165dfe6cb66SJason Wang	jmp 1b
166dfe6cb66SJason Wang
167dfe6cb66SJason Wangstart32:
168d6e8f863SNadav Amit	call reset_apic
16918a34cceSNadav Amit	call save_id
170dfe6cb66SJason Wang	call load_tss
171dfe6cb66SJason Wang	call mask_pic_interrupts
172dfe6cb66SJason Wang	call enable_apic
17331e68df7SPaolo Bonzini	call ap_init
174dfe6cb66SJason Wang	call enable_x2apic
17531e68df7SPaolo Bonzini	call smp_init
1763c7d322eSAndrew Jones        push $__environ
177dfe6cb66SJason Wang        push $__argv
178dfe6cb66SJason Wang        push __argc
1797d36db35SAvi Kivity        call main
1807d36db35SAvi Kivity	push %eax
1817d36db35SAvi Kivity	call exit
1827d36db35SAvi Kivity
183dfe6cb66SJason Wangload_tss:
184dfe6cb66SJason Wang	lidt idt_descr
185dfe6cb66SJason Wang	mov $16, %eax
186dfe6cb66SJason Wang	mov %ax, %ss
187dfe6cb66SJason Wang	mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
188dfe6cb66SJason Wang	mov (%eax), %eax
189dfe6cb66SJason Wang	shr $24, %eax
190dfe6cb66SJason Wang	mov %eax, %ebx
191dfe6cb66SJason Wang	shl $3, %ebx
192dfe6cb66SJason Wang	mov $((tss_end - tss) / max_cpus), %edx
193dfe6cb66SJason Wang	imul %edx
194dfe6cb66SJason Wang	add $tss, %eax
195dfe6cb66SJason Wang	mov %ax, tss_descr+2(%ebx)
196dfe6cb66SJason Wang	shr $16, %eax
197dfe6cb66SJason Wang	mov %al, tss_descr+4(%ebx)
198dfe6cb66SJason Wang	shr $8, %eax
199dfe6cb66SJason Wang	mov %al, tss_descr+7(%ebx)
200dfe6cb66SJason Wang	lea tss_descr-gdt32(%ebx), %eax
201dfe6cb66SJason Wang	ltr %ax
202dfe6cb66SJason Wang	ret
2037d36db35SAvi Kivity
20431e68df7SPaolo Bonziniap_init:
205dfe6cb66SJason Wang	cld
206dfe6cb66SJason Wang	lea sipi_entry, %esi
207dfe6cb66SJason Wang	xor %edi, %edi
208dfe6cb66SJason Wang	mov $(sipi_end - sipi_entry), %ecx
209dfe6cb66SJason Wang	rep/movsb
210dfe6cb66SJason Wang	mov $APIC_DEFAULT_PHYS_BASE, %eax
211dfe6cb66SJason Wang	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%eax)
212dfe6cb66SJason Wang	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%eax)
213dfe6cb66SJason Wang	call fwcfg_get_nb_cpus
214dfe6cb66SJason Wang1:	pause
215dfe6cb66SJason Wang	cmpw %ax, cpu_online_count
216dfe6cb66SJason Wang	jne 1b
217dfe6cb66SJason Wang	ret
218dfe6cb66SJason Wang
21918a34cceSNadav Amitonline_cpus:
22018048d0fSSean Christopherson	.fill (max_cpus + 7) / 8, 1, 0
22118a34cceSNadav Amit
222dfe6cb66SJason Wangcpu_online_count:	.word 1
223dfe6cb66SJason Wang
224dfe6cb66SJason Wang.code16
225dfe6cb66SJason Wangsipi_entry:
226dfe6cb66SJason Wang	mov %cr0, %eax
227dfe6cb66SJason Wang	or $1, %eax
228dfe6cb66SJason Wang	mov %eax, %cr0
229dfe6cb66SJason Wang	lgdtl gdt32_descr - sipi_entry
230dfe6cb66SJason Wang	ljmpl $8, $ap_start32
231dfe6cb66SJason Wang
232dfe6cb66SJason Wanggdt32_descr:
233dfe6cb66SJason Wang	.word gdt32_end - gdt32 - 1
234dfe6cb66SJason Wang	.long gdt32
235dfe6cb66SJason Wang
236dfe6cb66SJason Wangsipi_end:
237