Set max virtual processor to 4 for ia64
[qemu-kvm/amd-iommu.git] / kvm / bios / vapic.S
blob16e5cc441de4b4b3e5ffc1b159c8623e6623b0ce
1         .text
2         .code32
3         .align 4096
5 vapic_size = 2*4096
7 .macro fixup delta=-4
8 777:
9         .pushsection .fixup, "a"
10         .long 777b + \delta  - vapic_base
11         .popsection
12 .endm
14 vapic_base:
15         .ascii "kvm aPiC"
17         /* relocation data */
18         .long vapic_base        ; fixup
19         .long fixup_start       ; fixup
20         .long fixup_end         ; fixup
22         .long vapic             ; fixup
23         .long vapic_size
24 vcpu_shift:
25         .long 0
26 real_tpr:
27         .long 0
28         .long set_tpr           ; fixup
29         .long set_tpr_eax       ; fixup
30         .long get_tpr_eax       ; fixup
31         .long get_tpr_ecx       ; fixup
32         .long get_tpr_edx       ; fixup
33         .long get_tpr_ebx       ; fixup
34         .long 0 /* esp. won't work. */
35         .long get_tpr_ebp       ; fixup
36         .long get_tpr_esi       ; fixup
37         .long get_tpr_edi       ; fixup
39 .macro kvm_hypercall
40         .byte 0x0f, 0x01, 0xc1
41 .endm
43 kvm_hypercall_vapic_poll_irq = 1
45 tr_vcpu_signature = 0xdb
47 .align 64
49 get_tpr_eax:
50         pushf
51         push %ecx
53         str %eax
54         cmp $tr_vcpu_signature, %al
55         jne get_tpr_bad
56         movzbl %ah, %eax
58         mov vcpu_shift, %ecx    ; fixup
59         shl %cl, %eax
60         movzbl vapic(%eax), %eax ; fixup
62 get_tpr_out:
63         pop %ecx
64         popf
65         ret
67 get_tpr_bad:
68         mov real_tpr, %eax      ; fixup
69         mov (%eax), %eax
70         jmp get_tpr_out
72 get_tpr_ebx:
73         mov %eax, %ebx
74         call get_tpr_eax
75         xchg %eax, %ebx
76         ret
78 get_tpr_ecx:
79         mov %eax, %ecx
80         call get_tpr_eax
81         xchg %eax, %ecx
82         ret
84 get_tpr_edx:
85         mov %eax, %edx
86         call get_tpr_eax
87         xchg %eax, %edx
88         ret
90 get_tpr_esi:
91         mov %eax, %esi
92         call get_tpr_eax
93         xchg %eax, %esi
94         ret
96 get_tpr_edi:
97         mov %eax, %edi
98         call get_tpr_edi
99         xchg %eax, %edi
100         ret
102 get_tpr_ebp:
103         mov %eax, %ebp
104         call get_tpr_eax
105         xchg %eax, %ebp
106         ret
108 set_tpr_eax:
109         push %eax
110         call set_tpr
111         ret
113 set_tpr:
114         pushf
115         push %eax
116         push %ecx
117         push %edx
118         push %ebx
120 set_tpr_failed:
121         str %eax
122         cmp $tr_vcpu_signature, %al
123         jne set_tpr_bad
124         movzbl %ah, %edx
126         mov vcpu_shift, %ecx    ; fixup
127         shl %cl, %edx
129         mov vapic(%edx), %eax   ; fixup
131         mov %eax, %ebx
132         mov 24(%esp), %bl
134         /* %ebx = new vapic (%bl = tpr, %bh = isr, %b3 = irr) */
136         lock cmpxchg %ebx, vapic(%edx) ; fixup
137         jnz set_tpr_failed
139         /* compute ppr */
140         cmp %bh, %bl
141         jae tpr_is_bigger
142 isr_is_bigger:
143         mov %bh, %bl
144 tpr_is_bigger:
145         /* %bl = ppr */
146         mov %bl, %ch   /* ch = ppr */
147         rol $8, %ebx
148         /* now: %bl = irr, %bh = ppr */
149         cmp %bh, %bl
150         ja set_tpr_poll_irq
152 set_tpr_out:
153         pop %ebx
154         pop %edx
155         pop %ecx
156         pop %eax
157         popf
158         ret $4
160 set_tpr_poll_irq:
161         mov $kvm_hypercall_vapic_poll_irq, %eax
162         kvm_hypercall
163         jmp set_tpr_out
165 set_tpr_bad:
166         mov 24(%esp), %ecx
167         mov real_tpr, %eax      ; fixup
168         mov %ecx, (%eax)
169         jmp set_tpr_out
171 .align 4096
173  * vapic format:
174  *  per-vcpu records of size 2^vcpu shift.
175  *     byte 0: tpr (r/w)
176  *     byte 1: highest in-service interrupt (isr) (r/o); bits 3:0 are zero
177  *     byte 2: zero (r/o)
178  *     byte 3: highest pending interrupt (irr) (r/o)
179  */
180 vapic:
181 . = . + vapic_size