xref: /kvm-unit-tests/x86/cstart.S (revision dfe6cb66b30d3c1cfaa6a915492f75a16e34ee6a)
17d36db35SAvi Kivity
2*dfe6cb66SJason Wang#include "apic-defs.h"
3*dfe6cb66SJason Wang
4*dfe6cb66SJason Wang.globl boot_idt
5*dfe6cb66SJason Wangboot_idt = 0
6*dfe6cb66SJason Wang
7*dfe6cb66SJason Wangipi_vector = 0x20
8*dfe6cb66SJason Wang
9*dfe6cb66SJason Wangmax_cpus = 4
107d36db35SAvi Kivity
117d36db35SAvi Kivity.bss
127d36db35SAvi Kivity
13*dfe6cb66SJason Wang	. = . + 4096 * max_cpus
14*dfe6cb66SJason Wang	.align 16
15*dfe6cb66SJason Wangstacktop:
16*dfe6cb66SJason Wang
17*dfe6cb66SJason Wang	. = . + 4096
18*dfe6cb66SJason Wang	.align 16
19*dfe6cb66SJason Wangring0stacktop:
20*dfe6cb66SJason Wang
21*dfe6cb66SJason Wang.data
22*dfe6cb66SJason Wang
23*dfe6cb66SJason Wang.align 4096
24*dfe6cb66SJason Wangpt:
25*dfe6cb66SJason Wangi = 0
26*dfe6cb66SJason Wang        .rept 1024
27*dfe6cb66SJason Wang        .long 0x1e7 | (i << 22)
28*dfe6cb66SJason Wang        i = i + 1
29*dfe6cb66SJason Wang        .endr
30*dfe6cb66SJason Wang
31*dfe6cb66SJason Wanggdt32:
32*dfe6cb66SJason Wang	.quad 0
33*dfe6cb66SJason Wang	.quad 0x00cf9b000000ffff // flat 32-bit code segment
34*dfe6cb66SJason Wang	.quad 0x00cf93000000ffff // flat 32-bit data segment
35*dfe6cb66SJason Wang
36*dfe6cb66SJason Wangtss_descr:
37*dfe6cb66SJason Wang        .rept max_cpus
38*dfe6cb66SJason Wang        .quad 0x000089000000ffff // 32-bit avail tss
39*dfe6cb66SJason Wang        .endr
40*dfe6cb66SJason Wanggdt32_end:
41*dfe6cb66SJason Wang
42*dfe6cb66SJason Wangi = 0
43*dfe6cb66SJason Wangtss:
44*dfe6cb66SJason Wang        .rept max_cpus
45*dfe6cb66SJason Wang        .long 0
46*dfe6cb66SJason Wang        .long ring0stacktop - i * 4096
47*dfe6cb66SJason Wang        .long 16
48*dfe6cb66SJason Wang        .quad 0, 0
49*dfe6cb66SJason Wang        .quad 0, 0, 0, 0, 0, 0, 0, 0
50*dfe6cb66SJason Wang        .long 0, 0, 0
51*dfe6cb66SJason Wang        i = i + 1
52*dfe6cb66SJason Wang        .endr
53*dfe6cb66SJason Wangtss_end:
54*dfe6cb66SJason Wang
55*dfe6cb66SJason Wangidt_descr:
56*dfe6cb66SJason Wang	.word 16 * 256 - 1
57*dfe6cb66SJason Wang	.long boot_idt
58*dfe6cb66SJason Wang
597d36db35SAvi Kivity.section .init
607d36db35SAvi Kivity
61*dfe6cb66SJason Wang.code32
62*dfe6cb66SJason Wang
637d36db35SAvi Kivitymb_magic = 0x1BADB002
647d36db35SAvi Kivitymb_flags = 0x0
657d36db35SAvi Kivity
667d36db35SAvi Kivity	# multiboot header
677d36db35SAvi Kivity	.long mb_magic, mb_flags, 0 - (mb_magic + mb_flags)
68ea7d43d0SAvi Kivitymb_cmdline = 16
697d36db35SAvi Kivity
70*dfe6cb66SJason WangMSR_GS_BASE = 0xc0000101
71*dfe6cb66SJason Wang
72*dfe6cb66SJason Wang.macro setup_percpu_area
73*dfe6cb66SJason Wang	lea -4096(%esp), %eax
74*dfe6cb66SJason Wang	mov $0, %edx
75*dfe6cb66SJason Wang	mov $MSR_GS_BASE, %ecx
76*dfe6cb66SJason Wang	wrmsr
77*dfe6cb66SJason Wang.endm
78*dfe6cb66SJason Wang
797d36db35SAvi Kivity.globl start
807d36db35SAvi Kivitystart:
81ea7d43d0SAvi Kivity        mov mb_cmdline(%ebx), %eax
82ea7d43d0SAvi Kivity        mov %eax, __args
83ea7d43d0SAvi Kivity        call __setup_args
84*dfe6cb66SJason Wang        mov $stacktop, %esp
85*dfe6cb66SJason Wang        setup_percpu_area
86*dfe6cb66SJason Wang        call prepare_32
87*dfe6cb66SJason Wang        jmpl $8, $start32
88*dfe6cb66SJason Wang
89*dfe6cb66SJason Wangprepare_32:
90*dfe6cb66SJason Wang        lgdtl gdt32_descr
91*dfe6cb66SJason Wang
92*dfe6cb66SJason Wang	mov %cr4, %eax
93*dfe6cb66SJason Wang	bts $4, %eax  // pse
94*dfe6cb66SJason Wang	mov %eax, %cr4
95*dfe6cb66SJason Wang
96*dfe6cb66SJason Wang	mov $pt, %eax
97*dfe6cb66SJason Wang	mov %eax, %cr3
98*dfe6cb66SJason Wang
99*dfe6cb66SJason Wang	mov %cr0, %eax
100*dfe6cb66SJason Wang	bts $0, %eax
101*dfe6cb66SJason Wang	bts $31, %eax
102*dfe6cb66SJason Wang	mov %eax, %cr0
103*dfe6cb66SJason Wang	ret
104*dfe6cb66SJason Wang
105*dfe6cb66SJason Wangsmp_stacktop:	.long 0xa0000
106*dfe6cb66SJason Wang
107*dfe6cb66SJason Wangap_start32:
108*dfe6cb66SJason Wang	mov $0x10, %ax
109*dfe6cb66SJason Wang	mov %ax, %ds
110*dfe6cb66SJason Wang	mov %ax, %es
111*dfe6cb66SJason Wang	mov %ax, %fs
112*dfe6cb66SJason Wang	mov %ax, %gs
113*dfe6cb66SJason Wang	mov %ax, %ss
114*dfe6cb66SJason Wang	mov $-4096, %esp
115*dfe6cb66SJason Wang	lock/xaddl %esp, smp_stacktop
116*dfe6cb66SJason Wang	setup_percpu_area
117*dfe6cb66SJason Wang	call prepare_32
118*dfe6cb66SJason Wang	call load_tss
119*dfe6cb66SJason Wang	call enable_apic
120*dfe6cb66SJason Wang	call enable_x2apic
121*dfe6cb66SJason Wang	sti
122*dfe6cb66SJason Wang	nop
123*dfe6cb66SJason Wang	lock incw cpu_online_count
124*dfe6cb66SJason Wang
125*dfe6cb66SJason Wang1:	hlt
126*dfe6cb66SJason Wang	jmp 1b
127*dfe6cb66SJason Wang
128*dfe6cb66SJason Wangstart32:
129*dfe6cb66SJason Wang	call load_tss
130*dfe6cb66SJason Wang	call mask_pic_interrupts
131*dfe6cb66SJason Wang	call enable_apic
132*dfe6cb66SJason Wang	call smp_init
133*dfe6cb66SJason Wang	call enable_x2apic
134*dfe6cb66SJason Wang        push $__argv
135*dfe6cb66SJason Wang        push __argc
1367d36db35SAvi Kivity        call main
1377d36db35SAvi Kivity	push %eax
1387d36db35SAvi Kivity	call exit
1397d36db35SAvi Kivity
140*dfe6cb66SJason Wangload_tss:
141*dfe6cb66SJason Wang	lidt idt_descr
142*dfe6cb66SJason Wang	mov $16, %eax
143*dfe6cb66SJason Wang	mov %ax, %ss
144*dfe6cb66SJason Wang	mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
145*dfe6cb66SJason Wang	mov (%eax), %eax
146*dfe6cb66SJason Wang	shr $24, %eax
147*dfe6cb66SJason Wang	mov %eax, %ebx
148*dfe6cb66SJason Wang	shl $3, %ebx
149*dfe6cb66SJason Wang	mov $((tss_end - tss) / max_cpus), %edx
150*dfe6cb66SJason Wang	imul %edx
151*dfe6cb66SJason Wang	add $tss, %eax
152*dfe6cb66SJason Wang	mov %ax, tss_descr+2(%ebx)
153*dfe6cb66SJason Wang	shr $16, %eax
154*dfe6cb66SJason Wang	mov %al, tss_descr+4(%ebx)
155*dfe6cb66SJason Wang	shr $8, %eax
156*dfe6cb66SJason Wang	mov %al, tss_descr+7(%ebx)
157*dfe6cb66SJason Wang	lea tss_descr-gdt32(%ebx), %eax
158*dfe6cb66SJason Wang	ltr %ax
159*dfe6cb66SJason Wang	ret
1607d36db35SAvi Kivity
161*dfe6cb66SJason Wangsmp_init:
162*dfe6cb66SJason Wang	cld
163*dfe6cb66SJason Wang	lea sipi_entry, %esi
164*dfe6cb66SJason Wang	xor %edi, %edi
165*dfe6cb66SJason Wang	mov $(sipi_end - sipi_entry), %ecx
166*dfe6cb66SJason Wang	rep/movsb
167*dfe6cb66SJason Wang	mov $APIC_DEFAULT_PHYS_BASE, %eax
168*dfe6cb66SJason Wang	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%eax)
169*dfe6cb66SJason Wang	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%eax)
170*dfe6cb66SJason Wang	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%eax)
171*dfe6cb66SJason Wang	call fwcfg_get_nb_cpus
172*dfe6cb66SJason Wang1:	pause
173*dfe6cb66SJason Wang	cmpw %ax, cpu_online_count
174*dfe6cb66SJason Wang	jne 1b
175*dfe6cb66SJason Wangsmp_init_done:
176*dfe6cb66SJason Wang	ret
177*dfe6cb66SJason Wang
178*dfe6cb66SJason Wangcpu_online_count:	.word 1
179*dfe6cb66SJason Wang
180*dfe6cb66SJason Wang.code16
181*dfe6cb66SJason Wangsipi_entry:
182*dfe6cb66SJason Wang	mov %cr0, %eax
183*dfe6cb66SJason Wang	or $1, %eax
184*dfe6cb66SJason Wang	mov %eax, %cr0
185*dfe6cb66SJason Wang	lgdtl gdt32_descr - sipi_entry
186*dfe6cb66SJason Wang	ljmpl $8, $ap_start32
187*dfe6cb66SJason Wang
188*dfe6cb66SJason Wanggdt32_descr:
189*dfe6cb66SJason Wang	.word gdt32_end - gdt32 - 1
190*dfe6cb66SJason Wang	.long gdt32
191*dfe6cb66SJason Wang
192*dfe6cb66SJason Wangsipi_end:
193