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