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