1 | /*
|
---|
2 | * i386 virtual CPU header
|
---|
3 | *
|
---|
4 | * Copyright (c) 2003 Fabrice Bellard
|
---|
5 | *
|
---|
6 | * This library is free software; you can redistribute it and/or
|
---|
7 | * modify it under the terms of the GNU Lesser General Public
|
---|
8 | * License as published by the Free Software Foundation; either
|
---|
9 | * version 2 of the License, or (at your option) any later version.
|
---|
10 | *
|
---|
11 | * This library is distributed in the hope that it will be useful,
|
---|
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
14 | * Lesser General Public License for more details.
|
---|
15 | *
|
---|
16 | * You should have received a copy of the GNU Lesser General Public
|
---|
17 | * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
---|
18 | */
|
---|
19 |
|
---|
20 | /*
|
---|
21 | * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
|
---|
22 | * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
|
---|
23 | * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
|
---|
24 | * a choice of LGPL license versions is made available with the language indicating
|
---|
25 | * that LGPLv2 or any later version may be used, or where a choice of which version
|
---|
26 | * of the LGPL is applied is otherwise unspecified.
|
---|
27 | */
|
---|
28 |
|
---|
29 | #ifndef CPU_I386_H
|
---|
30 | #define CPU_I386_H
|
---|
31 |
|
---|
32 | #include "config.h"
|
---|
33 |
|
---|
34 | #ifdef TARGET_X86_64
|
---|
35 | #define TARGET_LONG_BITS 64
|
---|
36 | #else
|
---|
37 | #define TARGET_LONG_BITS 32
|
---|
38 | #endif
|
---|
39 |
|
---|
40 | /* target supports implicit self modifying code */
|
---|
41 | #define TARGET_HAS_SMC
|
---|
42 | /* support for self modifying code even if the modified instruction is
|
---|
43 | close to the modifying instruction */
|
---|
44 | #define TARGET_HAS_PRECISE_SMC
|
---|
45 |
|
---|
46 | #define TARGET_HAS_ICE 1
|
---|
47 |
|
---|
48 | #ifdef TARGET_X86_64
|
---|
49 | #define ELF_MACHINE EM_X86_64
|
---|
50 | #else
|
---|
51 | #define ELF_MACHINE EM_386
|
---|
52 | #endif
|
---|
53 |
|
---|
54 | #define CPUState struct CPUX86State
|
---|
55 |
|
---|
56 | #include "cpu-defs.h"
|
---|
57 |
|
---|
58 | #include "softfloat.h"
|
---|
59 |
|
---|
60 | #ifdef VBOX
|
---|
61 | # include <iprt/critsect.h>
|
---|
62 | # include <iprt/thread.h>
|
---|
63 | # include <iprt/assert.h>
|
---|
64 | # include <iprt/asm.h>
|
---|
65 | # include <VBox/vmm/vmm.h>
|
---|
66 | # include <VBox/vmm/stam.h>
|
---|
67 | # include <VBox/vmm/cpumctx.h>
|
---|
68 | # undef MSR_IA32_APICBASE_BSP
|
---|
69 | #endif /* VBOX */
|
---|
70 |
|
---|
71 | #define R_EAX 0
|
---|
72 | #define R_ECX 1
|
---|
73 | #define R_EDX 2
|
---|
74 | #define R_EBX 3
|
---|
75 | #define R_ESP 4
|
---|
76 | #define R_EBP 5
|
---|
77 | #define R_ESI 6
|
---|
78 | #define R_EDI 7
|
---|
79 |
|
---|
80 | #define R_AL 0
|
---|
81 | #define R_CL 1
|
---|
82 | #define R_DL 2
|
---|
83 | #define R_BL 3
|
---|
84 | #define R_AH 4
|
---|
85 | #define R_CH 5
|
---|
86 | #define R_DH 6
|
---|
87 | #define R_BH 7
|
---|
88 |
|
---|
89 | #define R_ES 0
|
---|
90 | #define R_CS 1
|
---|
91 | #define R_SS 2
|
---|
92 | #define R_DS 3
|
---|
93 | #define R_FS 4
|
---|
94 | #define R_GS 5
|
---|
95 |
|
---|
96 | /* segment descriptor fields */
|
---|
97 | #define DESC_G_MASK (1 << 23)
|
---|
98 | #define DESC_B_SHIFT 22
|
---|
99 | #define DESC_B_MASK (1 << DESC_B_SHIFT)
|
---|
100 | #define DESC_L_SHIFT 21 /* x86_64 only : 64 bit code segment */
|
---|
101 | #define DESC_L_MASK (1 << DESC_L_SHIFT)
|
---|
102 | #define DESC_AVL_MASK (1 << 20)
|
---|
103 | #define DESC_P_MASK (1 << 15)
|
---|
104 | #define DESC_DPL_SHIFT 13
|
---|
105 | #define DESC_DPL_MASK (3 << DESC_DPL_SHIFT)
|
---|
106 | #define DESC_S_MASK (1 << 12)
|
---|
107 | #define DESC_TYPE_SHIFT 8
|
---|
108 | #define DESC_TYPE_MASK (15 << DESC_TYPE_SHIFT)
|
---|
109 | #define DESC_A_MASK (1 << 8)
|
---|
110 |
|
---|
111 | #define DESC_CS_MASK (1 << 11) /* 1=code segment 0=data segment */
|
---|
112 | #define DESC_C_MASK (1 << 10) /* code: conforming */
|
---|
113 | #define DESC_R_MASK (1 << 9) /* code: readable */
|
---|
114 |
|
---|
115 | #define DESC_E_MASK (1 << 10) /* data: expansion direction */
|
---|
116 | #define DESC_W_MASK (1 << 9) /* data: writable */
|
---|
117 |
|
---|
118 | #define DESC_TSS_BUSY_MASK (1 << 9)
|
---|
119 | #ifdef VBOX
|
---|
120 | # define DESC_INTEL_UNUSABLE RT_BIT_32(16+8) /**< Internal VT-x bit for NULL sectors. */
|
---|
121 | # define DESC_RAW_FLAG_BITS UINT32_C(0x00ffffff) /**< Flag bits we load from the descriptor. */
|
---|
122 | #endif
|
---|
123 |
|
---|
124 | /* eflags masks */
|
---|
125 | #define CC_C 0x0001
|
---|
126 | #define CC_P 0x0004
|
---|
127 | #define CC_A 0x0010
|
---|
128 | #define CC_Z 0x0040
|
---|
129 | #define CC_S 0x0080
|
---|
130 | #define CC_O 0x0800
|
---|
131 |
|
---|
132 | #define TF_SHIFT 8
|
---|
133 | #define IOPL_SHIFT 12
|
---|
134 | #define VM_SHIFT 17
|
---|
135 |
|
---|
136 | #define TF_MASK 0x00000100
|
---|
137 | #define IF_MASK 0x00000200
|
---|
138 | #define DF_MASK 0x00000400
|
---|
139 | #define IOPL_MASK 0x00003000
|
---|
140 | #define NT_MASK 0x00004000
|
---|
141 | #define RF_MASK 0x00010000
|
---|
142 | #define VM_MASK 0x00020000
|
---|
143 | #define AC_MASK 0x00040000
|
---|
144 | #define VIF_MASK 0x00080000
|
---|
145 | #define VIP_MASK 0x00100000
|
---|
146 | #define ID_MASK 0x00200000
|
---|
147 |
|
---|
148 | /* hidden flags - used internally by qemu to represent additional cpu
|
---|
149 | states. Only the CPL, INHIBIT_IRQ, SMM and SVMI are not
|
---|
150 | redundant. We avoid using the IOPL_MASK, TF_MASK and VM_MASK bit
|
---|
151 | position to ease oring with eflags. */
|
---|
152 | /* current cpl */
|
---|
153 | #define HF_CPL_SHIFT 0
|
---|
154 | /* true if soft mmu is being used */
|
---|
155 | #define HF_SOFTMMU_SHIFT 2
|
---|
156 | /* true if hardware interrupts must be disabled for next instruction */
|
---|
157 | #define HF_INHIBIT_IRQ_SHIFT 3
|
---|
158 | /* 16 or 32 segments */
|
---|
159 | #define HF_CS32_SHIFT 4
|
---|
160 | #define HF_SS32_SHIFT 5
|
---|
161 | /* zero base for DS, ES and SS : can be '0' only in 32 bit CS segment */
|
---|
162 | #define HF_ADDSEG_SHIFT 6
|
---|
163 | /* copy of CR0.PE (protected mode) */
|
---|
164 | #define HF_PE_SHIFT 7
|
---|
165 | #define HF_TF_SHIFT 8 /* must be same as eflags */
|
---|
166 | #define HF_MP_SHIFT 9 /* the order must be MP, EM, TS */
|
---|
167 | #define HF_EM_SHIFT 10
|
---|
168 | #define HF_TS_SHIFT 11
|
---|
169 | #define HF_IOPL_SHIFT 12 /* must be same as eflags */
|
---|
170 | #define HF_LMA_SHIFT 14 /* only used on x86_64: long mode active */
|
---|
171 | #define HF_CS64_SHIFT 15 /* only used on x86_64: 64 bit code segment */
|
---|
172 | #define HF_RF_SHIFT 16 /* must be same as eflags */
|
---|
173 | #define HF_VM_SHIFT 17 /* must be same as eflags */
|
---|
174 | #define HF_SMM_SHIFT 19 /* CPU in SMM mode */
|
---|
175 | #define HF_SVME_SHIFT 20 /* SVME enabled (copy of EFER.SVME) */
|
---|
176 | #define HF_SVMI_SHIFT 21 /* SVM intercepts are active */
|
---|
177 | #define HF_OSFXSR_SHIFT 22 /* CR4.OSFXSR */
|
---|
178 |
|
---|
179 | #define HF_CPL_MASK (3 << HF_CPL_SHIFT)
|
---|
180 | #define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT)
|
---|
181 | #define HF_INHIBIT_IRQ_MASK (1 << HF_INHIBIT_IRQ_SHIFT)
|
---|
182 | #define HF_CS32_MASK (1 << HF_CS32_SHIFT)
|
---|
183 | #define HF_SS32_MASK (1 << HF_SS32_SHIFT)
|
---|
184 | #define HF_ADDSEG_MASK (1 << HF_ADDSEG_SHIFT)
|
---|
185 | #define HF_PE_MASK (1 << HF_PE_SHIFT)
|
---|
186 | #define HF_TF_MASK (1 << HF_TF_SHIFT)
|
---|
187 | #define HF_MP_MASK (1 << HF_MP_SHIFT)
|
---|
188 | #define HF_EM_MASK (1 << HF_EM_SHIFT)
|
---|
189 | #define HF_TS_MASK (1 << HF_TS_SHIFT)
|
---|
190 | #define HF_IOPL_MASK (3 << HF_IOPL_SHIFT)
|
---|
191 | #define HF_LMA_MASK (1 << HF_LMA_SHIFT)
|
---|
192 | #define HF_CS64_MASK (1 << HF_CS64_SHIFT)
|
---|
193 | #define HF_RF_MASK (1 << HF_RF_SHIFT)
|
---|
194 | #define HF_VM_MASK (1 << HF_VM_SHIFT)
|
---|
195 | #define HF_SMM_MASK (1 << HF_SMM_SHIFT)
|
---|
196 | #define HF_SVME_MASK (1 << HF_SVME_SHIFT)
|
---|
197 | #define HF_SVMI_MASK (1 << HF_SVMI_SHIFT)
|
---|
198 | #define HF_OSFXSR_MASK (1 << HF_OSFXSR_SHIFT)
|
---|
199 |
|
---|
200 | /* hflags2 */
|
---|
201 |
|
---|
202 | #define HF2_GIF_SHIFT 0 /* if set CPU takes interrupts */
|
---|
203 | #define HF2_HIF_SHIFT 1 /* value of IF_MASK when entering SVM */
|
---|
204 | #define HF2_NMI_SHIFT 2 /* CPU serving NMI */
|
---|
205 | #define HF2_VINTR_SHIFT 3 /* value of V_INTR_MASKING bit */
|
---|
206 |
|
---|
207 | #define HF2_GIF_MASK (1 << HF2_GIF_SHIFT)
|
---|
208 | #define HF2_HIF_MASK (1 << HF2_HIF_SHIFT)
|
---|
209 | #define HF2_NMI_MASK (1 << HF2_NMI_SHIFT)
|
---|
210 | #define HF2_VINTR_MASK (1 << HF2_VINTR_SHIFT)
|
---|
211 |
|
---|
212 | #define CR0_PE_SHIFT 0
|
---|
213 | #define CR0_MP_SHIFT 1
|
---|
214 |
|
---|
215 | #define CR0_PE_MASK (1 << 0)
|
---|
216 | #define CR0_MP_MASK (1 << 1)
|
---|
217 | #define CR0_EM_MASK (1 << 2)
|
---|
218 | #define CR0_TS_MASK (1 << 3)
|
---|
219 | #define CR0_ET_MASK (1 << 4)
|
---|
220 | #define CR0_NE_MASK (1 << 5)
|
---|
221 | #define CR0_WP_MASK (1 << 16)
|
---|
222 | #define CR0_AM_MASK (1 << 18)
|
---|
223 | #define CR0_PG_MASK (1U << 31)
|
---|
224 |
|
---|
225 | #define CR4_VME_MASK (1 << 0)
|
---|
226 | #define CR4_PVI_MASK (1 << 1)
|
---|
227 | #define CR4_TSD_MASK (1 << 2)
|
---|
228 | #define CR4_DE_MASK (1 << 3)
|
---|
229 | #define CR4_PSE_MASK (1 << 4)
|
---|
230 | #define CR4_PAE_MASK (1 << 5)
|
---|
231 | #define CR4_MCE_MASK (1 << 6)
|
---|
232 | #define CR4_PGE_MASK (1 << 7)
|
---|
233 | #define CR4_PCE_MASK (1 << 8)
|
---|
234 | #define CR4_OSFXSR_SHIFT 9
|
---|
235 | #define CR4_OSFXSR_MASK (1 << CR4_OSFXSR_SHIFT)
|
---|
236 | #define CR4_OSXMMEXCPT_MASK (1 << 10)
|
---|
237 |
|
---|
238 | #define DR6_BD (1 << 13)
|
---|
239 | #define DR6_BS (1 << 14)
|
---|
240 | #define DR6_BT (1 << 15)
|
---|
241 | #define DR6_FIXED_1 0xffff0ff0
|
---|
242 |
|
---|
243 | #define DR7_GD (1 << 13)
|
---|
244 | #define DR7_TYPE_SHIFT 16
|
---|
245 | #define DR7_LEN_SHIFT 18
|
---|
246 | #define DR7_FIXED_1 0x00000400
|
---|
247 |
|
---|
248 | #define PG_PRESENT_BIT 0
|
---|
249 | #define PG_RW_BIT 1
|
---|
250 | #define PG_USER_BIT 2
|
---|
251 | #define PG_PWT_BIT 3
|
---|
252 | #define PG_PCD_BIT 4
|
---|
253 | #define PG_ACCESSED_BIT 5
|
---|
254 | #define PG_DIRTY_BIT 6
|
---|
255 | #define PG_PSE_BIT 7
|
---|
256 | #define PG_GLOBAL_BIT 8
|
---|
257 | #define PG_NX_BIT 63
|
---|
258 |
|
---|
259 | #define PG_PRESENT_MASK (1 << PG_PRESENT_BIT)
|
---|
260 | #define PG_RW_MASK (1 << PG_RW_BIT)
|
---|
261 | #define PG_USER_MASK (1 << PG_USER_BIT)
|
---|
262 | #define PG_PWT_MASK (1 << PG_PWT_BIT)
|
---|
263 | #define PG_PCD_MASK (1 << PG_PCD_BIT)
|
---|
264 | #define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT)
|
---|
265 | #define PG_DIRTY_MASK (1 << PG_DIRTY_BIT)
|
---|
266 | #define PG_PSE_MASK (1 << PG_PSE_BIT)
|
---|
267 | #define PG_GLOBAL_MASK (1 << PG_GLOBAL_BIT)
|
---|
268 | #define PG_NX_MASK (1LL << PG_NX_BIT)
|
---|
269 |
|
---|
270 | #define PG_ERROR_W_BIT 1
|
---|
271 |
|
---|
272 | #define PG_ERROR_P_MASK 0x01
|
---|
273 | #define PG_ERROR_W_MASK (1 << PG_ERROR_W_BIT)
|
---|
274 | #define PG_ERROR_U_MASK 0x04
|
---|
275 | #define PG_ERROR_RSVD_MASK 0x08
|
---|
276 | #define PG_ERROR_I_D_MASK 0x10
|
---|
277 |
|
---|
278 | #define MCG_CTL_P (1UL<<8) /* MCG_CAP register available */
|
---|
279 |
|
---|
280 | #define MCE_CAP_DEF MCG_CTL_P
|
---|
281 | #define MCE_BANKS_DEF 10
|
---|
282 |
|
---|
283 | #define MCG_STATUS_MCIP (1ULL<<2) /* machine check in progress */
|
---|
284 |
|
---|
285 | #define MCI_STATUS_VAL (1ULL<<63) /* valid error */
|
---|
286 | #define MCI_STATUS_OVER (1ULL<<62) /* previous errors lost */
|
---|
287 | #define MCI_STATUS_UC (1ULL<<61) /* uncorrected error */
|
---|
288 |
|
---|
289 | #define MSR_IA32_TSC 0x10
|
---|
290 | #define MSR_IA32_APICBASE 0x1b
|
---|
291 | #define MSR_IA32_APICBASE_BSP (1<<8)
|
---|
292 | #define MSR_IA32_APICBASE_ENABLE (1<<11)
|
---|
293 | #define MSR_IA32_APICBASE_BASE (0xfffff<<12)
|
---|
294 |
|
---|
295 | #define MSR_MTRRcap 0xfe
|
---|
296 | #define MSR_MTRRcap_VCNT 8
|
---|
297 | #define MSR_MTRRcap_FIXRANGE_SUPPORT (1 << 8)
|
---|
298 | #define MSR_MTRRcap_WC_SUPPORTED (1 << 10)
|
---|
299 |
|
---|
300 | #define MSR_IA32_SYSENTER_CS 0x174
|
---|
301 | #define MSR_IA32_SYSENTER_ESP 0x175
|
---|
302 | #define MSR_IA32_SYSENTER_EIP 0x176
|
---|
303 |
|
---|
304 | #define MSR_MCG_CAP 0x179
|
---|
305 | #define MSR_MCG_STATUS 0x17a
|
---|
306 | #define MSR_MCG_CTL 0x17b
|
---|
307 |
|
---|
308 | #define MSR_IA32_PERF_STATUS 0x198
|
---|
309 |
|
---|
310 | #define MSR_MTRRphysBase(reg) (0x200 + 2 * (reg))
|
---|
311 | #define MSR_MTRRphysMask(reg) (0x200 + 2 * (reg) + 1)
|
---|
312 |
|
---|
313 | #define MSR_MTRRfix64K_00000 0x250
|
---|
314 | #define MSR_MTRRfix16K_80000 0x258
|
---|
315 | #define MSR_MTRRfix16K_A0000 0x259
|
---|
316 | #define MSR_MTRRfix4K_C0000 0x268
|
---|
317 | #define MSR_MTRRfix4K_C8000 0x269
|
---|
318 | #define MSR_MTRRfix4K_D0000 0x26a
|
---|
319 | #define MSR_MTRRfix4K_D8000 0x26b
|
---|
320 | #define MSR_MTRRfix4K_E0000 0x26c
|
---|
321 | #define MSR_MTRRfix4K_E8000 0x26d
|
---|
322 | #define MSR_MTRRfix4K_F0000 0x26e
|
---|
323 | #define MSR_MTRRfix4K_F8000 0x26f
|
---|
324 |
|
---|
325 | #define MSR_PAT 0x277
|
---|
326 |
|
---|
327 | #define MSR_MTRRdefType 0x2ff
|
---|
328 |
|
---|
329 | #define MSR_MC0_CTL 0x400
|
---|
330 | #define MSR_MC0_STATUS 0x401
|
---|
331 | #define MSR_MC0_ADDR 0x402
|
---|
332 | #define MSR_MC0_MISC 0x403
|
---|
333 |
|
---|
334 | #define MSR_EFER 0xc0000080
|
---|
335 |
|
---|
336 | #define MSR_EFER_SCE (1 << 0)
|
---|
337 | #define MSR_EFER_LME (1 << 8)
|
---|
338 | #define MSR_EFER_LMA (1 << 10)
|
---|
339 | #define MSR_EFER_NXE (1 << 11)
|
---|
340 | #define MSR_EFER_SVME (1 << 12)
|
---|
341 | #define MSR_EFER_FFXSR (1 << 14)
|
---|
342 |
|
---|
343 | #ifdef VBOX
|
---|
344 | # define MSR_APIC_RANGE_START 0x800
|
---|
345 | # define MSR_APIC_RANGE_END 0x900
|
---|
346 | #endif
|
---|
347 |
|
---|
348 | #define MSR_STAR 0xc0000081
|
---|
349 | #define MSR_LSTAR 0xc0000082
|
---|
350 | #define MSR_CSTAR 0xc0000083
|
---|
351 | #define MSR_FMASK 0xc0000084
|
---|
352 | #define MSR_FSBASE 0xc0000100
|
---|
353 | #define MSR_GSBASE 0xc0000101
|
---|
354 | #define MSR_KERNELGSBASE 0xc0000102
|
---|
355 | #define MSR_TSC_AUX 0xc0000103
|
---|
356 |
|
---|
357 | #define MSR_VM_HSAVE_PA 0xc0010117
|
---|
358 |
|
---|
359 | /* cpuid_features bits */
|
---|
360 | #define CPUID_FP87 (1 << 0)
|
---|
361 | #define CPUID_VME (1 << 1)
|
---|
362 | #define CPUID_DE (1 << 2)
|
---|
363 | #define CPUID_PSE (1 << 3)
|
---|
364 | #define CPUID_TSC (1 << 4)
|
---|
365 | #define CPUID_MSR (1 << 5)
|
---|
366 | #define CPUID_PAE (1 << 6)
|
---|
367 | #define CPUID_MCE (1 << 7)
|
---|
368 | #define CPUID_CX8 (1 << 8)
|
---|
369 | #define CPUID_APIC (1 << 9)
|
---|
370 | #define CPUID_SEP (1 << 11) /* sysenter/sysexit */
|
---|
371 | #define CPUID_MTRR (1 << 12)
|
---|
372 | #define CPUID_PGE (1 << 13)
|
---|
373 | #define CPUID_MCA (1 << 14)
|
---|
374 | #define CPUID_CMOV (1 << 15)
|
---|
375 | #define CPUID_PAT (1 << 16)
|
---|
376 | #define CPUID_PSE36 (1 << 17)
|
---|
377 | #define CPUID_PN (1 << 18)
|
---|
378 | #define CPUID_CLFLUSH (1 << 19)
|
---|
379 | #define CPUID_DTS (1 << 21)
|
---|
380 | #define CPUID_ACPI (1 << 22)
|
---|
381 | #define CPUID_MMX (1 << 23)
|
---|
382 | #define CPUID_FXSR (1 << 24)
|
---|
383 | #define CPUID_SSE (1 << 25)
|
---|
384 | #define CPUID_SSE2 (1 << 26)
|
---|
385 | #define CPUID_SS (1 << 27)
|
---|
386 | #define CPUID_HT (1 << 28)
|
---|
387 | #define CPUID_TM (1 << 29)
|
---|
388 | #define CPUID_IA64 (1 << 30)
|
---|
389 | #define CPUID_PBE (1 << 31)
|
---|
390 |
|
---|
391 | #define CPUID_EXT_SSE3 (1 << 0)
|
---|
392 | #define CPUID_EXT_DTES64 (1 << 2)
|
---|
393 | #define CPUID_EXT_MONITOR (1 << 3)
|
---|
394 | #define CPUID_EXT_DSCPL (1 << 4)
|
---|
395 | #define CPUID_EXT_VMX (1 << 5)
|
---|
396 | #define CPUID_EXT_SMX (1 << 6)
|
---|
397 | #define CPUID_EXT_EST (1 << 7)
|
---|
398 | #define CPUID_EXT_TM2 (1 << 8)
|
---|
399 | #define CPUID_EXT_SSSE3 (1 << 9)
|
---|
400 | #define CPUID_EXT_CID (1 << 10)
|
---|
401 | #define CPUID_EXT_CX16 (1 << 13)
|
---|
402 | #define CPUID_EXT_XTPR (1 << 14)
|
---|
403 | #define CPUID_EXT_PDCM (1 << 15)
|
---|
404 | #define CPUID_EXT_DCA (1 << 18)
|
---|
405 | #define CPUID_EXT_SSE41 (1 << 19)
|
---|
406 | #define CPUID_EXT_SSE42 (1 << 20)
|
---|
407 | #define CPUID_EXT_X2APIC (1 << 21)
|
---|
408 | #define CPUID_EXT_MOVBE (1 << 22)
|
---|
409 | #define CPUID_EXT_POPCNT (1 << 23)
|
---|
410 | #define CPUID_EXT_XSAVE (1 << 26)
|
---|
411 | #define CPUID_EXT_OSXSAVE (1 << 27)
|
---|
412 | #define CPUID_EXT_HYPERVISOR (1 << 31)
|
---|
413 |
|
---|
414 | #define CPUID_EXT2_SYSCALL (1 << 11)
|
---|
415 | #define CPUID_EXT2_MP (1 << 19)
|
---|
416 | #define CPUID_EXT2_NX (1 << 20)
|
---|
417 | #define CPUID_EXT2_MMXEXT (1 << 22)
|
---|
418 | #define CPUID_EXT2_FFXSR (1 << 25)
|
---|
419 | #define CPUID_EXT2_PDPE1GB (1 << 26)
|
---|
420 | #define CPUID_EXT2_RDTSCP (1 << 27)
|
---|
421 | #define CPUID_EXT2_LM (1 << 29)
|
---|
422 | #define CPUID_EXT2_3DNOWEXT (1 << 30)
|
---|
423 | #define CPUID_EXT2_3DNOW (1 << 31)
|
---|
424 |
|
---|
425 | #define CPUID_EXT3_LAHF_LM (1 << 0)
|
---|
426 | #define CPUID_EXT3_CMP_LEG (1 << 1)
|
---|
427 | #define CPUID_EXT3_SVM (1 << 2)
|
---|
428 | #define CPUID_EXT3_EXTAPIC (1 << 3)
|
---|
429 | #define CPUID_EXT3_CR8LEG (1 << 4)
|
---|
430 | #define CPUID_EXT3_ABM (1 << 5)
|
---|
431 | #define CPUID_EXT3_SSE4A (1 << 6)
|
---|
432 | #define CPUID_EXT3_MISALIGNSSE (1 << 7)
|
---|
433 | #define CPUID_EXT3_3DNOWPREFETCH (1 << 8)
|
---|
434 | #define CPUID_EXT3_OSVW (1 << 9)
|
---|
435 | #define CPUID_EXT3_IBS (1 << 10)
|
---|
436 | #define CPUID_EXT3_SKINIT (1 << 12)
|
---|
437 |
|
---|
438 | #define CPUID_VENDOR_INTEL_1 0x756e6547 /* "Genu" */
|
---|
439 | #define CPUID_VENDOR_INTEL_2 0x49656e69 /* "ineI" */
|
---|
440 | #define CPUID_VENDOR_INTEL_3 0x6c65746e /* "ntel" */
|
---|
441 |
|
---|
442 | #define CPUID_VENDOR_AMD_1 0x68747541 /* "Auth" */
|
---|
443 | #define CPUID_VENDOR_AMD_2 0x69746e65 /* "enti" */
|
---|
444 | #define CPUID_VENDOR_AMD_3 0x444d4163 /* "cAMD" */
|
---|
445 |
|
---|
446 | #define CPUID_MWAIT_IBE (1 << 1) /* Interrupts can exit capability */
|
---|
447 | #define CPUID_MWAIT_EMX (1 << 0) /* enumeration supported */
|
---|
448 |
|
---|
449 | #define EXCP00_DIVZ 0
|
---|
450 | #define EXCP01_DB 1
|
---|
451 | #define EXCP02_NMI 2
|
---|
452 | #define EXCP03_INT3 3
|
---|
453 | #define EXCP04_INTO 4
|
---|
454 | #define EXCP05_BOUND 5
|
---|
455 | #define EXCP06_ILLOP 6
|
---|
456 | #define EXCP07_PREX 7
|
---|
457 | #define EXCP08_DBLE 8
|
---|
458 | #define EXCP09_XERR 9
|
---|
459 | #define EXCP0A_TSS 10
|
---|
460 | #define EXCP0B_NOSEG 11
|
---|
461 | #define EXCP0C_STACK 12
|
---|
462 | #define EXCP0D_GPF 13
|
---|
463 | #define EXCP0E_PAGE 14
|
---|
464 | #define EXCP10_COPR 16
|
---|
465 | #define EXCP11_ALGN 17
|
---|
466 | #define EXCP12_MCHK 18
|
---|
467 |
|
---|
468 | #define EXCP_SYSCALL 0x100 /* only happens in user only emulation
|
---|
469 | for syscall instruction */
|
---|
470 |
|
---|
471 | enum {
|
---|
472 | CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
|
---|
473 | CC_OP_EFLAGS, /* all cc are explicitly computed, CC_SRC = flags */
|
---|
474 |
|
---|
475 | CC_OP_MULB, /* modify all flags, C, O = (CC_SRC != 0) */
|
---|
476 | CC_OP_MULW,
|
---|
477 | CC_OP_MULL,
|
---|
478 | CC_OP_MULQ,
|
---|
479 |
|
---|
480 | CC_OP_ADDB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
|
---|
481 | CC_OP_ADDW,
|
---|
482 | CC_OP_ADDL,
|
---|
483 | CC_OP_ADDQ,
|
---|
484 |
|
---|
485 | CC_OP_ADCB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
|
---|
486 | CC_OP_ADCW,
|
---|
487 | CC_OP_ADCL,
|
---|
488 | CC_OP_ADCQ,
|
---|
489 |
|
---|
490 | CC_OP_SUBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
|
---|
491 | CC_OP_SUBW,
|
---|
492 | CC_OP_SUBL,
|
---|
493 | CC_OP_SUBQ,
|
---|
494 |
|
---|
495 | CC_OP_SBBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
|
---|
496 | CC_OP_SBBW,
|
---|
497 | CC_OP_SBBL,
|
---|
498 | CC_OP_SBBQ,
|
---|
499 |
|
---|
500 | CC_OP_LOGICB, /* modify all flags, CC_DST = res */
|
---|
501 | CC_OP_LOGICW,
|
---|
502 | CC_OP_LOGICL,
|
---|
503 | CC_OP_LOGICQ,
|
---|
504 |
|
---|
505 | CC_OP_INCB, /* modify all flags except, CC_DST = res, CC_SRC = C */
|
---|
506 | CC_OP_INCW,
|
---|
507 | CC_OP_INCL,
|
---|
508 | CC_OP_INCQ,
|
---|
509 |
|
---|
510 | CC_OP_DECB, /* modify all flags except, CC_DST = res, CC_SRC = C */
|
---|
511 | CC_OP_DECW,
|
---|
512 | CC_OP_DECL,
|
---|
513 | CC_OP_DECQ,
|
---|
514 |
|
---|
515 | CC_OP_SHLB, /* modify all flags, CC_DST = res, CC_SRC.msb = C */
|
---|
516 | CC_OP_SHLW,
|
---|
517 | CC_OP_SHLL,
|
---|
518 | CC_OP_SHLQ,
|
---|
519 |
|
---|
520 | CC_OP_SARB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */
|
---|
521 | CC_OP_SARW,
|
---|
522 | CC_OP_SARL,
|
---|
523 | CC_OP_SARQ,
|
---|
524 |
|
---|
525 | CC_OP_NB,
|
---|
526 | };
|
---|
527 |
|
---|
528 | #ifdef FLOATX80
|
---|
529 | #define USE_X86LDOUBLE
|
---|
530 | #endif
|
---|
531 |
|
---|
532 | #ifdef USE_X86LDOUBLE
|
---|
533 | typedef floatx80 CPU86_LDouble;
|
---|
534 | #else
|
---|
535 | typedef float64 CPU86_LDouble;
|
---|
536 | #endif
|
---|
537 |
|
---|
538 | typedef struct SegmentCache {
|
---|
539 | uint32_t selector;
|
---|
540 | #ifdef VBOX
|
---|
541 | /** The new selector is saved here when we are unable to sync it before invoking the recompiled code. */
|
---|
542 | uint16_t newselector;
|
---|
543 | uint16_t fVBoxFlags;
|
---|
544 | #endif
|
---|
545 | target_ulong base;
|
---|
546 | uint32_t limit;
|
---|
547 | uint32_t flags;
|
---|
548 | } SegmentCache;
|
---|
549 |
|
---|
550 | typedef union {
|
---|
551 | uint8_t _b[16];
|
---|
552 | uint16_t _w[8];
|
---|
553 | uint32_t _l[4];
|
---|
554 | uint64_t _q[2];
|
---|
555 | float32 _s[4];
|
---|
556 | float64 _d[2];
|
---|
557 | } XMMReg;
|
---|
558 |
|
---|
559 | typedef union {
|
---|
560 | uint8_t _b[8];
|
---|
561 | uint16_t _w[4];
|
---|
562 | uint32_t _l[2];
|
---|
563 | float32 _s[2];
|
---|
564 | uint64_t q;
|
---|
565 | } MMXReg;
|
---|
566 |
|
---|
567 | #ifdef HOST_WORDS_BIGENDIAN
|
---|
568 | #define XMM_B(n) _b[15 - (n)]
|
---|
569 | #define XMM_W(n) _w[7 - (n)]
|
---|
570 | #define XMM_L(n) _l[3 - (n)]
|
---|
571 | #define XMM_S(n) _s[3 - (n)]
|
---|
572 | #define XMM_Q(n) _q[1 - (n)]
|
---|
573 | #define XMM_D(n) _d[1 - (n)]
|
---|
574 |
|
---|
575 | #define MMX_B(n) _b[7 - (n)]
|
---|
576 | #define MMX_W(n) _w[3 - (n)]
|
---|
577 | #define MMX_L(n) _l[1 - (n)]
|
---|
578 | #define MMX_S(n) _s[1 - (n)]
|
---|
579 | #else
|
---|
580 | #define XMM_B(n) _b[n]
|
---|
581 | #define XMM_W(n) _w[n]
|
---|
582 | #define XMM_L(n) _l[n]
|
---|
583 | #define XMM_S(n) _s[n]
|
---|
584 | #define XMM_Q(n) _q[n]
|
---|
585 | #define XMM_D(n) _d[n]
|
---|
586 |
|
---|
587 | #define MMX_B(n) _b[n]
|
---|
588 | #define MMX_W(n) _w[n]
|
---|
589 | #define MMX_L(n) _l[n]
|
---|
590 | #define MMX_S(n) _s[n]
|
---|
591 | #endif
|
---|
592 | #define MMX_Q(n) q
|
---|
593 |
|
---|
594 | typedef union {
|
---|
595 | #ifdef USE_X86LDOUBLE
|
---|
596 | CPU86_LDouble d __attribute__((aligned(16)));
|
---|
597 | #else
|
---|
598 | CPU86_LDouble d;
|
---|
599 | #endif
|
---|
600 | MMXReg mmx;
|
---|
601 | } FPReg;
|
---|
602 |
|
---|
603 | typedef struct {
|
---|
604 | uint64_t base;
|
---|
605 | uint64_t mask;
|
---|
606 | } MTRRVar;
|
---|
607 |
|
---|
608 | #define CPU_NB_REGS64 16
|
---|
609 | #define CPU_NB_REGS32 8
|
---|
610 |
|
---|
611 | #ifdef TARGET_X86_64
|
---|
612 | #define CPU_NB_REGS CPU_NB_REGS64
|
---|
613 | #else
|
---|
614 | #define CPU_NB_REGS CPU_NB_REGS32
|
---|
615 | #endif
|
---|
616 |
|
---|
617 | #define NB_MMU_MODES 2
|
---|
618 |
|
---|
619 | typedef struct CPUX86State {
|
---|
620 | /* standard registers */
|
---|
621 | target_ulong regs[CPU_NB_REGS];
|
---|
622 | target_ulong eip;
|
---|
623 | target_ulong eflags; /* eflags register. During CPU emulation, CC
|
---|
624 | flags and DF are set to zero because they are
|
---|
625 | stored elsewhere */
|
---|
626 |
|
---|
627 | /* emulator internal eflags handling */
|
---|
628 | target_ulong cc_src;
|
---|
629 | target_ulong cc_dst;
|
---|
630 | uint32_t cc_op;
|
---|
631 | int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */
|
---|
632 | uint32_t hflags; /* TB flags, see HF_xxx constants. These flags
|
---|
633 | are known at translation time. */
|
---|
634 | uint32_t hflags2; /* various other flags, see HF2_xxx constants. */
|
---|
635 |
|
---|
636 | /* segments */
|
---|
637 | SegmentCache segs[6]; /* selector values */
|
---|
638 | SegmentCache ldt;
|
---|
639 | SegmentCache tr;
|
---|
640 | SegmentCache gdt; /* only base and limit are used */
|
---|
641 | SegmentCache idt; /* only base and limit are used */
|
---|
642 |
|
---|
643 | target_ulong cr[5]; /* NOTE: cr1 is unused */
|
---|
644 | int32_t a20_mask;
|
---|
645 |
|
---|
646 | /* FPU state */
|
---|
647 | unsigned int fpstt; /* top of stack index */
|
---|
648 | uint16_t fpus;
|
---|
649 | uint16_t fpuc;
|
---|
650 | uint8_t fptags[8]; /* 0 = valid, 1 = empty */
|
---|
651 | FPReg fpregs[8];
|
---|
652 |
|
---|
653 | /* emulator internal variables */
|
---|
654 | float_status fp_status;
|
---|
655 | #ifdef VBOX
|
---|
656 | uint32_t alignment3[3]; /* force the long double to start a 16 byte line. */
|
---|
657 | #endif
|
---|
658 | CPU86_LDouble ft0;
|
---|
659 | #if defined(VBOX) && defined(RT_ARCH_X86) && !defined(RT_OS_DARWIN)
|
---|
660 | uint32_t alignment4; /* long double is 12 byte, pad it to 16. */
|
---|
661 | #endif
|
---|
662 |
|
---|
663 | float_status mmx_status; /* for 3DNow! float ops */
|
---|
664 | float_status sse_status;
|
---|
665 | uint32_t mxcsr;
|
---|
666 | XMMReg xmm_regs[CPU_NB_REGS];
|
---|
667 | XMMReg xmm_t0;
|
---|
668 | MMXReg mmx_t0;
|
---|
669 | target_ulong cc_tmp; /* temporary for rcr/rcl */
|
---|
670 |
|
---|
671 | /* sysenter registers */
|
---|
672 | uint32_t sysenter_cs;
|
---|
673 | #ifdef VBOX
|
---|
674 | uint32_t alignment0;
|
---|
675 | #endif
|
---|
676 | target_ulong sysenter_esp;
|
---|
677 | target_ulong sysenter_eip;
|
---|
678 | uint64_t efer;
|
---|
679 | uint64_t star;
|
---|
680 |
|
---|
681 | uint64_t vm_hsave;
|
---|
682 | uint64_t vm_vmcb;
|
---|
683 | uint64_t tsc_offset;
|
---|
684 | uint64_t intercept;
|
---|
685 | uint16_t intercept_cr_read;
|
---|
686 | uint16_t intercept_cr_write;
|
---|
687 | uint16_t intercept_dr_read;
|
---|
688 | uint16_t intercept_dr_write;
|
---|
689 | uint32_t intercept_exceptions;
|
---|
690 | uint8_t v_tpr;
|
---|
691 |
|
---|
692 | #ifdef TARGET_X86_64
|
---|
693 | target_ulong lstar;
|
---|
694 | target_ulong cstar;
|
---|
695 | target_ulong fmask;
|
---|
696 | target_ulong kernelgsbase;
|
---|
697 | #endif
|
---|
698 | uint64_t system_time_msr;
|
---|
699 | uint64_t wall_clock_msr;
|
---|
700 |
|
---|
701 | uint64_t tsc;
|
---|
702 |
|
---|
703 | uint64_t pat;
|
---|
704 |
|
---|
705 | /* exception/interrupt handling */
|
---|
706 | int error_code;
|
---|
707 | int exception_is_int;
|
---|
708 | #ifdef VBOX
|
---|
709 | # define EXCEPTION_IS_INT_VALUE_HARDWARE_IRQ 0x42 /**< Special CPUX86State::exception_is_int value indicating hardware irq. (HACK ALERT) */
|
---|
710 | #endif
|
---|
711 | target_ulong exception_next_eip;
|
---|
712 | target_ulong dr[8]; /* debug registers */
|
---|
713 | union {
|
---|
714 | CPUBreakpoint *cpu_breakpoint[4];
|
---|
715 | CPUWatchpoint *cpu_watchpoint[4];
|
---|
716 | }; /* break/watchpoints for dr[0..3] */
|
---|
717 | uint32_t smbase;
|
---|
718 | int old_exception; /* exception in flight */
|
---|
719 |
|
---|
720 | CPU_COMMON
|
---|
721 |
|
---|
722 | #ifdef VBOX
|
---|
723 | /** cpu state flags. (see defines below) */
|
---|
724 | uint32_t state;
|
---|
725 | /** The VM handle. */
|
---|
726 | PVM pVM;
|
---|
727 | /** The VMCPU handle. */
|
---|
728 | PVMCPU pVCpu;
|
---|
729 | /** code buffer for instruction emulation */
|
---|
730 | void *pvCodeBuffer;
|
---|
731 | /** code buffer size */
|
---|
732 | uint32_t cbCodeBuffer;
|
---|
733 | #endif /* VBOX */
|
---|
734 |
|
---|
735 | /* processor features (e.g. for CPUID insn) */
|
---|
736 | #ifndef VBOX /* remR3CpuId deals with these */
|
---|
737 | uint32_t cpuid_level;
|
---|
738 | uint32_t cpuid_vendor1;
|
---|
739 | uint32_t cpuid_vendor2;
|
---|
740 | uint32_t cpuid_vendor3;
|
---|
741 | uint32_t cpuid_version;
|
---|
742 | #endif /* !VBOX */
|
---|
743 | uint32_t cpuid_features;
|
---|
744 | uint32_t cpuid_ext_features;
|
---|
745 | #ifndef VBOX
|
---|
746 | uint32_t cpuid_xlevel;
|
---|
747 | uint32_t cpuid_model[12];
|
---|
748 | #endif /* !VBOX */
|
---|
749 | uint32_t cpuid_ext2_features;
|
---|
750 | uint32_t cpuid_ext3_features;
|
---|
751 | uint32_t cpuid_apic_id;
|
---|
752 | #ifndef VBOX
|
---|
753 | int cpuid_vendor_override;
|
---|
754 |
|
---|
755 | /* MTRRs */
|
---|
756 | uint64_t mtrr_fixed[11];
|
---|
757 | uint64_t mtrr_deftype;
|
---|
758 | MTRRVar mtrr_var[8];
|
---|
759 |
|
---|
760 | /* For KVM */
|
---|
761 | uint32_t mp_state;
|
---|
762 | int32_t exception_injected;
|
---|
763 | int32_t interrupt_injected;
|
---|
764 | uint8_t soft_interrupt;
|
---|
765 | uint8_t nmi_injected;
|
---|
766 | uint8_t nmi_pending;
|
---|
767 | uint8_t has_error_code;
|
---|
768 | uint32_t sipi_vector;
|
---|
769 |
|
---|
770 | uint32_t cpuid_kvm_features;
|
---|
771 |
|
---|
772 | /* in order to simplify APIC support, we leave this pointer to the
|
---|
773 | user */
|
---|
774 | struct DeviceState *apic_state;
|
---|
775 |
|
---|
776 | uint64 mcg_cap;
|
---|
777 | uint64 mcg_status;
|
---|
778 | uint64 mcg_ctl;
|
---|
779 | uint64 mce_banks[MCE_BANKS_DEF*4];
|
---|
780 |
|
---|
781 | uint64_t tsc_aux;
|
---|
782 |
|
---|
783 | /* vmstate */
|
---|
784 | uint16_t fpus_vmstate;
|
---|
785 | uint16_t fptag_vmstate;
|
---|
786 | uint16_t fpregs_format_vmstate;
|
---|
787 |
|
---|
788 | uint64_t xstate_bv;
|
---|
789 | XMMReg ymmh_regs[CPU_NB_REGS];
|
---|
790 |
|
---|
791 | uint64_t xcr0;
|
---|
792 | #else /* VBOX */
|
---|
793 |
|
---|
794 | /** Alignment padding. */
|
---|
795 | # if HC_ARCH_BITS == 64 \
|
---|
796 | || ( HC_ARCH_BITS == 32 \
|
---|
797 | && !defined(RT_OS_WINDOWS) \
|
---|
798 | && ( (!defined(VBOX_ENABLE_VBOXREM64) && !defined(RT_OS_SOLARIS) && !defined(RT_OS_FREEBSD)) \
|
---|
799 | || (defined(VBOX_ENABLE_VBOXREM64) && (defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD))) ) )
|
---|
800 | uint32_t alignment2[1];
|
---|
801 | # endif
|
---|
802 |
|
---|
803 | /** Profiling tb_flush. */
|
---|
804 | STAMPROFILE StatTbFlush;
|
---|
805 |
|
---|
806 | /** Addends for HVA -> GPA translations. */
|
---|
807 | target_phys_addr_t phys_addends[NB_MMU_MODES][CPU_TLB_SIZE];
|
---|
808 | #endif /* VBOX */
|
---|
809 | } CPUX86State;
|
---|
810 |
|
---|
811 | #ifdef VBOX
|
---|
812 |
|
---|
813 | /* Version 1.6 structure; just for loading the old saved state */
|
---|
814 | typedef struct SegmentCache_Ver16 {
|
---|
815 | uint32_t selector;
|
---|
816 | uint32_t base;
|
---|
817 | uint32_t limit;
|
---|
818 | uint32_t flags;
|
---|
819 | /** The new selector is saved here when we are unable to sync it before invoking the recompiled code. */
|
---|
820 | uint32_t newselector;
|
---|
821 | } SegmentCache_Ver16;
|
---|
822 |
|
---|
823 | # define CPU_NB_REGS_VER16 8
|
---|
824 |
|
---|
825 | /* Version 1.6 structure; just for loading the old saved state */
|
---|
826 | typedef struct CPUX86State_Ver16 {
|
---|
827 | # if TARGET_LONG_BITS > HOST_LONG_BITS
|
---|
828 | /* temporaries if we cannot store them in host registers */
|
---|
829 | uint32_t t0, t1, t2;
|
---|
830 | # endif
|
---|
831 |
|
---|
832 | /* standard registers */
|
---|
833 | uint32_t regs[CPU_NB_REGS_VER16];
|
---|
834 | uint32_t eip;
|
---|
835 | uint32_t eflags; /* eflags register. During CPU emulation, CC
|
---|
836 | flags and DF are set to zero because they are
|
---|
837 | stored elsewhere */
|
---|
838 |
|
---|
839 | /* emulator internal eflags handling */
|
---|
840 | uint32_t cc_src;
|
---|
841 | uint32_t cc_dst;
|
---|
842 | uint32_t cc_op;
|
---|
843 | int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */
|
---|
844 | uint32_t hflags; /* hidden flags, see HF_xxx constants */
|
---|
845 |
|
---|
846 | /* segments */
|
---|
847 | SegmentCache_Ver16 segs[6]; /* selector values */
|
---|
848 | SegmentCache_Ver16 ldt;
|
---|
849 | SegmentCache_Ver16 tr;
|
---|
850 | SegmentCache_Ver16 gdt; /* only base and limit are used */
|
---|
851 | SegmentCache_Ver16 idt; /* only base and limit are used */
|
---|
852 |
|
---|
853 | uint32_t cr[5]; /* NOTE: cr1 is unused */
|
---|
854 | uint32_t a20_mask;
|
---|
855 |
|
---|
856 | /* FPU state */
|
---|
857 | unsigned int fpstt; /* top of stack index */
|
---|
858 | unsigned int fpus;
|
---|
859 | unsigned int fpuc;
|
---|
860 | uint8_t fptags[8]; /* 0 = valid, 1 = empty */
|
---|
861 | union {
|
---|
862 | # ifdef USE_X86LDOUBLE
|
---|
863 | CPU86_LDouble d __attribute__((aligned(16)));
|
---|
864 | # else
|
---|
865 | CPU86_LDouble d;
|
---|
866 | # endif
|
---|
867 | MMXReg mmx;
|
---|
868 | } fpregs[8];
|
---|
869 |
|
---|
870 | /* emulator internal variables */
|
---|
871 | float_status fp_status;
|
---|
872 | # ifdef VBOX
|
---|
873 | uint32_t alignment3[3]; /* force the long double to start a 16 byte line. */
|
---|
874 | # endif
|
---|
875 | CPU86_LDouble ft0;
|
---|
876 | # if defined(VBOX) && defined(RT_ARCH_X86) && !defined(RT_OS_DARWIN)
|
---|
877 | uint32_t alignment4; /* long double is 12 byte, pad it to 16. */
|
---|
878 | # endif
|
---|
879 | union {
|
---|
880 | float f;
|
---|
881 | double d;
|
---|
882 | int i32;
|
---|
883 | int64_t i64;
|
---|
884 | } fp_convert;
|
---|
885 |
|
---|
886 | float_status sse_status;
|
---|
887 | uint32_t mxcsr;
|
---|
888 | XMMReg xmm_regs[CPU_NB_REGS_VER16];
|
---|
889 | XMMReg xmm_t0;
|
---|
890 | MMXReg mmx_t0;
|
---|
891 |
|
---|
892 | /* sysenter registers */
|
---|
893 | uint32_t sysenter_cs;
|
---|
894 | uint32_t sysenter_esp;
|
---|
895 | uint32_t sysenter_eip;
|
---|
896 | # ifdef VBOX
|
---|
897 | uint32_t alignment0;
|
---|
898 | # endif
|
---|
899 | uint64_t efer;
|
---|
900 | uint64_t star;
|
---|
901 |
|
---|
902 | uint64_t pat;
|
---|
903 |
|
---|
904 | /* temporary data for USE_CODE_COPY mode */
|
---|
905 | # ifdef USE_CODE_COPY
|
---|
906 | uint32_t tmp0;
|
---|
907 | uint32_t saved_esp;
|
---|
908 | int native_fp_regs; /* if true, the FPU state is in the native CPU regs */
|
---|
909 | # endif
|
---|
910 |
|
---|
911 | /* exception/interrupt handling */
|
---|
912 | jmp_buf jmp_env;
|
---|
913 | } CPUX86State_Ver16;
|
---|
914 |
|
---|
915 | /** CPUX86State state flags
|
---|
916 | * @{ */
|
---|
917 | # define CPU_RAW_RING0 0x0002 /* Set after first time RawR0 is executed, never cleared. */
|
---|
918 | # define CPU_EMULATE_SINGLE_INSTR 0x0040 /* Execute a single instruction in emulation mode */
|
---|
919 | # define CPU_EMULATE_SINGLE_STEP 0x0080 /* go into single step mode */
|
---|
920 | # define CPU_RAW_HM 0x0100 /* Set after first time HWACC is executed, never cleared. */
|
---|
921 | /** @} */
|
---|
922 | #endif /* !VBOX */
|
---|
923 |
|
---|
924 | #ifdef VBOX
|
---|
925 | CPUX86State *cpu_x86_init(CPUX86State *env, const char *cpu_model);
|
---|
926 | #else /* !VBOX */
|
---|
927 | CPUX86State *cpu_x86_init(const char *cpu_model);
|
---|
928 | #endif /* !VBOX */
|
---|
929 | int cpu_x86_exec(CPUX86State *s);
|
---|
930 | void cpu_x86_close(CPUX86State *s);
|
---|
931 | void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
|
---|
932 | const char *optarg);
|
---|
933 | void x86_cpudef_setup(void);
|
---|
934 |
|
---|
935 | int cpu_get_pic_interrupt(CPUX86State *s);
|
---|
936 | /* MSDOS compatibility mode FPU exception support */
|
---|
937 | void cpu_set_ferr(CPUX86State *s);
|
---|
938 |
|
---|
939 | /* this function must always be used to load data in the segment
|
---|
940 | cache: it synchronizes the hflags with the segment cache values */
|
---|
941 | #ifndef VBOX
|
---|
942 | static inline void cpu_x86_load_seg_cache(CPUX86State *env,
|
---|
943 | int seg_reg, unsigned int selector,
|
---|
944 | target_ulong base,
|
---|
945 | unsigned int limit,
|
---|
946 | unsigned int flags)
|
---|
947 | #else
|
---|
948 | static inline void cpu_x86_load_seg_cache_with_clean_flags(CPUX86State *env,
|
---|
949 | int seg_reg, unsigned int selector,
|
---|
950 | target_ulong base,
|
---|
951 | unsigned int limit,
|
---|
952 | unsigned int flags)
|
---|
953 | #endif
|
---|
954 | {
|
---|
955 | SegmentCache *sc;
|
---|
956 | unsigned int new_hflags;
|
---|
957 |
|
---|
958 | sc = &env->segs[seg_reg];
|
---|
959 | sc->selector = selector;
|
---|
960 | sc->base = base;
|
---|
961 | sc->limit = limit;
|
---|
962 | sc->flags = flags;
|
---|
963 | #ifdef VBOX
|
---|
964 | sc->newselector = 0;
|
---|
965 | sc->fVBoxFlags = CPUMSELREG_FLAGS_VALID;
|
---|
966 | #endif
|
---|
967 |
|
---|
968 | /* update the hidden flags */
|
---|
969 | {
|
---|
970 | if (seg_reg == R_CS) {
|
---|
971 | #ifdef TARGET_X86_64
|
---|
972 | if ((env->hflags & HF_LMA_MASK) && (flags & DESC_L_MASK)) {
|
---|
973 | /* long mode */
|
---|
974 | env->hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
|
---|
975 | env->hflags &= ~(HF_ADDSEG_MASK);
|
---|
976 | } else
|
---|
977 | #endif
|
---|
978 | {
|
---|
979 | /* legacy / compatibility case */
|
---|
980 | new_hflags = (env->segs[R_CS].flags & DESC_B_MASK)
|
---|
981 | >> (DESC_B_SHIFT - HF_CS32_SHIFT);
|
---|
982 | env->hflags = (env->hflags & ~(HF_CS32_MASK | HF_CS64_MASK)) |
|
---|
983 | new_hflags;
|
---|
984 | }
|
---|
985 | }
|
---|
986 | new_hflags = (env->segs[R_SS].flags & DESC_B_MASK)
|
---|
987 | >> (DESC_B_SHIFT - HF_SS32_SHIFT);
|
---|
988 | if (env->hflags & HF_CS64_MASK) {
|
---|
989 | /* zero base assumed for DS, ES and SS in long mode */
|
---|
990 | } else if (!(env->cr[0] & CR0_PE_MASK) ||
|
---|
991 | (env->eflags & VM_MASK) ||
|
---|
992 | !(env->hflags & HF_CS32_MASK)) {
|
---|
993 | /* XXX: try to avoid this test. The problem comes from the
|
---|
994 | fact that is real mode or vm86 mode we only modify the
|
---|
995 | 'base' and 'selector' fields of the segment cache to go
|
---|
996 | faster. A solution may be to force addseg to one in
|
---|
997 | translate-i386.c. */
|
---|
998 | new_hflags |= HF_ADDSEG_MASK;
|
---|
999 | } else {
|
---|
1000 | new_hflags |= ((env->segs[R_DS].base |
|
---|
1001 | env->segs[R_ES].base |
|
---|
1002 | env->segs[R_SS].base) != 0) <<
|
---|
1003 | HF_ADDSEG_SHIFT;
|
---|
1004 | }
|
---|
1005 | env->hflags = (env->hflags &
|
---|
1006 | ~(HF_SS32_MASK | HF_ADDSEG_MASK)) | new_hflags;
|
---|
1007 | }
|
---|
1008 | }
|
---|
1009 |
|
---|
1010 | #ifdef VBOX
|
---|
1011 | /* Raw input, adjust the flags adding the stupid intel flag when applicable. */
|
---|
1012 | static inline void cpu_x86_load_seg_cache(CPUX86State *env,
|
---|
1013 | int seg_reg, unsigned int selector,
|
---|
1014 | target_ulong base,
|
---|
1015 | unsigned int limit,
|
---|
1016 | unsigned int flags)
|
---|
1017 | {
|
---|
1018 | flags &= DESC_RAW_FLAG_BITS;
|
---|
1019 | if (flags & DESC_P_MASK)
|
---|
1020 | flags |= DESC_A_MASK; /* Make sure the A bit is set to avoid trouble. */
|
---|
1021 | else if (selector < 4U)
|
---|
1022 | flags |= DESC_INTEL_UNUSABLE;
|
---|
1023 | cpu_x86_load_seg_cache_with_clean_flags(env, seg_reg, selector, base, limit, flags);
|
---|
1024 | }
|
---|
1025 | #endif
|
---|
1026 |
|
---|
1027 | static inline void cpu_x86_load_seg_cache_sipi(CPUX86State *env,
|
---|
1028 | int sipi_vector)
|
---|
1029 | {
|
---|
1030 | env->eip = 0;
|
---|
1031 | cpu_x86_load_seg_cache(env, R_CS, sipi_vector << 8,
|
---|
1032 | sipi_vector << 12,
|
---|
1033 | env->segs[R_CS].limit,
|
---|
1034 | env->segs[R_CS].flags);
|
---|
1035 | env->halted = 0;
|
---|
1036 | }
|
---|
1037 |
|
---|
1038 | int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
|
---|
1039 | target_ulong *base, unsigned int *limit,
|
---|
1040 | unsigned int *flags);
|
---|
1041 |
|
---|
1042 | /* wrapper, just in case memory mappings must be changed */
|
---|
1043 | static inline void cpu_x86_set_cpl(CPUX86State *s, int cpl)
|
---|
1044 | {
|
---|
1045 | #if HF_CPL_MASK == 3
|
---|
1046 | s->hflags = (s->hflags & ~HF_CPL_MASK) | cpl;
|
---|
1047 | #else
|
---|
1048 | #error HF_CPL_MASK is hardcoded
|
---|
1049 | #endif
|
---|
1050 | }
|
---|
1051 |
|
---|
1052 | /* op_helper.c */
|
---|
1053 | /* used for debug or cpu save/restore */
|
---|
1054 | void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, CPU86_LDouble f);
|
---|
1055 | CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper);
|
---|
1056 |
|
---|
1057 | /* cpu-exec.c */
|
---|
1058 | /* the following helpers are only usable in user mode simulation as
|
---|
1059 | they can trigger unexpected exceptions */
|
---|
1060 | void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector);
|
---|
1061 | void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32);
|
---|
1062 | void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32);
|
---|
1063 |
|
---|
1064 | /* you can call this signal handler from your SIGBUS and SIGSEGV
|
---|
1065 | signal handlers to inform the virtual CPU of exceptions. non zero
|
---|
1066 | is returned if the signal was handled by the virtual CPU. */
|
---|
1067 | int cpu_x86_signal_handler(int host_signum, void *pinfo,
|
---|
1068 | void *puc);
|
---|
1069 |
|
---|
1070 | /* cpuid.c */
|
---|
1071 | void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
---|
1072 | uint32_t *eax, uint32_t *ebx,
|
---|
1073 | uint32_t *ecx, uint32_t *edx);
|
---|
1074 | int cpu_x86_register (CPUX86State *env, const char *cpu_model);
|
---|
1075 | void cpu_clear_apic_feature(CPUX86State *env);
|
---|
1076 |
|
---|
1077 | /* helper.c */
|
---|
1078 | int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
|
---|
1079 | int is_write, int mmu_idx, int is_softmmu);
|
---|
1080 | #define cpu_handle_mmu_fault cpu_x86_handle_mmu_fault
|
---|
1081 | void cpu_x86_set_a20(CPUX86State *env, int a20_state);
|
---|
1082 |
|
---|
1083 | static inline int hw_breakpoint_enabled(unsigned long dr7, int index)
|
---|
1084 | {
|
---|
1085 | return (dr7 >> (index * 2)) & 3;
|
---|
1086 | }
|
---|
1087 |
|
---|
1088 | static inline int hw_breakpoint_type(unsigned long dr7, int index)
|
---|
1089 | {
|
---|
1090 | return (dr7 >> (DR7_TYPE_SHIFT + (index * 4))) & 3;
|
---|
1091 | }
|
---|
1092 |
|
---|
1093 | static inline int hw_breakpoint_len(unsigned long dr7, int index)
|
---|
1094 | {
|
---|
1095 | int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 4))) & 3);
|
---|
1096 | return (len == 2) ? 8 : len + 1;
|
---|
1097 | }
|
---|
1098 |
|
---|
1099 | void hw_breakpoint_insert(CPUX86State *env, int index);
|
---|
1100 | void hw_breakpoint_remove(CPUX86State *env, int index);
|
---|
1101 | int check_hw_breakpoints(CPUX86State *env, int force_dr6_update);
|
---|
1102 |
|
---|
1103 | /* will be suppressed */
|
---|
1104 | void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
|
---|
1105 | void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
|
---|
1106 | void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
|
---|
1107 |
|
---|
1108 | /* hw/pc.c */
|
---|
1109 | void cpu_smm_update(CPUX86State *env);
|
---|
1110 | uint64_t cpu_get_tsc(CPUX86State *env);
|
---|
1111 |
|
---|
1112 | /* used to debug */
|
---|
1113 | #define X86_DUMP_FPU 0x0001 /* dump FPU state too */
|
---|
1114 | #define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
|
---|
1115 |
|
---|
1116 | #ifdef VBOX
|
---|
1117 | int cpu_rdmsr(CPUX86State *env, uint32_t idMsr, uint64_t *puValue);
|
---|
1118 | int cpu_wrmsr(CPUX86State *env, uint32_t idMsr, uint64_t uValue);
|
---|
1119 | void cpu_trap_raw(CPUX86State *env1);
|
---|
1120 |
|
---|
1121 | /* in helper.c */
|
---|
1122 | uint8_t read_byte(CPUX86State *env1, target_ulong addr);
|
---|
1123 | uint16_t read_word(CPUX86State *env1, target_ulong addr);
|
---|
1124 | void write_byte(CPUX86State *env1, target_ulong addr, uint8_t val);
|
---|
1125 | uint32_t read_dword(CPUX86State *env1, target_ulong addr);
|
---|
1126 | void write_word(CPUX86State *env1, target_ulong addr, uint16_t val);
|
---|
1127 | void write_dword(CPUX86State *env1, target_ulong addr, uint32_t val);
|
---|
1128 | /* in helper.c */
|
---|
1129 | int emulate_single_instr(CPUX86State *env1);
|
---|
1130 | int get_ss_esp_from_tss_raw(CPUX86State *env1, uint32_t *ss_ptr, uint32_t *esp_ptr, int dpl);
|
---|
1131 |
|
---|
1132 | void restore_raw_fp_state(CPUX86State *env, uint8_t *ptr);
|
---|
1133 | void save_raw_fp_state(CPUX86State *env, uint8_t *ptr);
|
---|
1134 | #endif /* VBOX */
|
---|
1135 |
|
---|
1136 | #define TARGET_PAGE_BITS 12
|
---|
1137 |
|
---|
1138 | #ifdef TARGET_X86_64
|
---|
1139 | #define TARGET_PHYS_ADDR_SPACE_BITS 52
|
---|
1140 | /* ??? This is really 48 bits, sign-extended, but the only thing
|
---|
1141 | accessible to userland with bit 48 set is the VSYSCALL, and that
|
---|
1142 | is handled via other mechanisms. */
|
---|
1143 | #define TARGET_VIRT_ADDR_SPACE_BITS 47
|
---|
1144 | #else
|
---|
1145 | #define TARGET_PHYS_ADDR_SPACE_BITS 36
|
---|
1146 | #define TARGET_VIRT_ADDR_SPACE_BITS 32
|
---|
1147 | #endif
|
---|
1148 |
|
---|
1149 | #define cpu_init cpu_x86_init
|
---|
1150 | #define cpu_exec cpu_x86_exec
|
---|
1151 | #define cpu_gen_code cpu_x86_gen_code
|
---|
1152 | #define cpu_signal_handler cpu_x86_signal_handler
|
---|
1153 | #define cpu_list_id x86_cpu_list
|
---|
1154 | #define cpudef_setup x86_cpudef_setup
|
---|
1155 |
|
---|
1156 | #define CPU_SAVE_VERSION 12
|
---|
1157 |
|
---|
1158 | /* MMU modes definitions */
|
---|
1159 | #define MMU_MODE0_SUFFIX _kernel
|
---|
1160 | #define MMU_MODE1_SUFFIX _user
|
---|
1161 | #define MMU_USER_IDX 1
|
---|
1162 | static inline int cpu_mmu_index (CPUState *env)
|
---|
1163 | {
|
---|
1164 | return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
|
---|
1165 | }
|
---|
1166 |
|
---|
1167 | /* translate.c */
|
---|
1168 | void optimize_flags_init(void);
|
---|
1169 |
|
---|
1170 | typedef struct CCTable {
|
---|
1171 | int (*compute_all)(void); /* return all the flags */
|
---|
1172 | int (*compute_c)(void); /* return the C flag */
|
---|
1173 | } CCTable;
|
---|
1174 |
|
---|
1175 | #if defined(CONFIG_USER_ONLY)
|
---|
1176 | static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
|
---|
1177 | {
|
---|
1178 | if (newsp)
|
---|
1179 | env->regs[R_ESP] = newsp;
|
---|
1180 | env->regs[R_EAX] = 0;
|
---|
1181 | }
|
---|
1182 | #endif
|
---|
1183 |
|
---|
1184 | #include "cpu-all.h"
|
---|
1185 | #include "svm.h"
|
---|
1186 |
|
---|
1187 | #ifndef VBOX
|
---|
1188 | #if !defined(CONFIG_USER_ONLY)
|
---|
1189 | #include "hw/apic.h"
|
---|
1190 | #endif
|
---|
1191 | #else /* VBOX */
|
---|
1192 | extern void cpu_set_apic_tpr(CPUX86State *env, uint8_t val);
|
---|
1193 | extern uint8_t cpu_get_apic_tpr(CPUX86State *env);
|
---|
1194 | extern uint64_t cpu_get_apic_base(CPUX86State *env);
|
---|
1195 | #endif /* VBOX */
|
---|
1196 |
|
---|
1197 | static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
|
---|
1198 | target_ulong *cs_base, int *flags)
|
---|
1199 | {
|
---|
1200 | *cs_base = env->segs[R_CS].base;
|
---|
1201 | if (env->hflags & HF_CS64_MASK)
|
---|
1202 | *pc = *cs_base + env->eip;
|
---|
1203 | else
|
---|
1204 | *pc = (uint32_t)(*cs_base + env->eip);
|
---|
1205 | *flags = env->hflags |
|
---|
1206 | (env->eflags & (IOPL_MASK | TF_MASK | RF_MASK | VM_MASK));
|
---|
1207 | }
|
---|
1208 |
|
---|
1209 | #ifndef VBOX
|
---|
1210 | void apic_init_reset(CPUState *env);
|
---|
1211 | void apic_sipi(CPUState *env);
|
---|
1212 | void do_cpu_init(CPUState *env);
|
---|
1213 | void do_cpu_sipi(CPUState *env);
|
---|
1214 | #endif /* !VBOX */
|
---|
1215 | #endif /* CPU_I386_H */
|
---|