xref: /kvm-unit-tests/x86/cstart.S (revision d3aacb4f57d05f74f2030dbe12e7dfd6aa1b273d)
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
24pt:
25i = 0
26        .rept 1024
27        .long 0x1e7 | (i << 22)
28        i = i + 1
29        .endr
30
31.globl gdt32
32gdt32:
33	.quad 0
34	.quad 0x00cf9b000000ffff // flat 32-bit code segment
35	.quad 0x00cf93000000ffff // flat 32-bit data segment
36	.quad 0x00cf1b000000ffff // flat 32-bit code segment, not present
37	.quad 0x00cffb000000ffff // 64-bit code segment (user)
38	.quad 0x00cff3000000ffff // 64-bit data segment (user)
39
40	.quad 0			 // 10 spare selectors
41	.quad 0
42	.quad 0
43	.quad 0
44	.quad 0
45	.quad 0
46	.quad 0
47	.quad 0
48	.quad 0
49	.quad 0
50
51tss_descr:
52        .rept max_cpus
53        .quad 0x000089000000ffff // 32-bit avail tss
54        .endr
55gdt32_end:
56
57i = 0
58.globl tss
59tss:
60        .rept max_cpus
61        .long 0
62        .long ring0stacktop - i * 4096
63        .long 16
64        .quad 0, 0
65        .quad 0, 0, 0, 0, 0, 0, 0, 0
66        .long 0, 0, 0
67        i = i + 1
68        .endr
69tss_end:
70
71idt_descr:
72	.word 16 * 256 - 1
73	.long boot_idt
74
75.section .init
76
77.code32
78
79mb_magic = 0x1BADB002
80mb_flags = 0x0
81
82	# multiboot header
83	.long mb_magic, mb_flags, 0 - (mb_magic + mb_flags)
84mb_cmdline = 16
85
86MSR_GS_BASE = 0xc0000101
87
88.macro setup_percpu_area
89	lea -4096(%esp), %eax
90	mov $0, %edx
91	mov $MSR_GS_BASE, %ecx
92	wrmsr
93.endm
94
95.globl start
96start:
97        mov mb_cmdline(%ebx), %eax
98        mov %eax, __args
99        call __setup_args
100        mov $stacktop, %esp
101        setup_percpu_area
102        call prepare_32
103        jmpl $8, $start32
104
105prepare_32:
106        lgdtl gdt32_descr
107
108	mov %cr4, %eax
109	bts $4, %eax  // pse
110	mov %eax, %cr4
111
112	mov $pt, %eax
113	mov %eax, %cr3
114
115	mov %cr0, %eax
116	bts $0, %eax
117	bts $31, %eax
118	mov %eax, %cr0
119	ret
120
121smp_stacktop:	.long 0xa0000
122
123ap_start32:
124	mov $0x10, %ax
125	mov %ax, %ds
126	mov %ax, %es
127	mov %ax, %fs
128	mov %ax, %gs
129	mov %ax, %ss
130	mov $-4096, %esp
131	lock/xaddl %esp, smp_stacktop
132	setup_percpu_area
133	call prepare_32
134	call load_tss
135	call enable_apic
136	call enable_x2apic
137	sti
138	nop
139	lock incw cpu_online_count
140
1411:	hlt
142	jmp 1b
143
144start32:
145	call load_tss
146	call mask_pic_interrupts
147	call enable_apic
148	call smp_init
149	call enable_x2apic
150        push $__argv
151        push __argc
152        call main
153	push %eax
154	call exit
155
156load_tss:
157	lidt idt_descr
158	mov $16, %eax
159	mov %ax, %ss
160	mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
161	mov (%eax), %eax
162	shr $24, %eax
163	mov %eax, %ebx
164	shl $3, %ebx
165	mov $((tss_end - tss) / max_cpus), %edx
166	imul %edx
167	add $tss, %eax
168	mov %ax, tss_descr+2(%ebx)
169	shr $16, %eax
170	mov %al, tss_descr+4(%ebx)
171	shr $8, %eax
172	mov %al, tss_descr+7(%ebx)
173	lea tss_descr-gdt32(%ebx), %eax
174	ltr %ax
175	ret
176
177smp_init:
178	cld
179	lea sipi_entry, %esi
180	xor %edi, %edi
181	mov $(sipi_end - sipi_entry), %ecx
182	rep/movsb
183	mov $APIC_DEFAULT_PHYS_BASE, %eax
184	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%eax)
185	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%eax)
186	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%eax)
187	call fwcfg_get_nb_cpus
1881:	pause
189	cmpw %ax, cpu_online_count
190	jne 1b
191smp_init_done:
192	ret
193
194cpu_online_count:	.word 1
195
196.code16
197sipi_entry:
198	mov %cr0, %eax
199	or $1, %eax
200	mov %eax, %cr0
201	lgdtl gdt32_descr - sipi_entry
202	ljmpl $8, $ap_start32
203
204gdt32_descr:
205	.word gdt32_end - gdt32 - 1
206	.long gdt32
207
208sipi_end:
209