kvm: testsuite: add tests for short/near Jcc and call instruction emulation
[kvm-userspace.git] / user / test / x86 / bootstrap.S
blobe32fea90cafd974e76f7eac2b5a701be4a91e672
1 /*
2  * minimal bootstrap to set up flat 32-bit protected mode
3  */
5 #include "fake-apic.h"
6         
7 bstart = 0xf0000
8         
9 .code16
11 stack_top = 0x1000
12 cpu_up = 0x1000
13 cpu_up_pmode = 0x1004
15 pmode_stack_start = 0x10000
16 pmode_stack_shift = 16
17 pmode_stack_size = (1 << pmode_stack_shift)
19 ipi_vec = 0xf0
20         
21 start:
22         mov $stack_top, %sp
23         call smp_init
25         cs lidtl idt_desc
26         cs lgdtl gdt_desc
27         mov %cr0, %eax
28         or $1, %eax
29         mov %eax, %cr0
30         ljmpl $8, $pmode + bstart
32 smp_init:
33         mov $ipi_vec, %eax
34         mov $(APIC_BASE + APIC_REG_IPI_VECTOR), %dx
35         out %eax, %dx
36         movw $ap_switch_to_pmode, ipi_vec*4
37         movw %cs, %ax
38         mov %ax, ipi_vec*4+2
39         mov $sipi, %eax
40         mov $(APIC_BASE + APIC_REG_SIPI_ADDR), %dx
41         outl %eax, %dx
42         mov $(APIC_BASE + APIC_REG_NCPU), %dx
43         inl %dx, %eax
44         mov %eax, %ecx
45         mov $1, %esi
46 smp_loop:
47         cmp %esi, %ecx
48         jbe smp_done
49         mov %esi, %eax
50         mov $(APIC_BASE + APIC_REG_SEND_SIPI), %dx
51         outl %eax, %dx
52 wait_for_cpu:
53         cmp cpu_up, %esi
54         jne wait_for_cpu
55         mov %esi, %eax
56         mov $(APIC_BASE + APIC_REG_SEND_IPI), %dx
57         out %eax, %dx
58 wait_for_cpu_pmode:
59         cmp cpu_up_pmode, %esi
60         jne wait_for_cpu_pmode
61         
62         inc %esi
63         jmp smp_loop
64 smp_done:
65         ret
67 sipi:
68         mov $(APIC_BASE + APIC_REG_ID), %dx
69         inl %dx, %eax
70         mov %eax, cpu_up
71         shl $12, %eax
72         addl $stack_top, %eax
73         movl %eax, %esp
74         sti
75         nop
76 1:      hlt
77         jmp 1b
79 ap_switch_to_pmode:
80         cs lidtl idt_desc
81         cs lgdtl gdt_desc
82         mov %cr0, %eax
83         or $1, %eax
84         mov %eax, %cr0
85         ljmpl $8, $ap_pmode + bstart
87 .code32 
88 ap_pmode:
89         mov $0x10, %ax
90         mov %ax, %ds
91         mov %ax, %es
92         mov %ax, %fs
93         mov %ax, %gs
94         mov %ax, %ss
95         mov $(APIC_BASE + APIC_REG_ID), %dx
96         in %dx, %eax
97         mov %eax, cpu_up_pmode
98         shl $pmode_stack_shift, %eax
99         lea pmode_stack_start + pmode_stack_size(%eax), %esp
100         sti
101         nop
102 ap_pmode_wait:
103         hlt
104         jmp ap_pmode_wait
106 pmode:
107         mov $0x10, %ax
108         mov %ax, %ds
109         mov %ax, %es
110         mov %ax, %fs
111         mov %ax, %gs
112         mov %ax, %ss
113         mov $pmode_stack_start + pmode_stack_size, %esp
114         ljmp $8, $0x100000
116 .align 16
117         
118 idt_desc:
119         .word 8*256-1
120         .long 0
122 gdt_desc:
123         .word gdt_end - gdt - 1
124         .long gdt + bstart
126 .align 16
128 gdt:
129         .quad 0
130         .quad 0x00cf9b000000ffff // flat 32-bit code segment
131         .quad 0x00cf93000000ffff // flat 32-bit data segment
132 gdt_end:
133         
134 . = 0xfff0
135         .code16
136         ljmp $0xf000, $start
137 .align 65536