/[qemu]/qemu/target-i386/cpu.h
ViewVC logotype

Diff of /qemu/target-i386/cpu.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.19 by bellard, Sat Oct 9 18:08:01 2004 UTC revision 1.20 by bellard, Mon Jan 3 23:50:08 2005 UTC
# Line 20  Line 20 
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
# Line 63  Line 69 
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
# Line 125  Line 133 
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)
# Line 138  Line 148 
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)
# Line 156  Line 168 
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
# Line 193  Line 208 
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
# Line 219  enum { Line 272  enum {
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  };  };
# Line 271  typedef double CPU86_LDouble; Line 334  typedef double CPU86_LDouble;
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 */
# Line 314  typedef struct CPUX86State { Line 397  typedef struct CPUX86State {
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
# Line 333  typedef struct CPUX86State { Line 427  typedef struct CPUX86State {
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    
# Line 346  typedef struct CPUX86State { Line 440  typedef struct CPUX86State {
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;
# Line 382  void cpu_set_ferr(CPUX86State *s); Line 486  void cpu_set_ferr(CPUX86State *s);
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;
# Line 395  static inline void cpu_x86_load_seg_cach Line 499  static inline void cpu_x86_load_seg_cach
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 */
# Line 448  void cpu_x86_set_a20(CPUX86State *env, i Line 570  void cpu_x86_set_a20(CPUX86State *env, i
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    

Legend:
Removed from v.1.19  
changed lines
  Added in v.1.20

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26