20 |
#ifndef CPU_I386_H |
#ifndef CPU_I386_H |
21 |
#define CPU_I386_H |
#define CPU_I386_H |
22 |
|
|
23 |
|
#include "config.h" |
24 |
|
|
25 |
|
#ifdef TARGET_X86_64 |
26 |
|
#define TARGET_LONG_BITS 64 |
27 |
|
#else |
28 |
#define TARGET_LONG_BITS 32 |
#define TARGET_LONG_BITS 32 |
29 |
|
#endif |
30 |
|
|
31 |
/* target supports implicit self modifying code */ |
/* target supports implicit self modifying code */ |
32 |
#define TARGET_HAS_SMC |
#define TARGET_HAS_SMC |
69 |
#define DESC_G_MASK (1 << 23) |
#define DESC_G_MASK (1 << 23) |
70 |
#define DESC_B_SHIFT 22 |
#define DESC_B_SHIFT 22 |
71 |
#define DESC_B_MASK (1 << DESC_B_SHIFT) |
#define DESC_B_MASK (1 << DESC_B_SHIFT) |
72 |
|
#define DESC_L_SHIFT 21 /* x86_64 only : 64 bit code segment */ |
73 |
|
#define DESC_L_MASK (1 << DESC_L_SHIFT) |
74 |
#define DESC_AVL_MASK (1 << 20) |
#define DESC_AVL_MASK (1 << 20) |
75 |
#define DESC_P_MASK (1 << 15) |
#define DESC_P_MASK (1 << 15) |
76 |
#define DESC_DPL_SHIFT 13 |
#define DESC_DPL_SHIFT 13 |
133 |
#define HF_EM_SHIFT 10 |
#define HF_EM_SHIFT 10 |
134 |
#define HF_TS_SHIFT 11 |
#define HF_TS_SHIFT 11 |
135 |
#define HF_IOPL_SHIFT 12 /* must be same as eflags */ |
#define HF_IOPL_SHIFT 12 /* must be same as eflags */ |
136 |
|
#define HF_LMA_SHIFT 14 /* only used on x86_64: long mode active */ |
137 |
|
#define HF_CS64_SHIFT 15 /* only used on x86_64: 64 bit code segment */ |
138 |
#define HF_VM_SHIFT 17 /* must be same as eflags */ |
#define HF_VM_SHIFT 17 /* must be same as eflags */ |
139 |
|
|
140 |
#define HF_CPL_MASK (3 << HF_CPL_SHIFT) |
#define HF_CPL_MASK (3 << HF_CPL_SHIFT) |
148 |
#define HF_MP_MASK (1 << HF_MP_SHIFT) |
#define HF_MP_MASK (1 << HF_MP_SHIFT) |
149 |
#define HF_EM_MASK (1 << HF_EM_SHIFT) |
#define HF_EM_MASK (1 << HF_EM_SHIFT) |
150 |
#define HF_TS_MASK (1 << HF_TS_SHIFT) |
#define HF_TS_MASK (1 << HF_TS_SHIFT) |
151 |
|
#define HF_LMA_MASK (1 << HF_LMA_SHIFT) |
152 |
|
#define HF_CS64_MASK (1 << HF_CS64_SHIFT) |
153 |
|
|
154 |
#define CR0_PE_MASK (1 << 0) |
#define CR0_PE_MASK (1 << 0) |
155 |
#define CR0_MP_MASK (1 << 1) |
#define CR0_MP_MASK (1 << 1) |
168 |
#define CR4_PSE_MASK (1 << 4) |
#define CR4_PSE_MASK (1 << 4) |
169 |
#define CR4_PAE_MASK (1 << 5) |
#define CR4_PAE_MASK (1 << 5) |
170 |
#define CR4_PGE_MASK (1 << 7) |
#define CR4_PGE_MASK (1 << 7) |
171 |
|
#define CR4_PCE_MASK (1 << 8) |
172 |
|
#define CR4_OSFXSR_MASK (1 << 9) |
173 |
|
#define CR4_OSXMMEXCPT_MASK (1 << 10) |
174 |
|
|
175 |
#define PG_PRESENT_BIT 0 |
#define PG_PRESENT_BIT 0 |
176 |
#define PG_RW_BIT 1 |
#define PG_RW_BIT 1 |
208 |
#define MSR_IA32_SYSENTER_ESP 0x175 |
#define MSR_IA32_SYSENTER_ESP 0x175 |
209 |
#define MSR_IA32_SYSENTER_EIP 0x176 |
#define MSR_IA32_SYSENTER_EIP 0x176 |
210 |
|
|
211 |
|
#define MSR_EFER 0xc0000080 |
212 |
|
|
213 |
|
#define MSR_EFER_SCE (1 << 0) |
214 |
|
#define MSR_EFER_LME (1 << 8) |
215 |
|
#define MSR_EFER_LMA (1 << 10) |
216 |
|
#define MSR_EFER_NXE (1 << 11) |
217 |
|
#define MSR_EFER_FFXSR (1 << 14) |
218 |
|
|
219 |
|
#define MSR_STAR 0xc0000081 |
220 |
|
#define MSR_LSTAR 0xc0000082 |
221 |
|
#define MSR_CSTAR 0xc0000083 |
222 |
|
#define MSR_FMASK 0xc0000084 |
223 |
|
#define MSR_FSBASE 0xc0000100 |
224 |
|
#define MSR_GSBASE 0xc0000101 |
225 |
|
#define MSR_KERNELGSBASE 0xc0000102 |
226 |
|
|
227 |
|
/* cpuid_features bits */ |
228 |
|
#define CPUID_FP87 (1 << 0) |
229 |
|
#define CPUID_VME (1 << 1) |
230 |
|
#define CPUID_DE (1 << 2) |
231 |
|
#define CPUID_PSE (1 << 3) |
232 |
|
#define CPUID_TSC (1 << 4) |
233 |
|
#define CPUID_MSR (1 << 5) |
234 |
|
#define CPUID_PAE (1 << 6) |
235 |
|
#define CPUID_MCE (1 << 7) |
236 |
|
#define CPUID_CX8 (1 << 8) |
237 |
|
#define CPUID_APIC (1 << 9) |
238 |
|
#define CPUID_SEP (1 << 11) /* sysenter/sysexit */ |
239 |
|
#define CPUID_MTRR (1 << 12) |
240 |
|
#define CPUID_PGE (1 << 13) |
241 |
|
#define CPUID_MCA (1 << 14) |
242 |
|
#define CPUID_CMOV (1 << 15) |
243 |
|
/* ... */ |
244 |
|
#define CPUID_MMX (1 << 23) |
245 |
|
#define CPUID_FXSR (1 << 24) |
246 |
|
#define CPUID_SSE (1 << 25) |
247 |
|
#define CPUID_SSE2 (1 << 26) |
248 |
|
|
249 |
#define EXCP00_DIVZ 0 |
#define EXCP00_DIVZ 0 |
250 |
#define EXCP01_SSTP 1 |
#define EXCP01_SSTP 1 |
251 |
#define EXCP02_NMI 2 |
#define EXCP02_NMI 2 |
272 |
CC_OP_MULB, /* modify all flags, C, O = (CC_SRC != 0) */ |
CC_OP_MULB, /* modify all flags, C, O = (CC_SRC != 0) */ |
273 |
CC_OP_MULW, |
CC_OP_MULW, |
274 |
CC_OP_MULL, |
CC_OP_MULL, |
275 |
|
CC_OP_MULQ, |
276 |
|
|
277 |
CC_OP_ADDB, /* modify all flags, CC_DST = res, CC_SRC = src1 */ |
CC_OP_ADDB, /* modify all flags, CC_DST = res, CC_SRC = src1 */ |
278 |
CC_OP_ADDW, |
CC_OP_ADDW, |
279 |
CC_OP_ADDL, |
CC_OP_ADDL, |
280 |
|
CC_OP_ADDQ, |
281 |
|
|
282 |
CC_OP_ADCB, /* modify all flags, CC_DST = res, CC_SRC = src1 */ |
CC_OP_ADCB, /* modify all flags, CC_DST = res, CC_SRC = src1 */ |
283 |
CC_OP_ADCW, |
CC_OP_ADCW, |
284 |
CC_OP_ADCL, |
CC_OP_ADCL, |
285 |
|
CC_OP_ADCQ, |
286 |
|
|
287 |
CC_OP_SUBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */ |
CC_OP_SUBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */ |
288 |
CC_OP_SUBW, |
CC_OP_SUBW, |
289 |
CC_OP_SUBL, |
CC_OP_SUBL, |
290 |
|
CC_OP_SUBQ, |
291 |
|
|
292 |
CC_OP_SBBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */ |
CC_OP_SBBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */ |
293 |
CC_OP_SBBW, |
CC_OP_SBBW, |
294 |
CC_OP_SBBL, |
CC_OP_SBBL, |
295 |
|
CC_OP_SBBQ, |
296 |
|
|
297 |
CC_OP_LOGICB, /* modify all flags, CC_DST = res */ |
CC_OP_LOGICB, /* modify all flags, CC_DST = res */ |
298 |
CC_OP_LOGICW, |
CC_OP_LOGICW, |
299 |
CC_OP_LOGICL, |
CC_OP_LOGICL, |
300 |
|
CC_OP_LOGICQ, |
301 |
|
|
302 |
CC_OP_INCB, /* modify all flags except, CC_DST = res, CC_SRC = C */ |
CC_OP_INCB, /* modify all flags except, CC_DST = res, CC_SRC = C */ |
303 |
CC_OP_INCW, |
CC_OP_INCW, |
304 |
CC_OP_INCL, |
CC_OP_INCL, |
305 |
|
CC_OP_INCQ, |
306 |
|
|
307 |
CC_OP_DECB, /* modify all flags except, CC_DST = res, CC_SRC = C */ |
CC_OP_DECB, /* modify all flags except, CC_DST = res, CC_SRC = C */ |
308 |
CC_OP_DECW, |
CC_OP_DECW, |
309 |
CC_OP_DECL, |
CC_OP_DECL, |
310 |
|
CC_OP_DECQ, |
311 |
|
|
312 |
CC_OP_SHLB, /* modify all flags, CC_DST = res, CC_SRC.msb = C */ |
CC_OP_SHLB, /* modify all flags, CC_DST = res, CC_SRC.msb = C */ |
313 |
CC_OP_SHLW, |
CC_OP_SHLW, |
314 |
CC_OP_SHLL, |
CC_OP_SHLL, |
315 |
|
CC_OP_SHLQ, |
316 |
|
|
317 |
CC_OP_SARB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */ |
CC_OP_SARB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */ |
318 |
CC_OP_SARW, |
CC_OP_SARW, |
319 |
CC_OP_SARL, |
CC_OP_SARL, |
320 |
|
CC_OP_SARQ, |
321 |
|
|
322 |
CC_OP_NB, |
CC_OP_NB, |
323 |
}; |
}; |
334 |
|
|
335 |
typedef struct SegmentCache { |
typedef struct SegmentCache { |
336 |
uint32_t selector; |
uint32_t selector; |
337 |
uint8_t *base; |
target_ulong base; |
338 |
uint32_t limit; |
uint32_t limit; |
339 |
uint32_t flags; |
uint32_t flags; |
340 |
} SegmentCache; |
} SegmentCache; |
341 |
|
|
342 |
|
typedef struct { |
343 |
|
union { |
344 |
|
uint8_t b[16]; |
345 |
|
uint16_t w[8]; |
346 |
|
uint32_t l[4]; |
347 |
|
uint64_t q[2]; |
348 |
|
} u; |
349 |
|
} XMMReg; |
350 |
|
|
351 |
|
#ifdef TARGET_X86_64 |
352 |
|
#define CPU_NB_REGS 16 |
353 |
|
#else |
354 |
|
#define CPU_NB_REGS 8 |
355 |
|
#endif |
356 |
|
|
357 |
typedef struct CPUX86State { |
typedef struct CPUX86State { |
358 |
|
#if TARGET_LONG_BITS > HOST_LONG_BITS |
359 |
|
/* temporaries if we cannot store them in host registers */ |
360 |
|
target_ulong t0, t1, t2; |
361 |
|
#endif |
362 |
|
|
363 |
/* standard registers */ |
/* standard registers */ |
364 |
uint32_t regs[8]; |
target_ulong regs[CPU_NB_REGS]; |
365 |
uint32_t eip; |
target_ulong eip; |
366 |
uint32_t eflags; /* eflags register. During CPU emulation, CC |
target_ulong eflags; /* eflags register. During CPU emulation, CC |
367 |
flags and DF are set to zero because they are |
flags and DF are set to zero because they are |
368 |
stored elsewhere */ |
stored elsewhere */ |
369 |
|
|
370 |
/* emulator internal eflags handling */ |
/* emulator internal eflags handling */ |
371 |
uint32_t cc_src; |
target_ulong cc_src; |
372 |
uint32_t cc_dst; |
target_ulong cc_dst; |
373 |
uint32_t cc_op; |
uint32_t cc_op; |
374 |
int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */ |
int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */ |
375 |
uint32_t hflags; /* hidden flags, see HF_xxx constants */ |
uint32_t hflags; /* hidden flags, see HF_xxx constants */ |
397 |
SegmentCache gdt; /* only base and limit are used */ |
SegmentCache gdt; /* only base and limit are used */ |
398 |
SegmentCache idt; /* only base and limit are used */ |
SegmentCache idt; /* only base and limit are used */ |
399 |
|
|
400 |
|
XMMReg xmm_regs[CPU_NB_REGS]; |
401 |
|
XMMReg xmm_t0; |
402 |
|
|
403 |
/* sysenter registers */ |
/* sysenter registers */ |
404 |
uint32_t sysenter_cs; |
uint32_t sysenter_cs; |
405 |
uint32_t sysenter_esp; |
uint32_t sysenter_esp; |
406 |
uint32_t sysenter_eip; |
uint32_t sysenter_eip; |
407 |
|
#ifdef TARGET_X86_64 |
408 |
|
target_ulong efer; |
409 |
|
target_ulong star; |
410 |
|
target_ulong lstar; |
411 |
|
target_ulong cstar; |
412 |
|
target_ulong fmask; |
413 |
|
target_ulong kernelgsbase; |
414 |
|
#endif |
415 |
|
|
416 |
/* temporary data for USE_CODE_COPY mode */ |
/* temporary data for USE_CODE_COPY mode */ |
417 |
#ifdef USE_CODE_COPY |
#ifdef USE_CODE_COPY |
427 |
int exception_is_int; |
int exception_is_int; |
428 |
int exception_next_eip; |
int exception_next_eip; |
429 |
struct TranslationBlock *current_tb; /* currently executing TB */ |
struct TranslationBlock *current_tb; /* currently executing TB */ |
430 |
uint32_t cr[5]; /* NOTE: cr1 is unused */ |
target_ulong cr[5]; /* NOTE: cr1 is unused */ |
431 |
uint32_t dr[8]; /* debug registers */ |
target_ulong dr[8]; /* debug registers */ |
432 |
int interrupt_request; |
int interrupt_request; |
433 |
int user_mode_only; /* user mode only simulation */ |
int user_mode_only; /* user mode only simulation */ |
434 |
|
|
440 |
context) */ |
context) */ |
441 |
unsigned long mem_write_pc; /* host pc at which the memory was |
unsigned long mem_write_pc; /* host pc at which the memory was |
442 |
written */ |
written */ |
443 |
unsigned long mem_write_vaddr; /* target virtual addr at which the |
target_ulong mem_write_vaddr; /* target virtual addr at which the |
444 |
memory was written */ |
memory was written */ |
445 |
/* 0 = kernel, 1 = user */ |
/* 0 = kernel, 1 = user */ |
446 |
CPUTLBEntry tlb_read[2][CPU_TLB_SIZE]; |
CPUTLBEntry tlb_read[2][CPU_TLB_SIZE]; |
447 |
CPUTLBEntry tlb_write[2][CPU_TLB_SIZE]; |
CPUTLBEntry tlb_write[2][CPU_TLB_SIZE]; |
448 |
|
|
449 |
/* from this point: preserved by CPU reset */ |
/* from this point: preserved by CPU reset */ |
450 |
/* ice debug support */ |
/* ice debug support */ |
451 |
uint32_t breakpoints[MAX_BREAKPOINTS]; |
target_ulong breakpoints[MAX_BREAKPOINTS]; |
452 |
int nb_breakpoints; |
int nb_breakpoints; |
453 |
int singlestep_enabled; |
int singlestep_enabled; |
454 |
|
|
455 |
|
/* processor features (e.g. for CPUID insn) */ |
456 |
|
uint32_t cpuid_vendor1; |
457 |
|
uint32_t cpuid_vendor2; |
458 |
|
uint32_t cpuid_vendor3; |
459 |
|
uint32_t cpuid_version; |
460 |
|
uint32_t cpuid_features; |
461 |
|
|
462 |
|
/* in order to simplify APIC support, we leave this pointer to the |
463 |
|
user */ |
464 |
|
struct APICState *apic_state; |
465 |
/* user data */ |
/* user data */ |
466 |
void *opaque; |
void *opaque; |
467 |
} CPUX86State; |
} CPUX86State; |
486 |
cache: it synchronizes the hflags with the segment cache values */ |
cache: it synchronizes the hflags with the segment cache values */ |
487 |
static inline void cpu_x86_load_seg_cache(CPUX86State *env, |
static inline void cpu_x86_load_seg_cache(CPUX86State *env, |
488 |
int seg_reg, unsigned int selector, |
int seg_reg, unsigned int selector, |
489 |
uint8_t *base, unsigned int limit, |
uint32_t base, unsigned int limit, |
490 |
unsigned int flags) |
unsigned int flags) |
491 |
{ |
{ |
492 |
SegmentCache *sc; |
SegmentCache *sc; |
499 |
sc->flags = flags; |
sc->flags = flags; |
500 |
|
|
501 |
/* update the hidden flags */ |
/* update the hidden flags */ |
502 |
new_hflags = (env->segs[R_CS].flags & DESC_B_MASK) |
{ |
503 |
>> (DESC_B_SHIFT - HF_CS32_SHIFT); |
if (seg_reg == R_CS) { |
504 |
new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK) |
#ifdef TARGET_X86_64 |
505 |
>> (DESC_B_SHIFT - HF_SS32_SHIFT); |
if ((env->hflags & HF_LMA_MASK) && (flags & DESC_L_MASK)) { |
506 |
if (!(env->cr[0] & CR0_PE_MASK) || |
/* long mode */ |
507 |
(env->eflags & VM_MASK) || |
env->hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK; |
508 |
!(new_hflags & HF_CS32_MASK)) { |
env->hflags &= ~(HF_ADDSEG_MASK); |
509 |
/* XXX: try to avoid this test. The problem comes from the |
} else |
510 |
fact that is real mode or vm86 mode we only modify the |
#endif |
511 |
'base' and 'selector' fields of the segment cache to go |
{ |
512 |
faster. A solution may be to force addseg to one in |
/* legacy / compatibility case */ |
513 |
translate-i386.c. */ |
new_hflags = (env->segs[R_CS].flags & DESC_B_MASK) |
514 |
new_hflags |= HF_ADDSEG_MASK; |
>> (DESC_B_SHIFT - HF_CS32_SHIFT); |
515 |
} else { |
env->hflags = (env->hflags & ~(HF_CS32_MASK | HF_CS64_MASK)) | |
516 |
new_hflags |= (((unsigned long)env->segs[R_DS].base | |
new_hflags; |
517 |
(unsigned long)env->segs[R_ES].base | |
} |
518 |
(unsigned long)env->segs[R_SS].base) != 0) << |
} |
519 |
HF_ADDSEG_SHIFT; |
new_hflags = (env->segs[R_SS].flags & DESC_B_MASK) |
520 |
|
>> (DESC_B_SHIFT - HF_SS32_SHIFT); |
521 |
|
if (env->hflags & HF_CS64_MASK) { |
522 |
|
/* zero base assumed for DS, ES and SS in long mode */ |
523 |
|
} else if (!(env->cr[0] & CR0_PE_MASK) || |
524 |
|
(env->eflags & VM_MASK) || |
525 |
|
!(new_hflags & HF_CS32_MASK)) { |
526 |
|
/* XXX: try to avoid this test. The problem comes from the |
527 |
|
fact that is real mode or vm86 mode we only modify the |
528 |
|
'base' and 'selector' fields of the segment cache to go |
529 |
|
faster. A solution may be to force addseg to one in |
530 |
|
translate-i386.c. */ |
531 |
|
new_hflags |= HF_ADDSEG_MASK; |
532 |
|
} else { |
533 |
|
new_hflags |= (((unsigned long)env->segs[R_DS].base | |
534 |
|
(unsigned long)env->segs[R_ES].base | |
535 |
|
(unsigned long)env->segs[R_SS].base) != 0) << |
536 |
|
HF_ADDSEG_SHIFT; |
537 |
|
} |
538 |
|
env->hflags = (env->hflags & |
539 |
|
~(HF_SS32_MASK | HF_ADDSEG_MASK)) | new_hflags; |
540 |
} |
} |
|
env->hflags = (env->hflags & |
|
|
~(HF_CS32_MASK | HF_SS32_MASK | HF_ADDSEG_MASK)) | new_hflags; |
|
541 |
} |
} |
542 |
|
|
543 |
/* wrapper, just in case memory mappings must be changed */ |
/* wrapper, just in case memory mappings must be changed */ |
570 |
|
|
571 |
uint64_t cpu_get_tsc(CPUX86State *env); |
uint64_t cpu_get_tsc(CPUX86State *env); |
572 |
|
|
573 |
|
void cpu_set_apic_base(CPUX86State *env, uint64_t val); |
574 |
|
uint64_t cpu_get_apic_base(CPUX86State *env); |
575 |
|
|
576 |
/* will be suppressed */ |
/* will be suppressed */ |
577 |
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0); |
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0); |
578 |
|
|