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