xref: /kvm-unit-tests/x86/cstart.S (revision c604fa931a1cb70c3649ac1b7223178fc79eab6a)
1
2#include "apic-defs.h"
3
4.global online_cpus
5
6ipi_vector = 0x20
7
8max_cpus = MAX_TEST_CPUS
9
10.bss
11
12	. = . + 4096 * max_cpus
13	.align 16
14stacktop:
15
16.data
17
18.align 4096
19pt:
20i = 0
21        .rept 1024
22        .long 0x1e7 | (i << 22)
23        i = i + 1
24        .endr
25
26.section .init
27
28.code32
29
30mb_magic = 0x1BADB002
31mb_flags = 0x0
32
33	# multiboot header
34	.long mb_magic, mb_flags, 0 - (mb_magic + mb_flags)
35mb_cmdline = 16
36
37.macro setup_tr_and_percpu
38	lidt idt_descr
39	push %esp
40	call setup_tss
41	addl $4, %esp
42	ltr %ax
43	add $(max_cpus * 8), %ax
44	mov %ax, %gs
45.endm
46
47.macro setup_segments
48	mov $0x10, %ax
49	mov %ax, %ds
50	mov %ax, %es
51	mov %ax, %fs
52	mov %ax, %gs
53	mov %ax, %ss
54.endm
55
56.globl start
57start:
58        lgdtl gdt_descr
59        setup_segments
60        mov $stacktop, %esp
61
62        push %ebx
63        call setup_multiboot
64        addl $4, %esp
65        call setup_libcflat
66        mov mb_cmdline(%ebx), %eax
67        mov %eax, __args
68        call __setup_args
69        call prepare_32
70        jmpl $8, $start32
71
72prepare_32:
73	mov $(1 << 4), %eax // pse
74	mov %eax, %cr4
75
76	mov $pt, %eax
77	mov %eax, %cr3
78
79	mov %cr0, %eax
80	bts $0, %eax
81	bts $31, %eax
82	mov %eax, %cr0
83	ret
84
85smp_stacktop:	.long stacktop - 4096
86
87save_id:
88	movl $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
89	movl (%eax), %eax
90	shrl $24, %eax
91	lock btsl %eax, online_cpus
92	retl
93
94ap_start32:
95	setup_segments
96	mov $-4096, %esp
97	lock xaddl %esp, smp_stacktop
98	setup_tr_and_percpu
99	call prepare_32
100	call reset_apic
101	call save_id
102	call enable_apic
103	call enable_x2apic
104	sti
105	nop
106	lock incw cpu_online_count
107
1081:	hlt
109	jmp 1b
110
111start32:
112	setup_tr_and_percpu
113	call reset_apic
114	call save_id
115	call mask_pic_interrupts
116	call enable_apic
117	call ap_init
118	call enable_x2apic
119	call smp_init
120        push $__environ
121        push $__argv
122        push __argc
123        call main
124	push %eax
125	call exit
126
127ap_init:
128	cld
129	sgdtl ap_gdt_descr // must be close to sipi_entry for real mode access to work
130	lea sipi_entry, %esi
131	xor %edi, %edi
132	mov $(sipi_end - sipi_entry), %ecx
133	rep movsb
134	mov $APIC_DEFAULT_PHYS_BASE, %eax
135	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%eax)
136	movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%eax)
137	call fwcfg_get_nb_cpus
1381:	pause
139	cmpw %ax, cpu_online_count
140	jne 1b
141	ret
142
143online_cpus:
144	.fill (max_cpus + 7) / 8, 1, 0
145
146.align 2
147cpu_online_count:	.word 1
148
149.code16
150sipi_entry:
151	mov %cr0, %eax
152	or $1, %eax
153	mov %eax, %cr0
154	lgdtl ap_gdt_descr - sipi_entry
155	ljmpl $8, $ap_start32
156
157ap_gdt_descr:
158	.word 0
159	.long 0
160
161sipi_end:
162