xref: /kvm-unit-tests/x86/cstart64.S (revision a322d4c597bb7a4de7985e7b51b80504f7e4fdda)
1
2#include "apic-defs.h"
3
4.globl boot_idt
5boot_idt = 0
6
7.globl idt_descr
8.globl tss_descr
9.globl gdt64_desc
10
11ipi_vector = 0x20
12
13max_cpus = 64
14
15.bss
16
17	. = . + 4096 * max_cpus
18	.align 16
19stacktop:
20
21	. = . + 4096
22	.align 16
23ring0stacktop:
24
25.data
26
27.align 4096
28.globl ptl2
29ptl2:
30i = 0
31	.rept 512 * 4
32	.quad 0x1e7 | (i << 21)
33	i = i + 1
34	.endr
35
36.align 4096
37ptl3:
38	.quad ptl2 + 7 + 0 * 4096
39	.quad ptl2 + 7 + 1 * 4096
40	.quad ptl2 + 7 + 2 * 4096
41	.quad ptl2 + 7 + 3 * 4096
42
43.align 4096
44ptl4:
45	.quad ptl3 + 7
46
47.align 4096
48
49gdt64_desc:
50	.word gdt64_end - gdt64 - 1
51	.quad gdt64
52
53gdt64:
54	.quad 0
55	.quad 0x00af9b000000ffff // 64-bit code segment
56	.quad 0x00cf93000000ffff // 64-bit data segment
57	.quad 0x00af1b000000ffff // 64-bit code segment, not present
58	.quad 0x00affb000000ffff // 64-bit code segment (user)
59	.quad 0x00cff3000000ffff // 64-bit data segment (user)
60	.quad 0x00cf9b000000ffff // 32-bit code segment
61	.quad 0x00cf92000000ffff // 32-bit data segment
62	.quad 0x008F9A000000FFFF // 16-bit code segment
63	.quad 0x008F92000000FFFF // 16-bit data segment
64
65	.quad 0			 // 6 spare selectors
66	.quad 0
67	.quad 0
68	.quad 0
69	.quad 0
70	.quad 0
71
72tss_descr:
73	.rept max_cpus
74	.quad 0x000089000000ffff // 64-bit avail tss
75	.quad 0                  // tss high addr
76	.endr
77gdt64_end:
78
79i = 0
80.globl tss
81tss:
82	.rept max_cpus
83	.long 0
84	.quad ring0stacktop - i * 4096
85	.quad 0, 0
86	.quad 0, 0, 0, 0, 0, 0, 0, 0
87	.long 0, 0, 0
88i = i + 1
89	.endr
90tss_end:
91
92mb_boot_info:	.quad 0
93
94.section .init
95
96.code32
97
98mb_magic = 0x1BADB002
99mb_flags = 0x0
100
101	# multiboot header
102	.long mb_magic, mb_flags, 0 - (mb_magic + mb_flags)
103mb_cmdline = 16
104
105MSR_GS_BASE = 0xc0000101
106
107.macro setup_percpu_area
108	lea -4096(%esp), %eax
109	mov $0, %edx
110	mov $MSR_GS_BASE, %ecx
111	wrmsr
112.endm
113
114.globl start
115start:
116	mov %ebx, mb_boot_info
117	mov $stacktop, %esp
118	setup_percpu_area
119	call prepare_64
120	jmpl $8, $start64
121
122prepare_64:
123	lgdt gdt64_desc
124
125	mov %cr4, %eax
126	bts $5, %eax  // pae
127	mov %eax, %cr4
128
129	mov $ptl4, %eax
130	mov %eax, %cr3
131
132efer = 0xc0000080
133	mov $efer, %ecx
134	rdmsr
135	bts $8, %eax
136	wrmsr
137
138	mov %cr0, %eax
139	bts $0, %eax
140	bts $31, %eax
141	mov %eax, %cr0
142	ret
143
144smp_stacktop:	.long 0xa0000
145
146.align 16
147
148gdt32:
149	.quad 0
150	.quad 0x00cf9b000000ffff // flat 32-bit code segment
151	.quad 0x00cf93000000ffff // flat 32-bit data segment
152gdt32_end:
153
154.code16
155sipi_entry:
156	mov %cr0, %eax
157	or $1, %eax
158	mov %eax, %cr0
159	lgdtl gdt32_descr - sipi_entry
160	ljmpl $8, $ap_start32
161
162gdt32_descr:
163	.word gdt32_end - gdt32 - 1
164	.long gdt32
165
166sipi_end:
167
168.code32
169ap_start32:
170	mov $0x10, %ax
171	mov %ax, %ds
172	mov %ax, %es
173	mov %ax, %fs
174	mov %ax, %gs
175	mov %ax, %ss
176	mov $-4096, %esp
177	lock/xaddl %esp, smp_stacktop
178	setup_percpu_area
179	call prepare_64
180	ljmpl $8, $ap_start64
181
182.code64
183ap_start64:
184	call load_tss
185	call enable_apic
186	call enable_x2apic
187	sti
188	nop
189	lock incw cpu_online_count
190
1911:	hlt
192	jmp 1b
193
194start64:
195	call load_tss
196	call mask_pic_interrupts
197	call enable_apic
198	call smp_init
199	call enable_x2apic
200	mov mb_boot_info(%rip), %rax
201	mov mb_cmdline(%rax), %rax
202	mov %rax, __args(%rip)
203	call __setup_args
204	mov __argc(%rip), %edi
205	lea __argv(%rip), %rsi
206	call main
207	mov %eax, %edi
208	call exit
209
210idt_descr:
211	.word 16 * 256 - 1
212	.quad boot_idt
213
214load_tss:
215	lidtq idt_descr
216	mov $0, %eax
217	mov %ax, %ss
218	mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
219	mov (%rax), %eax
220	shr $24, %eax
221	mov %eax, %ebx
222	shl $4, %ebx
223	mov $((tss_end - tss) / max_cpus), %edx
224	imul %edx
225	add $tss, %rax
226	mov %ax, tss_descr+2(%rbx)
227	shr $16, %rax
228	mov %al, tss_descr+4(%rbx)
229	shr $8, %rax
230	mov %al, tss_descr+7(%rbx)
231	shr $8, %rax
232	mov %eax, tss_descr+8(%rbx)
233	lea tss_descr-gdt64(%rbx), %rax
234	ltr %ax
235	ret
236
237smp_init:
238	cld
239	lea sipi_entry, %rsi
240	xor %rdi, %rdi
241	mov $(sipi_end - sipi_entry), %rcx
242	rep/movsb
243	mov $APIC_DEFAULT_PHYS_BASE, %eax
244	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%rax)
245	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%rax)
246	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%rax)
247	call fwcfg_get_nb_cpus
2481:	pause
249	cmpw %ax, cpu_online_count
250	jne 1b
251smp_init_done:
252	ret
253
254cpu_online_count:	.word 1
255