xref: /kvm-unit-tests/x86/cstart.S (revision d6e8f863a5fbc6136aef5dd0cbd3c1b8f40851a7)
17d36db35SAvi Kivity
2dfe6cb66SJason Wang#include "apic-defs.h"
3dfe6cb66SJason Wang
4dfe6cb66SJason Wang.globl boot_idt
518a34cceSNadav Amit.global online_cpus
618a34cceSNadav Amit
7dfe6cb66SJason Wangboot_idt = 0
8dfe6cb66SJason Wang
9dfe6cb66SJason Wangipi_vector = 0x20
10dfe6cb66SJason Wang
1118a34cceSNadav Amitmax_cpus = MAX_TEST_CPUS
127d36db35SAvi Kivity
137d36db35SAvi Kivity.bss
147d36db35SAvi Kivity
15dfe6cb66SJason Wang	. = . + 4096 * max_cpus
16dfe6cb66SJason Wang	.align 16
17dfe6cb66SJason Wangstacktop:
18dfe6cb66SJason Wang
19dfe6cb66SJason Wang	. = . + 4096
20dfe6cb66SJason Wang	.align 16
21dfe6cb66SJason Wangring0stacktop:
22dfe6cb66SJason Wang
23dfe6cb66SJason Wang.data
24dfe6cb66SJason Wang
25dfe6cb66SJason Wang.align 4096
26dfe6cb66SJason Wangpt:
27dfe6cb66SJason Wangi = 0
28dfe6cb66SJason Wang        .rept 1024
29dfe6cb66SJason Wang        .long 0x1e7 | (i << 22)
30dfe6cb66SJason Wang        i = i + 1
31dfe6cb66SJason Wang        .endr
32dfe6cb66SJason Wang
338f4755faSPaolo Bonzini.globl gdt32
34dfe6cb66SJason Wanggdt32:
35dfe6cb66SJason Wang	.quad 0
36dfe6cb66SJason Wang	.quad 0x00cf9b000000ffff // flat 32-bit code segment
37dfe6cb66SJason Wang	.quad 0x00cf93000000ffff // flat 32-bit data segment
388f4755faSPaolo Bonzini	.quad 0x00cf1b000000ffff // flat 32-bit code segment, not present
3910594e42SPaolo Bonzini	.quad 0                  // TSS for task gates
4010594e42SPaolo Bonzini	.quad 0x008f9b000000FFFF // 16-bit code segment
4110594e42SPaolo Bonzini	.quad 0x008f93000000FFFF // 16-bit data segment
4210594e42SPaolo Bonzini	.quad 0x00cffb000000ffff // 32-bit code segment (user)
4310594e42SPaolo Bonzini	.quad 0x00cff3000000ffff // 32-bit data segment (user)
4410594e42SPaolo Bonzini	.quad 0                  // unused
458f4755faSPaolo Bonzini
4610594e42SPaolo Bonzini	.quad 0			 // 6 spare selectors
478f4755faSPaolo Bonzini	.quad 0
488f4755faSPaolo Bonzini	.quad 0
498f4755faSPaolo Bonzini	.quad 0
508f4755faSPaolo Bonzini	.quad 0
518f4755faSPaolo Bonzini	.quad 0
52dfe6cb66SJason Wang
53dfe6cb66SJason Wangtss_descr:
54dfe6cb66SJason Wang        .rept max_cpus
55dfe6cb66SJason Wang        .quad 0x000089000000ffff // 32-bit avail tss
56dfe6cb66SJason Wang        .endr
57dfe6cb66SJason Wanggdt32_end:
58dfe6cb66SJason Wang
59dfe6cb66SJason Wangi = 0
608f4755faSPaolo Bonzini.globl tss
61dfe6cb66SJason Wangtss:
62dfe6cb66SJason Wang        .rept max_cpus
63dfe6cb66SJason Wang        .long 0
64dfe6cb66SJason Wang        .long ring0stacktop - i * 4096
65dfe6cb66SJason Wang        .long 16
66dfe6cb66SJason Wang        .quad 0, 0
67dfe6cb66SJason Wang        .quad 0, 0, 0, 0, 0, 0, 0, 0
68dfe6cb66SJason Wang        .long 0, 0, 0
69dfe6cb66SJason Wang        i = i + 1
70dfe6cb66SJason Wang        .endr
71dfe6cb66SJason Wangtss_end:
72dfe6cb66SJason Wang
73dfe6cb66SJason Wangidt_descr:
74dfe6cb66SJason Wang	.word 16 * 256 - 1
75dfe6cb66SJason Wang	.long boot_idt
76dfe6cb66SJason Wang
777d36db35SAvi Kivity.section .init
787d36db35SAvi Kivity
79dfe6cb66SJason Wang.code32
80dfe6cb66SJason Wang
817d36db35SAvi Kivitymb_magic = 0x1BADB002
827d36db35SAvi Kivitymb_flags = 0x0
837d36db35SAvi Kivity
847d36db35SAvi Kivity	# multiboot header
857d36db35SAvi Kivity	.long mb_magic, mb_flags, 0 - (mb_magic + mb_flags)
86ea7d43d0SAvi Kivitymb_cmdline = 16
877d36db35SAvi Kivity
88dfe6cb66SJason WangMSR_GS_BASE = 0xc0000101
89dfe6cb66SJason Wang
90dfe6cb66SJason Wang.macro setup_percpu_area
91dfe6cb66SJason Wang	lea -4096(%esp), %eax
92dfe6cb66SJason Wang	mov $0, %edx
93dfe6cb66SJason Wang	mov $MSR_GS_BASE, %ecx
94dfe6cb66SJason Wang	wrmsr
95dfe6cb66SJason Wang.endm
96dfe6cb66SJason Wang
977d36db35SAvi Kivity.globl start
987d36db35SAvi Kivitystart:
9993dd2aa3SAndrew Jones        push %ebx
100716cea8aSPaolo Bonzini        call setup_multiboot
101716cea8aSPaolo Bonzini        call setup_libcflat
102ea7d43d0SAvi Kivity        mov mb_cmdline(%ebx), %eax
103ea7d43d0SAvi Kivity        mov %eax, __args
104ea7d43d0SAvi Kivity        call __setup_args
105dfe6cb66SJason Wang        mov $stacktop, %esp
106dfe6cb66SJason Wang        setup_percpu_area
107dfe6cb66SJason Wang        call prepare_32
108dfe6cb66SJason Wang        jmpl $8, $start32
109dfe6cb66SJason Wang
110dfe6cb66SJason Wangprepare_32:
111dfe6cb66SJason Wang        lgdtl gdt32_descr
112dfe6cb66SJason Wang
113dfe6cb66SJason Wang	mov %cr4, %eax
114dfe6cb66SJason Wang	bts $4, %eax  // pse
115dfe6cb66SJason Wang	mov %eax, %cr4
116dfe6cb66SJason Wang
117dfe6cb66SJason Wang	mov $pt, %eax
118dfe6cb66SJason Wang	mov %eax, %cr3
119dfe6cb66SJason Wang
120dfe6cb66SJason Wang	mov %cr0, %eax
121dfe6cb66SJason Wang	bts $0, %eax
122dfe6cb66SJason Wang	bts $31, %eax
123dfe6cb66SJason Wang	mov %eax, %cr0
124dfe6cb66SJason Wang	ret
125dfe6cb66SJason Wang
126dfe6cb66SJason Wangsmp_stacktop:	.long 0xa0000
127dfe6cb66SJason Wang
12818a34cceSNadav Amitsave_id:
12918a34cceSNadav Amit	movl $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
13018a34cceSNadav Amit	movl (%eax), %eax
13118a34cceSNadav Amit	shrl $24, %eax
13218a34cceSNadav Amit	lock btsl %eax, online_cpus
13318a34cceSNadav Amit	retl
13418a34cceSNadav Amit
135dfe6cb66SJason Wangap_start32:
136dfe6cb66SJason Wang	mov $0x10, %ax
137dfe6cb66SJason Wang	mov %ax, %ds
138dfe6cb66SJason Wang	mov %ax, %es
139dfe6cb66SJason Wang	mov %ax, %fs
140dfe6cb66SJason Wang	mov %ax, %gs
141dfe6cb66SJason Wang	mov %ax, %ss
142dfe6cb66SJason Wang	mov $-4096, %esp
143dfe6cb66SJason Wang	lock/xaddl %esp, smp_stacktop
144dfe6cb66SJason Wang	setup_percpu_area
145dfe6cb66SJason Wang	call prepare_32
146*d6e8f863SNadav Amit	call reset_apic
14718a34cceSNadav Amit	call save_id
148dfe6cb66SJason Wang	call load_tss
149dfe6cb66SJason Wang	call enable_apic
150dfe6cb66SJason Wang	call enable_x2apic
151dfe6cb66SJason Wang	sti
152dfe6cb66SJason Wang	nop
153dfe6cb66SJason Wang	lock incw cpu_online_count
154dfe6cb66SJason Wang
155dfe6cb66SJason Wang1:	hlt
156dfe6cb66SJason Wang	jmp 1b
157dfe6cb66SJason Wang
158dfe6cb66SJason Wangstart32:
159*d6e8f863SNadav Amit	call reset_apic
16018a34cceSNadav Amit	call save_id
161dfe6cb66SJason Wang	call load_tss
162dfe6cb66SJason Wang	call mask_pic_interrupts
163dfe6cb66SJason Wang	call enable_apic
164dfe6cb66SJason Wang	call smp_init
165dfe6cb66SJason Wang	call enable_x2apic
1663c7d322eSAndrew Jones        push $__environ
167dfe6cb66SJason Wang        push $__argv
168dfe6cb66SJason Wang        push __argc
1697d36db35SAvi Kivity        call main
1707d36db35SAvi Kivity	push %eax
1717d36db35SAvi Kivity	call exit
1727d36db35SAvi Kivity
173dfe6cb66SJason Wangload_tss:
174dfe6cb66SJason Wang	lidt idt_descr
175dfe6cb66SJason Wang	mov $16, %eax
176dfe6cb66SJason Wang	mov %ax, %ss
177dfe6cb66SJason Wang	mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
178dfe6cb66SJason Wang	mov (%eax), %eax
179dfe6cb66SJason Wang	shr $24, %eax
180dfe6cb66SJason Wang	mov %eax, %ebx
181dfe6cb66SJason Wang	shl $3, %ebx
182dfe6cb66SJason Wang	mov $((tss_end - tss) / max_cpus), %edx
183dfe6cb66SJason Wang	imul %edx
184dfe6cb66SJason Wang	add $tss, %eax
185dfe6cb66SJason Wang	mov %ax, tss_descr+2(%ebx)
186dfe6cb66SJason Wang	shr $16, %eax
187dfe6cb66SJason Wang	mov %al, tss_descr+4(%ebx)
188dfe6cb66SJason Wang	shr $8, %eax
189dfe6cb66SJason Wang	mov %al, tss_descr+7(%ebx)
190dfe6cb66SJason Wang	lea tss_descr-gdt32(%ebx), %eax
191dfe6cb66SJason Wang	ltr %ax
192dfe6cb66SJason Wang	ret
1937d36db35SAvi Kivity
194dfe6cb66SJason Wangsmp_init:
195dfe6cb66SJason Wang	cld
196dfe6cb66SJason Wang	lea sipi_entry, %esi
197dfe6cb66SJason Wang	xor %edi, %edi
198dfe6cb66SJason Wang	mov $(sipi_end - sipi_entry), %ecx
199dfe6cb66SJason Wang	rep/movsb
200dfe6cb66SJason Wang	mov $APIC_DEFAULT_PHYS_BASE, %eax
201dfe6cb66SJason Wang	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%eax)
202dfe6cb66SJason Wang	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%eax)
203dfe6cb66SJason Wang	call fwcfg_get_nb_cpus
204dfe6cb66SJason Wang1:	pause
205dfe6cb66SJason Wang	cmpw %ax, cpu_online_count
206dfe6cb66SJason Wang	jne 1b
207dfe6cb66SJason Wangsmp_init_done:
208dfe6cb66SJason Wang	ret
209dfe6cb66SJason Wang
21018a34cceSNadav Amitonline_cpus:
21118a34cceSNadav Amit	.quad 0
21218a34cceSNadav Amit
213dfe6cb66SJason Wangcpu_online_count:	.word 1
214dfe6cb66SJason Wang
215dfe6cb66SJason Wang.code16
216dfe6cb66SJason Wangsipi_entry:
217dfe6cb66SJason Wang	mov %cr0, %eax
218dfe6cb66SJason Wang	or $1, %eax
219dfe6cb66SJason Wang	mov %eax, %cr0
220dfe6cb66SJason Wang	lgdtl gdt32_descr - sipi_entry
221dfe6cb66SJason Wang	ljmpl $8, $ap_start32
222dfe6cb66SJason Wang
223dfe6cb66SJason Wanggdt32_descr:
224dfe6cb66SJason Wang	.word gdt32_end - gdt32 - 1
225dfe6cb66SJason Wang	.long gdt32
226dfe6cb66SJason Wang
227dfe6cb66SJason Wangsipi_end:
228