Fix apic build with kvm disabled
[qemu/qemu-dev-zwu.git] / kvm / test / x86 / cstart64.S
blob46e9d5cd48a9dba96bd381f7d448a77af2a42314
2 #include "apic-defs.h"
4 .globl boot_idt
5 boot_idt = 0
7 ipi_vector = 0x20
9 max_cpus = 4
11 .bss
13         . = . + 4096 * max_cpus
14         .align 16
15 stacktop:
17         . = . + 4096
18         .align 16
19 ring0stacktop:
21 .data
22                 
23 .align 4096
24 ptl2:
25 i = 0
26         .rept 512 * 4
27         .quad 0x1e7 | (i << 21)
28         i = i + 1
29         .endr
31 .align 4096
32 ptl3:
33         .quad ptl2 + 7 + 0 * 4096
34         .quad ptl2 + 7 + 1 * 4096
35         .quad ptl2 + 7 + 2 * 4096
36         .quad ptl2 + 7 + 3 * 4096
38 .align 4096
39 ptl4:
40         .quad ptl3 + 7
41         
42 .align 4096
44 gdt64_desc:
45         .word gdt64_end - gdt64 - 1
46         .quad gdt64
48 gdt64:
49         .quad 0
50         .quad 0x00af9b000000ffff // 64-bit code segment
51         .quad 0x00cf93000000ffff // 64-bit data segment
52         .quad 0x00affb000000ffff // 64-bit code segment (user)
53         .quad 0x00cff3000000ffff // 64-bit data segment (user)
54         .quad 0x00cf9b000000ffff // 32-bit code segment
55         .quad 0x00cf92000000ffff // 32-bit code segment
56         .quad 0x008F9A000000FFFF // 16-bit code segment
57         .quad 0x008F92000000FFFF // 16-bit data segment
59 tss_descr:
60         .rept max_cpus
61         .quad 0x000089000000ffff // 64-bit avail tss
62         .quad 0                  // tss high addr
63         .endr
64 gdt64_end:
66 i = 0
67 tss:
68         .rept max_cpus
69         .long 0
70         .quad ring0stacktop - i * 4096
71         .quad 0, 0, 0
72         .quad 0, 0, 0, 0, 0, 0, 0, 0
73         .long 0, 0, 0
74 i = i + 1
75         .endr
76 tss_end:
78 .section .init
80 .code32
82 mb_magic = 0x1BADB002
83 mb_flags = 0x0
85         # multiboot header
86         .long mb_magic, mb_flags, 0 - (mb_magic + mb_flags)
88 MSR_GS_BASE = 0xc0000101
90 .macro setup_percpu_area
91         lea -4096(%esp), %eax
92         mov $0, %edx
93         mov $MSR_GS_BASE, %ecx
94         wrmsr
95 .endm
97 .globl start
98 start:
99         mov $stacktop, %esp
100         setup_percpu_area
101         call prepare_64
102         jmpl $8, $start64
104 prepare_64:
105         lgdt gdt64_desc
107         mov %cr4, %eax
108         bts $5, %eax  // pae
109         mov %eax, %cr4
111         mov $ptl4, %eax
112         mov %eax, %cr3
114 efer = 0xc0000080
115         mov $efer, %ecx
116         rdmsr
117         bts $8, %eax
118         wrmsr
120         mov %cr0, %eax
121         bts $0, %eax
122         bts $31, %eax
123         mov %eax, %cr0
124         ret
126 smp_stacktop:   .long 0xa0000
128 .align 16
130 gdt32:
131         .quad 0
132         .quad 0x00cf9b000000ffff // flat 32-bit code segment
133         .quad 0x00cf93000000ffff // flat 32-bit data segment
134 gdt32_end:
136 .code16
137 sipi_entry:
138         mov %cr0, %eax
139         or $1, %eax
140         mov %eax, %cr0
141         lgdtl gdt32_descr - sipi_entry
142         ljmpl $8, $ap_start32
144 gdt32_descr:
145         .word gdt32_end - gdt32 - 1
146         .long gdt32
148 sipi_end:
150 .code32
151 ap_start32:
152         mov $0x10, %ax
153         mov %ax, %ds
154         mov %ax, %es
155         mov %ax, %fs
156         mov %ax, %gs
157         mov %ax, %ss
158         mov $-4096, %esp
159         lock/xaddl %esp, smp_stacktop
160         setup_percpu_area
161         call prepare_64
162         ljmpl $8, $ap_start64
164 .code64
165 ap_start64:
166         call load_tss
167         call enable_apic
168         call enable_x2apic
169         sti
170         nop
171         lock incw cpu_online_count
173 1:      hlt
174         jmp 1b
176 start64:
177         call load_tss
178         call mask_pic_interrupts
179         call enable_apic
180         call smp_init
181         call enable_x2apic
182         call main
183         mov %eax, %edi
184         call exit
186 idt_descr:
187         .word 16 * 256 - 1
188         .quad boot_idt
190 load_tss:
191         lidtq idt_descr
192         mov $0, %eax
193         mov %ax, %ss
194         mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
195         mov (%rax), %eax
196         shr $24, %eax
197         mov %eax, %ebx
198         shl $4, %ebx
199         mov $((tss_end - tss) / max_cpus), %edx
200         imul %edx
201         add $tss, %rax
202         mov %ax, tss_descr+2(%rbx)
203         shr $16, %rax
204         mov %al, tss_descr+4(%rbx)
205         shr $8, %rax
206         mov %al, tss_descr+7(%rbx)
207         shr $8, %rax
208         mov %eax, tss_descr+8(%rbx)
209         lea tss_descr-gdt64(%rbx), %rax
210         ltr %ax
211         ret
213 smp_init:
214         cld
215         lea sipi_entry, %rsi
216         xor %rdi, %rdi
217         mov $(sipi_end - sipi_entry), %rcx
218         rep/movsb
219         mov $APIC_DEFAULT_PHYS_BASE, %eax
220         movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%rax)
221         movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%rax)
222         movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%rax)
223         call fwcfg_get_nb_cpus
224 1:      pause
225         cmpw %ax, cpu_online_count
226         jne 1b
227 smp_init_done:
228         ret
230 cpu_online_count:       .word 1