|
|
| version 1.13, 2004/02/04 13:24:35 | version 1.19, 2004/02/20 16:09:04 |
|---|---|
| Line 32 | Line 32 |
| Copyright by Yui/Studio Milmake 1999-2000 | Copyright by Yui/Studio Milmake 1999-2000 |
| Copyright by Norio HATTORI 2000,2001 | Copyright by Norio HATTORI 2000,2001 |
| Copyright by NONAKA Kimihiro 2002-2003 | Copyright by NONAKA Kimihiro 2002-2004 |
| */ | */ |
| #ifndef IA32_CPU_CPU_H__ | #ifndef IA32_CPU_CPU_H__ |
| Line 47 extern "C" { | Line 47 extern "C" { |
| typedef union { | typedef union { |
| #if defined(BYTESEX_LITTLE) | #if defined(BYTESEX_LITTLE) |
| struct { | struct { |
| BYTE l; | UINT8 l; |
| BYTE h; | UINT8 h; |
| BYTE _hl; | UINT8 _hl; |
| BYTE _hh; | UINT8 _hh; |
| } b; | } b; |
| struct { | struct { |
| WORD w; | UINT16 w; |
| WORD _hw; | UINT16 _hw; |
| } w; | } w; |
| #elif defined(BYTESEX_BIG) | #elif defined(BYTESEX_BIG) |
| struct { | struct { |
| BYTE _hh; | UINT8 _hh; |
| BYTE _hl; | UINT8 _hl; |
| BYTE h; | UINT8 h; |
| BYTE l; | UINT8 l; |
| } b; | } b; |
| struct { | struct { |
| WORD _hw; | UINT16 _hw; |
| WORD w; | UINT16 w; |
| } w; | } w; |
| #endif | #endif |
| DWORD d; | UINT32 d; |
| } REG32; | } REG32; |
| #ifdef __cplusplus | #ifdef __cplusplus |
| Line 118 enum { | Line 118 enum { |
| typedef struct { | typedef struct { |
| REG32 reg[CPU_REG_NUM]; | REG32 reg[CPU_REG_NUM]; |
| WORD sreg[CPU_SEGREG_NUM]; | UINT16 sreg[CPU_SEGREG_NUM]; |
| REG32 eflags; | REG32 eflags; |
| REG32 eip; | REG32 eip; |
| Line 126 typedef struct { | Line 126 typedef struct { |
| REG32 prev_eip; | REG32 prev_eip; |
| REG32 prev_esp; | REG32 prev_esp; |
| DWORD tr[CPU_TEST_REG_NUM]; | UINT32 tr[CPU_TEST_REG_NUM]; |
| DWORD dr[CPU_DEBUG_REG_NUM]; | UINT32 dr[CPU_DEBUG_REG_NUM]; |
| } CPU_REGS; | } CPU_REGS; |
| typedef struct { | typedef struct { |
| WORD gdtr_limit; | UINT16 gdtr_limit; |
| DWORD gdtr_base; | UINT32 gdtr_base; |
| WORD idtr_limit; | UINT16 idtr_limit; |
| DWORD idtr_base; | UINT32 idtr_base; |
| WORD ldtr; | UINT16 ldtr; |
| WORD tr; | UINT16 tr; |
| DWORD cr0; | UINT32 cr0; |
| DWORD cr1; | UINT32 cr1; |
| DWORD cr2; | UINT32 cr2; |
| DWORD cr3; | UINT32 cr3; |
| DWORD cr4; | UINT32 cr4; |
| DWORD mxcsr; | UINT32 mxcsr; |
| } CPU_SYSREGS; | } CPU_SYSREGS; |
| typedef struct { | typedef struct { |
| descriptor_t sreg[CPU_SEGREG_NUM]; | descriptor_t sreg[CPU_SEGREG_NUM]; |
| descriptor_t ldtr_desc; | descriptor_t ldtr; |
| descriptor_t tr_desc; | descriptor_t tr; |
| UINT32 adrsmask; | UINT32 adrsmask; |
| DWORD ovflag; | UINT32 ovflag; |
| BYTE ss_32; | UINT8 ss_32; |
| BYTE resetreq; | UINT8 resetreq; |
| BYTE trap; | UINT8 trap; |
| BYTE _dummy; | |
| BYTE cpl; | UINT8 page_wp; |
| BYTE protected_mode; | |
| BYTE paging; | |
| BYTE vm86; | |
| DWORD pde_base; | UINT8 protected_mode; |
| UINT8 paging; | |
| UINT8 vm86; | |
| UINT8 user_mode; | |
| DWORD ioaddr; /* I/O bitmap linear address */ | UINT8 hlt; |
| WORD iolimit; /* I/O bitmap count */ | UINT8 pad[3]; |
| BYTE nerror; /* double fault/ triple fault */ | UINT32 pde_base; |
| BYTE prev_exception; | |
| UINT32 ioaddr; /* I/O bitmap linear address */ | |
| UINT16 iolimit; /* I/O bitmap count */ | |
| UINT8 nerror; /* double fault/ triple fault */ | |
| UINT8 prev_exception; | |
| } CPU_STAT; | } CPU_STAT; |
| typedef struct { | typedef struct { |
| BYTE op_32; | UINT8 op_32; |
| BYTE as_32; | UINT8 as_32; |
| BYTE rep_used; | UINT8 rep_used; |
| BYTE seg_used; | UINT8 seg_used; |
| DWORD seg_base; | UINT32 seg_base; |
| } CPU_INST; | } CPU_INST; |
| typedef struct { | typedef struct { |
| Line 229 extern I386CORE i386core; | Line 233 extern I386CORE i386core; |
| #define CPU_EXTMEMSIZE i386core.e.extsize | #define CPU_EXTMEMSIZE i386core.e.extsize |
| #define CPU_INPADRS i386core.e.inport | #define CPU_INPADRS i386core.e.inport |
| extern BYTE iflags[]; | |
| extern sigjmp_buf exec_1step_jmpbuf; | extern sigjmp_buf exec_1step_jmpbuf; |
| Line 353 do { \ | Line 356 do { \ |
| #define CPU_FS CPU_REGS_SREG(CPU_FS_INDEX) | #define CPU_FS CPU_REGS_SREG(CPU_FS_INDEX) |
| #define CPU_GS CPU_REGS_SREG(CPU_GS_INDEX) | #define CPU_GS CPU_REGS_SREG(CPU_GS_INDEX) |
| #define ES_BASE CPU_STATSAVE.cpu_stat.sreg[CPU_ES_INDEX].u.seg.segbase | #define ES_BASE CPU_STAT_SREGBASE(CPU_ES_INDEX) |
| #define CS_BASE CPU_STATSAVE.cpu_stat.sreg[CPU_CS_INDEX].u.seg.segbase | #define CS_BASE CPU_STAT_SREGBASE(CPU_CS_INDEX) |
| #define SS_BASE CPU_STATSAVE.cpu_stat.sreg[CPU_SS_INDEX].u.seg.segbase | #define SS_BASE CPU_STAT_SREGBASE(CPU_SS_INDEX) |
| #define DS_BASE CPU_STATSAVE.cpu_stat.sreg[CPU_DS_INDEX].u.seg.segbase | #define DS_BASE CPU_STAT_SREGBASE(CPU_DS_INDEX) |
| #define FS_BASE CPU_STATSAVE.cpu_stat.sreg[CPU_FS_INDEX].u.seg.segbase | #define FS_BASE CPU_STAT_SREGBASE(CPU_FS_INDEX) |
| #define GS_BASE CPU_STATSAVE.cpu_stat.sreg[CPU_GS_INDEX].u.seg.segbase | #define GS_BASE CPU_STAT_SREGBASE(CPU_GS_INDEX) |
| #define CPU_EFLAG CPU_STATSAVE.cpu_regs.eflags.d | #define CPU_EFLAG CPU_STATSAVE.cpu_regs.eflags.d |
| #define CPU_FLAG CPU_STATSAVE.cpu_regs.eflags.w.w | #define CPU_FLAG CPU_STATSAVE.cpu_regs.eflags.w.w |
| #define CPU_FLAGL CPU_STATSAVE.cpu_regs.eflags.b.l | #define CPU_FLAGL CPU_STATSAVE.cpu_regs.eflags.b.l |
| #define CPU_FLAGH CPU_STATSAVE.cpu_regs.eflags.b.h | #define CPU_FLAGH CPU_STATSAVE.cpu_regs.eflags.b.h |
| #define CPU_TRAP CPU_STATSAVE.cpu_stat.trap | #define CPU_TRAP CPU_STATSAVE.cpu_stat.trap |
| #if 0 | |
| #define CPU_INPORT CPU_STATSAVE.cpu_stat.inport | #define CPU_INPORT CPU_STATSAVE.cpu_stat.inport |
| #endif | |
| #define CPU_OV CPU_STATSAVE.cpu_stat.ovflag | #define CPU_OV CPU_STATSAVE.cpu_stat.ovflag |
| #define C_FLAG (1 << 0) | #define C_FLAG (1 << 0) |
| Line 397 do { \ | Line 398 do { \ |
| #define REAL_FLAGREG ((CPU_FLAG & 0xf7ff) | (CPU_OV ? O_FLAG : 0)) | #define REAL_FLAGREG ((CPU_FLAG & 0xf7ff) | (CPU_OV ? O_FLAG : 0)) |
| #define REAL_EFLAGREG ((CPU_EFLAG & 0xfffff7ff) | (CPU_OV ? O_FLAG : 0)) | #define REAL_EFLAGREG ((CPU_EFLAG & 0xfffff7ff) | (CPU_OV ? O_FLAG : 0)) |
| void set_flags(WORD new_flags, WORD mask); | void set_flags(UINT16 new_flags, UINT16 mask); |
| void set_eflags(DWORD new_flags, DWORD mask); | void set_eflags(UINT32 new_flags, UINT32 mask); |
| #define CPU_INST_OP32 CPU_STATSAVE.cpu_inst.op_32 | #define CPU_INST_OP32 CPU_STATSAVE.cpu_inst.op_32 |
| Line 409 void set_eflags(DWORD new_flags, DWORD m | Line 410 void set_eflags(DWORD new_flags, DWORD m |
| #define DS_FIX (!CPU_INST_SEGUSE ? CPU_DS_INDEX : CPU_INST_SEGREG_INDEX) | #define DS_FIX (!CPU_INST_SEGUSE ? CPU_DS_INDEX : CPU_INST_SEGREG_INDEX) |
| #define SS_FIX (!CPU_INST_SEGUSE ? CPU_SS_INDEX : CPU_INST_SEGREG_INDEX) | #define SS_FIX (!CPU_INST_SEGUSE ? CPU_SS_INDEX : CPU_INST_SEGREG_INDEX) |
| #define CPU_STAT_CS_BASE CPU_STATSAVE.cpu_stat.sreg[CPU_CS_INDEX].u.seg.limit | #define CPU_STAT_CS_BASE CPU_STAT_SREGBASE(CPU_CS_INDEX) |
| #define CPU_STAT_CS_LIMIT CPU_STATSAVE.cpu_stat.sreg[CPU_CS_INDEX].u.seg.limit | #define CPU_STAT_CS_LIMIT CPU_STAT_SREGLIMIT(CPU_CS_INDEX) |
| #define CPU_STAT_CS_END CPU_STATSAVE.cpu_stat.sreg[CPU_CS_INDEX].u.seg.segend | #define CPU_STAT_CS_END CPU_STAT_SREGEND(CPU_CS_INDEX) |
| #define CPU_STAT_ADRSMASK CPU_STATSAVE.cpu_stat.adrsmask | #define CPU_STAT_ADRSMASK CPU_STATSAVE.cpu_stat.adrsmask |
| #define CPU_STAT_SS32 CPU_STATSAVE.cpu_stat.ss_32 | #define CPU_STAT_SS32 CPU_STATSAVE.cpu_stat.ss_32 |
| #define CPU_STAT_RESETREQ CPU_STATSAVE.cpu_stat.resetreq | #define CPU_STAT_RESETREQ CPU_STATSAVE.cpu_stat.resetreq |
| #define CPU_STAT_PM CPU_STATSAVE.cpu_stat.protected_mode | #define CPU_STAT_PM CPU_STATSAVE.cpu_stat.protected_mode |
| #define CPU_STAT_VM86 CPU_STATSAVE.cpu_stat.vm86 | |
| #define CPU_STAT_PAGING CPU_STATSAVE.cpu_stat.paging | #define CPU_STAT_PAGING CPU_STATSAVE.cpu_stat.paging |
| #define CPU_STAT_CPL CPU_STATSAVE.cpu_stat.cpl | #define CPU_STAT_VM86 CPU_STATSAVE.cpu_stat.vm86 |
| #define CPU_STAT_WP CPU_STATSAVE.cpu_stat.page_wp | |
| #define CPU_STAT_CPL CPU_STAT_SREG(CPU_CS_INDEX).rpl | |
| #define CPU_STAT_USER_MODE CPU_STATSAVE.cpu_stat.user_mode | |
| #define CPU_STAT_PDE_BASE CPU_STATSAVE.cpu_stat.pde_base | #define CPU_STAT_PDE_BASE CPU_STATSAVE.cpu_stat.pde_base |
| #define CPU_STAT_HLT CPU_STATSAVE.cpu_stat.hlt | |
| #define CPU_STAT_IOPL ((CPU_EFLAG & IOPL_FLAG) >> 12) | #define CPU_STAT_IOPL ((CPU_EFLAG & IOPL_FLAG) >> 12) |
| #define CPU_IOPL0 0 | #define CPU_IOPL0 0 |
| #define CPU_IOPL1 1 | #define CPU_IOPL1 1 |
| Line 431 void set_eflags(DWORD new_flags, DWORD m | Line 436 void set_eflags(DWORD new_flags, DWORD m |
| #define CPU_STAT_IOADDR CPU_STATSAVE.cpu_stat.ioaddr | #define CPU_STAT_IOADDR CPU_STATSAVE.cpu_stat.ioaddr |
| #define CPU_STAT_IOLIMIT CPU_STATSAVE.cpu_stat.iolimit | #define CPU_STAT_IOLIMIT CPU_STATSAVE.cpu_stat.iolimit |
| #define CPU_STAT_NERROR CPU_STATSAVE.cpu_stat.nerror | #define CPU_STAT_PREV_EXCEPTION CPU_STATSAVE.cpu_stat.prev_exception |
| #define CPU_STAT_PREV_EXCEPTION CPU_STATSAVE.cpu_stat.prev_exception | #define CPU_STAT_EXCEPTION_COUNTER CPU_STATSAVE.cpu_stat.nerror |
| #define CPU_STAT_EXCEPTION_COUNTER_INC() CPU_STATSAVE.cpu_stat.nerror++ | |
| #define CPU_STAT_EXCEPTION_COUNTER_CLEAR() CPU_STATSAVE.cpu_stat.nerror = 0 | |
| #define CPU_MODE_SUPERVISER 0 | #define CPU_MODE_SUPERVISER 0 |
| #define CPU_MODE_USER 1 | #define CPU_MODE_USER 1 |
| #define CPU_IS_USER_MODE() ((CPU_STAT_CPL == 3) ? CPU_MODE_USER : CPU_MODE_SUPERVISER) | #define CPU_SET_CPL(cpl) \ |
| do { \ | |
| UINT8 __t = (UINT8)((cpl) & 3); \ | |
| CPU_STAT_CPL = __t; \ | |
| CPU_STAT_USER_MODE = (__t == 3) ? CPU_MODE_USER : CPU_MODE_SUPERVISER; \ | |
| } while (/*CONSTCOND*/ 0) | |
| #define CPU_CLI \ | |
| do { \ | |
| CPU_FLAG &= ~I_FLAG; \ | |
| CPU_TRAP = 0; \ | |
| } while (/*CONSTCOND*/0) | |
| #define CPU_CLI do { CPU_FLAG &= ~I_FLAG; \ | #define CPU_STI \ |
| CPU_TRAP = 0; } while (/*CONSTCOND*/ 0) | do { \ |
| #define CPU_STI do { CPU_FLAG |= I_FLAG; \ | CPU_FLAG |= I_FLAG; \ |
| CPU_TRAP = (CPU_FLAG >> 8) & 1; } while (/*CONSTCOND*/0) | CPU_TRAP = (CPU_FLAG >> 8) & 1; \ |
| } while (/*CONSTCOND*/0) | |
| #define CPU_GDTR_LIMIT CPU_STATSAVE.cpu_sysregs.gdtr_limit | #define CPU_GDTR_LIMIT CPU_STATSAVE.cpu_sysregs.gdtr_limit |
| #define CPU_GDTR_BASE CPU_STATSAVE.cpu_sysregs.gdtr_base | #define CPU_GDTR_BASE CPU_STATSAVE.cpu_sysregs.gdtr_base |
| #define CPU_IDTR_LIMIT CPU_STATSAVE.cpu_sysregs.idtr_limit | #define CPU_IDTR_LIMIT CPU_STATSAVE.cpu_sysregs.idtr_limit |
| #define CPU_IDTR_BASE CPU_STATSAVE.cpu_sysregs.idtr_base | #define CPU_IDTR_BASE CPU_STATSAVE.cpu_sysregs.idtr_base |
| #define CPU_LDTR CPU_STATSAVE.cpu_sysregs.ldtr | #define CPU_LDTR CPU_STATSAVE.cpu_sysregs.ldtr |
| #define CPU_LDTR_DESC CPU_STATSAVE.cpu_stat.ldtr_desc | #define CPU_LDTR_DESC CPU_STATSAVE.cpu_stat.ldtr |
| #define CPU_LDTR_BASE CPU_STATSAVE.cpu_stat.ldtr_desc.u.seg.segbase | #define CPU_LDTR_BASE CPU_STATSAVE.cpu_stat.ldtr.u.seg.segbase |
| #define CPU_LDTR_END CPU_STATSAVE.cpu_stat.ldtr_desc.u.seg.segend | #define CPU_LDTR_END CPU_STATSAVE.cpu_stat.ldtr.u.seg.segend |
| #define CPU_LDTR_LIMIT CPU_STATSAVE.cpu_stat.ldtr_desc.u.seg.limit | #define CPU_LDTR_LIMIT CPU_STATSAVE.cpu_stat.ldtr.u.seg.limit |
| #define CPU_TR CPU_STATSAVE.cpu_sysregs.tr | #define CPU_TR CPU_STATSAVE.cpu_sysregs.tr |
| #define CPU_TR_DESC CPU_STATSAVE.cpu_stat.tr_desc | #define CPU_TR_DESC CPU_STATSAVE.cpu_stat.tr |
| #define CPU_TR_BASE CPU_STATSAVE.cpu_stat.tr_desc.u.seg.segbase | #define CPU_TR_BASE CPU_STATSAVE.cpu_stat.tr.u.seg.segbase |
| #define CPU_TR_END CPU_STATSAVE.cpu_stat.tr_desc.u.seg.segend | #define CPU_TR_END CPU_STATSAVE.cpu_stat.tr.u.seg.segend |
| #define CPU_TR_LIMIT CPU_STATSAVE.cpu_stat.tr_desc.u.seg.limit | #define CPU_TR_LIMIT CPU_STATSAVE.cpu_stat.tr.u.seg.limit |
| /* | /* |
| * control register | * control register |
| Line 501 void set_eflags(DWORD new_flags, DWORD m | Line 520 void set_eflags(DWORD new_flags, DWORD m |
| void ia32_init(void); | void ia32_init(void); |
| void ia32_initreg(void); | |
| void ia32_setextsize(UINT32 size); | |
| void ia32reset(void); | void ia32reset(void); |
| void ia32shut(void); | void ia32shut(void); |
| Line 509 void ia32withtrap(void); | Line 530 void ia32withtrap(void); |
| void ia32withdma(void); | void ia32withdma(void); |
| void ia32_step(void); | void ia32_step(void); |
| void CPUCALL ia32_interrupt(BYTE vect); | void CPUCALL ia32_interrupt(int vect); |
| void CPUCALL ia32_exception(DWORD vect, DWORD p1, DWORD p2); | void CPUCALL ia32_exception(int vect, int p1, int p2); |
| void exec_1step(void); | void exec_1step(void); |
| #define INST_PREFIX (1 << 0) | #define INST_PREFIX (1 << 0) |
| #define INST_STRING (1 << 1) | #define INST_STRING (1 << 1) |
| #define REP_CHECKZF (1 << 7) | #define REP_CHECKZF (1 << 7) |
| int disasm(UINT32 *eip, char *buf, size_t size); | |
| void ia32_printf(const char *buf, ...); | void ia32_printf(const char *buf, ...); |
| void ia32_warning(const char *buf, ...); | void ia32_warning(const char *buf, ...); |
| void ia32_panic(const char *buf, ...); | void ia32_panic(const char *buf, ...); |
| Line 527 void FASTCALL change_pm(BOOL onoff); | Line 550 void FASTCALL change_pm(BOOL onoff); |
| void FASTCALL change_vm(BOOL onoff); | void FASTCALL change_vm(BOOL onoff); |
| void FASTCALL change_pg(BOOL onoff); | void FASTCALL change_pg(BOOL onoff); |
| extern BYTE szpcflag[0x200]; | extern const UINT8 iflags[]; |
| extern BYTE szpflag_w[0x10000]; | #define szpcflag iflags |
| extern UINT8 szpflag_w[0x10000]; | |
| extern BYTE *reg8_b20[0x100]; | |
| extern BYTE *reg8_b53[0x100]; | extern UINT8 *reg8_b20[0x100]; |
| extern WORD *reg16_b20[0x100]; | extern UINT8 *reg8_b53[0x100]; |
| extern WORD *reg16_b53[0x100]; | extern UINT16 *reg16_b20[0x100]; |
| extern DWORD *reg32_b20[0x100]; | extern UINT16 *reg16_b53[0x100]; |
| extern DWORD *reg32_b53[0x100]; | extern UINT32 *reg32_b20[0x100]; |
| extern UINT32 *reg32_b53[0x100]; | |
| extern const char *reg8_str[8]; | extern const char *reg8_str[8]; |
| extern const char *reg16_str[8]; | extern const char *reg16_str[8]; |
| Line 545 char *cpu_reg2str(void); | Line 569 char *cpu_reg2str(void); |
| #if defined(USE_FPU) | #if defined(USE_FPU) |
| char *fpu_reg2str(void); | char *fpu_reg2str(void); |
| #endif | #endif |
| void put_cpuinfo(void); | |
| void dbg_printf(const char *str, ...); | void dbg_printf(const char *str, ...); |
| /* | /* |
| * Misc. | * Misc. |
| */ | */ |
| void gdtr_dump(DWORD base, DWORD limit); | void gdtr_dump(UINT32 base, UINT limit); |
| void idtr_dump(DWORD base, DWORD limit); | void idtr_dump(UINT32 base, UINT limit); |
| void ldtr_dump(DWORD base, DWORD limit); | void ldtr_dump(UINT32 base, UINT limit); |
| void tr_dump(WORD selector, DWORD base, DWORD limit); | void tr_dump(UINT16 selector, UINT32 base, UINT limit); |
| #ifdef __cplusplus | #ifdef __cplusplus |
| } | } |