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