xref: /kvm-unit-tests/x86/cstart.S (revision 10594e42ecdda42e5eff703439b7079a0c93e8e5)
17d36db35SAvi Kivity
2dfe6cb66SJason Wang#include "apic-defs.h"
3dfe6cb66SJason Wang
4dfe6cb66SJason Wang.globl boot_idt
5dfe6cb66SJason Wangboot_idt = 0
6dfe6cb66SJason Wang
7dfe6cb66SJason Wangipi_vector = 0x20
8dfe6cb66SJason Wang
97407b79bSJason Wangmax_cpus = 64
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
318f4755faSPaolo Bonzini.globl gdt32
32dfe6cb66SJason Wanggdt32:
33dfe6cb66SJason Wang	.quad 0
34dfe6cb66SJason Wang	.quad 0x00cf9b000000ffff // flat 32-bit code segment
35dfe6cb66SJason Wang	.quad 0x00cf93000000ffff // flat 32-bit data segment
368f4755faSPaolo Bonzini	.quad 0x00cf1b000000ffff // flat 32-bit code segment, not present
37*10594e42SPaolo Bonzini	.quad 0                  // TSS for task gates
38*10594e42SPaolo Bonzini	.quad 0x008f9b000000FFFF // 16-bit code segment
39*10594e42SPaolo Bonzini	.quad 0x008f93000000FFFF // 16-bit data segment
40*10594e42SPaolo Bonzini	.quad 0x00cffb000000ffff // 32-bit code segment (user)
41*10594e42SPaolo Bonzini	.quad 0x00cff3000000ffff // 32-bit data segment (user)
42*10594e42SPaolo Bonzini	.quad 0                  // unused
438f4755faSPaolo Bonzini
44*10594e42SPaolo Bonzini	.quad 0			 // 6 spare selectors
458f4755faSPaolo Bonzini	.quad 0
468f4755faSPaolo Bonzini	.quad 0
478f4755faSPaolo Bonzini	.quad 0
488f4755faSPaolo Bonzini	.quad 0
498f4755faSPaolo Bonzini	.quad 0
50dfe6cb66SJason Wang
51dfe6cb66SJason Wangtss_descr:
52dfe6cb66SJason Wang        .rept max_cpus
53dfe6cb66SJason Wang        .quad 0x000089000000ffff // 32-bit avail tss
54dfe6cb66SJason Wang        .endr
55dfe6cb66SJason Wanggdt32_end:
56dfe6cb66SJason Wang
57dfe6cb66SJason Wangi = 0
588f4755faSPaolo Bonzini.globl tss
59dfe6cb66SJason Wangtss:
60dfe6cb66SJason Wang        .rept max_cpus
61dfe6cb66SJason Wang        .long 0
62dfe6cb66SJason Wang        .long ring0stacktop - i * 4096
63dfe6cb66SJason Wang        .long 16
64dfe6cb66SJason Wang        .quad 0, 0
65dfe6cb66SJason Wang        .quad 0, 0, 0, 0, 0, 0, 0, 0
66dfe6cb66SJason Wang        .long 0, 0, 0
67dfe6cb66SJason Wang        i = i + 1
68dfe6cb66SJason Wang        .endr
69dfe6cb66SJason Wangtss_end:
70dfe6cb66SJason Wang
71dfe6cb66SJason Wangidt_descr:
72dfe6cb66SJason Wang	.word 16 * 256 - 1
73dfe6cb66SJason Wang	.long boot_idt
74dfe6cb66SJason Wang
757d36db35SAvi Kivity.section .init
767d36db35SAvi Kivity
77dfe6cb66SJason Wang.code32
78dfe6cb66SJason Wang
797d36db35SAvi Kivitymb_magic = 0x1BADB002
807d36db35SAvi Kivitymb_flags = 0x0
817d36db35SAvi Kivity
827d36db35SAvi Kivity	# multiboot header
837d36db35SAvi Kivity	.long mb_magic, mb_flags, 0 - (mb_magic + mb_flags)
84ea7d43d0SAvi Kivitymb_cmdline = 16
857d36db35SAvi Kivity
86dfe6cb66SJason WangMSR_GS_BASE = 0xc0000101
87dfe6cb66SJason Wang
88dfe6cb66SJason Wang.macro setup_percpu_area
89dfe6cb66SJason Wang	lea -4096(%esp), %eax
90dfe6cb66SJason Wang	mov $0, %edx
91dfe6cb66SJason Wang	mov $MSR_GS_BASE, %ecx
92dfe6cb66SJason Wang	wrmsr
93dfe6cb66SJason Wang.endm
94dfe6cb66SJason Wang
957d36db35SAvi Kivity.globl start
967d36db35SAvi Kivitystart:
9793dd2aa3SAndrew Jones        push %ebx
9893dd2aa3SAndrew Jones        call setup_get_initrd
993c7d322eSAndrew Jones        call setup_environ
100ea7d43d0SAvi Kivity        mov mb_cmdline(%ebx), %eax
101ea7d43d0SAvi Kivity        mov %eax, __args
102ea7d43d0SAvi Kivity        call __setup_args
103dfe6cb66SJason Wang        mov $stacktop, %esp
104dfe6cb66SJason Wang        setup_percpu_area
105dfe6cb66SJason Wang        call prepare_32
106dfe6cb66SJason Wang        jmpl $8, $start32
107dfe6cb66SJason Wang
108dfe6cb66SJason Wangprepare_32:
109dfe6cb66SJason Wang        lgdtl gdt32_descr
110dfe6cb66SJason Wang
111dfe6cb66SJason Wang	mov %cr4, %eax
112dfe6cb66SJason Wang	bts $4, %eax  // pse
113dfe6cb66SJason Wang	mov %eax, %cr4
114dfe6cb66SJason Wang
115dfe6cb66SJason Wang	mov $pt, %eax
116dfe6cb66SJason Wang	mov %eax, %cr3
117dfe6cb66SJason Wang
118dfe6cb66SJason Wang	mov %cr0, %eax
119dfe6cb66SJason Wang	bts $0, %eax
120dfe6cb66SJason Wang	bts $31, %eax
121dfe6cb66SJason Wang	mov %eax, %cr0
122dfe6cb66SJason Wang	ret
123dfe6cb66SJason Wang
124dfe6cb66SJason Wangsmp_stacktop:	.long 0xa0000
125dfe6cb66SJason Wang
126dfe6cb66SJason Wangap_start32:
127dfe6cb66SJason Wang	mov $0x10, %ax
128dfe6cb66SJason Wang	mov %ax, %ds
129dfe6cb66SJason Wang	mov %ax, %es
130dfe6cb66SJason Wang	mov %ax, %fs
131dfe6cb66SJason Wang	mov %ax, %gs
132dfe6cb66SJason Wang	mov %ax, %ss
133dfe6cb66SJason Wang	mov $-4096, %esp
134dfe6cb66SJason Wang	lock/xaddl %esp, smp_stacktop
135dfe6cb66SJason Wang	setup_percpu_area
136dfe6cb66SJason Wang	call prepare_32
137dfe6cb66SJason Wang	call load_tss
138dfe6cb66SJason Wang	call enable_apic
139dfe6cb66SJason Wang	call enable_x2apic
140dfe6cb66SJason Wang	sti
141dfe6cb66SJason Wang	nop
142dfe6cb66SJason Wang	lock incw cpu_online_count
143dfe6cb66SJason Wang
144dfe6cb66SJason Wang1:	hlt
145dfe6cb66SJason Wang	jmp 1b
146dfe6cb66SJason Wang
147dfe6cb66SJason Wangstart32:
148dfe6cb66SJason Wang	call load_tss
149dfe6cb66SJason Wang	call mask_pic_interrupts
150dfe6cb66SJason Wang	call enable_apic
151dfe6cb66SJason Wang	call smp_init
152dfe6cb66SJason Wang	call enable_x2apic
1533c7d322eSAndrew Jones        push $__environ
154dfe6cb66SJason Wang        push $__argv
155dfe6cb66SJason Wang        push __argc
1567d36db35SAvi Kivity        call main
1577d36db35SAvi Kivity	push %eax
1587d36db35SAvi Kivity	call exit
1597d36db35SAvi Kivity
160dfe6cb66SJason Wangload_tss:
161dfe6cb66SJason Wang	lidt idt_descr
162dfe6cb66SJason Wang	mov $16, %eax
163dfe6cb66SJason Wang	mov %ax, %ss
164dfe6cb66SJason Wang	mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
165dfe6cb66SJason Wang	mov (%eax), %eax
166dfe6cb66SJason Wang	shr $24, %eax
167dfe6cb66SJason Wang	mov %eax, %ebx
168dfe6cb66SJason Wang	shl $3, %ebx
169dfe6cb66SJason Wang	mov $((tss_end - tss) / max_cpus), %edx
170dfe6cb66SJason Wang	imul %edx
171dfe6cb66SJason Wang	add $tss, %eax
172dfe6cb66SJason Wang	mov %ax, tss_descr+2(%ebx)
173dfe6cb66SJason Wang	shr $16, %eax
174dfe6cb66SJason Wang	mov %al, tss_descr+4(%ebx)
175dfe6cb66SJason Wang	shr $8, %eax
176dfe6cb66SJason Wang	mov %al, tss_descr+7(%ebx)
177dfe6cb66SJason Wang	lea tss_descr-gdt32(%ebx), %eax
178dfe6cb66SJason Wang	ltr %ax
179dfe6cb66SJason Wang	ret
1807d36db35SAvi Kivity
181dfe6cb66SJason Wangsmp_init:
182dfe6cb66SJason Wang	cld
183dfe6cb66SJason Wang	lea sipi_entry, %esi
184dfe6cb66SJason Wang	xor %edi, %edi
185dfe6cb66SJason Wang	mov $(sipi_end - sipi_entry), %ecx
186dfe6cb66SJason Wang	rep/movsb
187dfe6cb66SJason Wang	mov $APIC_DEFAULT_PHYS_BASE, %eax
188dfe6cb66SJason Wang	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%eax)
189dfe6cb66SJason Wang	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%eax)
190dfe6cb66SJason Wang	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%eax)
191dfe6cb66SJason Wang	call fwcfg_get_nb_cpus
192dfe6cb66SJason Wang1:	pause
193dfe6cb66SJason Wang	cmpw %ax, cpu_online_count
194dfe6cb66SJason Wang	jne 1b
195dfe6cb66SJason Wangsmp_init_done:
196dfe6cb66SJason Wang	ret
197dfe6cb66SJason Wang
198dfe6cb66SJason Wangcpu_online_count:	.word 1
199dfe6cb66SJason Wang
200dfe6cb66SJason Wang.code16
201dfe6cb66SJason Wangsipi_entry:
202dfe6cb66SJason Wang	mov %cr0, %eax
203dfe6cb66SJason Wang	or $1, %eax
204dfe6cb66SJason Wang	mov %eax, %cr0
205dfe6cb66SJason Wang	lgdtl gdt32_descr - sipi_entry
206dfe6cb66SJason Wang	ljmpl $8, $ap_start32
207dfe6cb66SJason Wang
208dfe6cb66SJason Wanggdt32_descr:
209dfe6cb66SJason Wang	.word gdt32_end - gdt32 - 1
210dfe6cb66SJason Wang	.long gdt32
211dfe6cb66SJason Wang
212dfe6cb66SJason Wangsipi_end:
213