xref: /kvm-unit-tests/x86/cstart.S (revision 4363f1d9a646a5c7ea673bee8fc33ca6f2cddbd8)
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 0                  // TSS for task gates
38	.quad 0x008f9b000000FFFF // 16-bit code segment
39	.quad 0x008f93000000FFFF // 16-bit data segment
40	.quad 0x00cffb000000ffff // 32-bit code segment (user)
41	.quad 0x00cff3000000ffff // 32-bit data segment (user)
42	.quad 0                  // unused
43
44	.quad 0			 // 6 spare selectors
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        push %ebx
98        call setup_multiboot
99        call setup_libcflat
100        mov mb_cmdline(%ebx), %eax
101        mov %eax, __args
102        call __setup_args
103        mov $stacktop, %esp
104        setup_percpu_area
105        call prepare_32
106        jmpl $8, $start32
107
108prepare_32:
109        lgdtl gdt32_descr
110
111	mov %cr4, %eax
112	bts $4, %eax  // pse
113	mov %eax, %cr4
114
115	mov $pt, %eax
116	mov %eax, %cr3
117
118	mov %cr0, %eax
119	bts $0, %eax
120	bts $31, %eax
121	mov %eax, %cr0
122	ret
123
124smp_stacktop:	.long 0xa0000
125
126ap_start32:
127	mov $0x10, %ax
128	mov %ax, %ds
129	mov %ax, %es
130	mov %ax, %fs
131	mov %ax, %gs
132	mov %ax, %ss
133	mov $-4096, %esp
134	lock/xaddl %esp, smp_stacktop
135	setup_percpu_area
136	call prepare_32
137	call load_tss
138	call enable_apic
139	call enable_x2apic
140	sti
141	nop
142	lock incw cpu_online_count
143
1441:	hlt
145	jmp 1b
146
147start32:
148	call load_tss
149	call mask_pic_interrupts
150	call enable_apic
151	call smp_init
152	call enable_x2apic
153        push $__environ
154        push $__argv
155        push __argc
156        call main
157	push %eax
158	call exit
159
160load_tss:
161	lidt idt_descr
162	mov $16, %eax
163	mov %ax, %ss
164	mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
165	mov (%eax), %eax
166	shr $24, %eax
167	mov %eax, %ebx
168	shl $3, %ebx
169	mov $((tss_end - tss) / max_cpus), %edx
170	imul %edx
171	add $tss, %eax
172	mov %ax, tss_descr+2(%ebx)
173	shr $16, %eax
174	mov %al, tss_descr+4(%ebx)
175	shr $8, %eax
176	mov %al, tss_descr+7(%ebx)
177	lea tss_descr-gdt32(%ebx), %eax
178	ltr %ax
179	ret
180
181smp_init:
182	cld
183	lea sipi_entry, %esi
184	xor %edi, %edi
185	mov $(sipi_end - sipi_entry), %ecx
186	rep/movsb
187	mov $APIC_DEFAULT_PHYS_BASE, %eax
188	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%eax)
189	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%eax)
190	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%eax)
191	call fwcfg_get_nb_cpus
1921:	pause
193	cmpw %ax, cpu_online_count
194	jne 1b
195smp_init_done:
196	ret
197
198cpu_online_count:	.word 1
199
200.code16
201sipi_entry:
202	mov %cr0, %eax
203	or $1, %eax
204	mov %eax, %cr0
205	lgdtl gdt32_descr - sipi_entry
206	ljmpl $8, $ap_start32
207
208gdt32_descr:
209	.word gdt32_end - gdt32 - 1
210	.long gdt32
211
212sipi_end:
213