--- np2/i386c/ia32/cpu.h 2003/12/08 00:55:31 1.1 +++ np2/i386c/ia32/cpu.h 2011/12/21 16:33:44 1.39 @@ -1,5 +1,3 @@ -/* $Id: cpu.h,v 1.1 2003/12/08 00:55:31 yui Exp $ */ - /* * Copyright (c) 2002-2003 NONAKA Kimihiro * All rights reserved. @@ -12,8 +10,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -32,21 +28,12 @@ Copyright by Yui/Studio Milmake 1999-2000 Copyright by Norio HATTORI 2000,2001 - Copyright by NONAKA Kimihiro 2002-2003 + Copyright by NONAKA Kimihiro 2002-2004 */ #ifndef IA32_CPU_CPU_H__ #define IA32_CPU_CPU_H__ -#if 0 // -> compiler.h -#include -#include -#include -#include -#include -#include -#endif - #include "interface.h" #ifdef __cplusplus @@ -56,41 +43,39 @@ extern "C" { typedef union { #if defined(BYTESEX_LITTLE) struct { - BYTE l; - BYTE h; - BYTE _hl; - BYTE _hh; + UINT8 l; + UINT8 h; + UINT8 _hl; + UINT8 _hh; } b; struct { - WORD w; - WORD _hw; + UINT16 w; + UINT16 _hw; } w; #elif defined(BYTESEX_BIG) struct { - BYTE _hh; - BYTE _hl; - BYTE h; - BYTE l; + UINT8 _hh; + UINT8 _hl; + UINT8 h; + UINT8 l; } b; struct { - WORD _hw; - WORD w; + UINT16 _hw; + UINT16 w; } w; #endif - DWORD d; + UINT32 d; } REG32; +typedef struct { + UINT8 b[10]; +} REG80; + #ifdef __cplusplus } #endif -#include "cpu_io.h" -#include "cpu_mem.h" -#include "exception.h" -#include "paging.h" -#include "resolve.h" #include "segments.h" -#include "task.h" #ifdef __cplusplus extern "C" { @@ -119,140 +104,195 @@ enum { CPU_SEGREG_NUM }; -#if 1 // パックしないとだめ? +enum { + CPU_TEST_REG_NUM = 8 +}; + +enum { + CPU_DEBUG_REG_NUM = 8, + CPU_DEBUG_REG_INDEX_NUM = 4 +}; + +enum { + MAX_PREFIX = 8 +}; typedef struct { REG32 reg[CPU_REG_NUM]; - WORD sreg[CPU_SEGREG_NUM]; + UINT16 sreg[CPU_SEGREG_NUM]; REG32 eflags; - REG32 eip; + REG32 prev_eip; + REG32 prev_esp; + + UINT32 tr[CPU_TEST_REG_NUM]; + UINT32 dr[CPU_DEBUG_REG_NUM]; } CPU_REGS; typedef struct { - WORD gdtr_limit; - DWORD gdtr_base; - WORD idtr_limit; - DWORD idtr_base; - - WORD ldtr; - WORD tr; - descriptor_t ldtr_desc; - descriptor_t tr_desc; - - DWORD cr0; - DWORD cr1; - DWORD cr2; - DWORD cr3; - DWORD cr4; - DWORD mxcsr; + UINT16 gdtr_limit; + UINT16 pad0; + UINT32 gdtr_base; + UINT16 idtr_limit; + UINT16 pad1; + UINT32 idtr_base; + + UINT16 ldtr; + UINT16 tr; + + UINT32 cr0; + UINT32 cr1; + UINT32 cr2; + UINT32 cr3; + UINT32 cr4; + UINT32 mxcsr; } CPU_SYSREGS; typedef struct { descriptor_t sreg[CPU_SEGREG_NUM]; + descriptor_t ldtr; + descriptor_t tr; + + UINT32 adrsmask; + UINT32 ovflag; + + UINT8 ss_32; + UINT8 resetreq; + UINT8 trap; + + UINT8 page_wp; - DWORD inport; - DWORD ovflag; + UINT8 protected_mode; + UINT8 paging; + UINT8 vm86; + UINT8 user_mode; - BYTE ss_32; - BYTE trap; - BYTE cpu_type; - BYTE _dummy; - - BYTE cpl; - BYTE protected_mode; - BYTE paging; - BYTE vm86; + UINT8 hlt; + UINT8 bp; /* break point bitmap */ + UINT8 bp_ev; /* break point event */ - DWORD ioaddr; /* I/O bitmap linear address */ - WORD iolimit; /* I/O bitmap count */ + UINT8 backout_sp; /* backout ESP, when exception */ - BYTE nerror; /* double fault/ triple fault */ - BYTE prev_exception; + UINT32 pde_base; + + UINT32 ioaddr; /* I/O bitmap linear address */ + UINT16 iolimit; /* I/O bitmap count */ + + UINT8 nerror; /* double fault/ triple fault */ + UINT8 prev_exception; } CPU_STAT; typedef struct { - BYTE op_32; - BYTE as_32; - BYTE rep_used; - BYTE seg_used; - DWORD seg_base; + UINT8 op_32; + UINT8 as_32; + UINT8 rep_used; + UINT8 seg_used; + UINT32 seg_base; } CPU_INST; -#else +/* FPU */ +enum { + FPU_REG_NUM = 8 +}; typedef struct { - REG32 reg[CPU_REG_NUM]; - WORD sreg[CPU_SEGREG_NUM]; + UINT16 seg; + UINT16 pad; + UINT32 offset; +} FPU_PTR; - REG32 eflags; +typedef struct { + UINT16 control; + UINT16 status; + UINT16 op; + + FPU_PTR inst; + FPU_PTR data; +} FPU_REGS; - REG32 eip; - REG32 prev_eip; -} __attribute__((packed)) CPU_REGS; +typedef struct { + UINT8 valid; /* レジスタ有効 */ + UINT8 sign; /* 符号 */ + UINT8 zero; /* ゼロ */ + UINT8 inf; /* ∞ */ + UINT8 nan; /* NaN */ + UINT8 denorm; /* 非正規化 */ + SINT16 exp; /* 指数部 */ + UINT64 num; /* 小数部 */ +} FP_REG; typedef struct { - WORD gdtr_limit; - DWORD gdtr_base; - WORD idtr_limit; - DWORD idtr_base; - - WORD ldtr; - WORD tr; - descriptor_t ldtr_desc; - descriptor_t tr_desc; - - DWORD cr0; - DWORD cr1; - DWORD cr2; - DWORD cr3; - DWORD cr4; - DWORD mxcsr; -} __attribute__((packed)) CPU_SYSREGS; + UINT8 top; /* スタック位置 */ + UINT8 pc; /* 精度 */ + UINT8 rc; /* 丸め */ + UINT8 dmy[1]; + + FP_REG reg[FPU_REG_NUM]; +} FPU_STAT; typedef struct { - descriptor_t sreg[CPU_SEGREG_NUM]; + CPU_REGS cpu_regs; + CPU_SYSREGS cpu_sysregs; + CPU_STAT cpu_stat; + CPU_INST cpu_inst; + CPU_INST cpu_inst_default; + +#if defined(USE_FPU) + FPU_REGS fpu_regs; + FPU_STAT fpu_stat; +#endif - DWORD inport; - DWORD ovflag; + /* protected by cpu shut */ + UINT8 cpu_type; + UINT8 itfbank; + UINT16 ram_d0; + SINT32 remainclock; + SINT32 baseclock; + UINT32 clock; +} I386STAT; - BYTE ss_32; - BYTE trap; - BYTE cpu_type; - BYTE _dummy; - - BYTE cpl; - BYTE protected_mode; - BYTE paging; - BYTE vm86; - - DWORD ioaddr; /* I/O bitmap linear address */ - WORD iolimit; /* I/O bitmap count */ - - BYTE nerror; /* double fault/ triple fault */ - BYTE prev_exception; -} __attribute__((packed)) CPU_STAT; - -typedef struct { - BYTE op_32; - BYTE as_32; - BYTE rep_used; - BYTE seg_used; - DWORD seg_base; -} __attribute__((packed)) CPU_INST; +typedef struct { + UINT8 *ext; + UINT32 extsize; + UINT8 *extbase; /* = ext - 0x100000 */ + UINT32 extlimit16mb; /* = extsize + 0x100000 (MAX:16MB) */ + UINT32 extlimit4gb; /* = extsize + 0x100000 */ + UINT32 inport; + UINT8 *ems[4]; +} I386EXT; -#endif +typedef struct { + I386STAT s; /* STATsaveされる奴 */ + I386EXT e; +} I386CORE; + +extern I386CORE i386core; + +#define CPU_STATSAVE i386core.s + +#define CPU_ADRSMASK i386core.s.cpu_stat.adrsmask +#define CPU_RESETREQ i386core.s.cpu_stat.resetreq + +#define CPU_REMCLOCK i386core.s.remainclock +#define CPU_BASECLOCK i386core.s.baseclock +#define CPU_CLOCK i386core.s.clock +#define CPU_ITFBANK i386core.s.itfbank +#define CPU_RAM_D000 i386core.s.ram_d0 -extern CPU_REGS cpu_regs; -extern CPU_SYSREGS cpu_sysregs; -extern CPU_STAT cpu_stat; -extern CPU_INST cpu_inst; -extern CPU_INST cpu_inst_default; -extern BYTE iflags[]; +#define CPU_TYPE i386core.s.cpu_type +#define CPUTYPE_V30 0x01 + +#define CPU_EXTMEM i386core.e.ext +#define CPU_EXTMEMSIZE i386core.e.extsize +#define CPU_EXTMEMBASE i386core.e.extbase +#define CPU_EXTLIMIT16 i386core.e.extlimit16mb +#define CPU_EXTLIMIT i386core.e.extlimit4gb +#define CPU_INPADRS i386core.e.inport +#define CPU_EMSPTR i386core.e.ems -extern jmp_buf exec_1step_jmpbuf; +extern sigjmp_buf exec_1step_jmpbuf; /* @@ -264,8 +304,12 @@ extern jmp_buf exec_1step_jmpbuf; #define CPU_VENDOR_3 0x6c65746e /* "ntel" */ /* version */ -#define CPU_FAMILY 6 -#define CPU_MODEL 1 +#define CPU_FAMILY 4 +#if defined(USE_FPU) +#define CPU_MODEL 1 /* 486DX */ +#else +#define CPU_MODEL 2 /* 486SX */ +#endif #define CPU_STEPPING 3 /* feature */ @@ -301,36 +345,22 @@ extern jmp_buf exec_1step_jmpbuf; /* (1 << 29) */ /* (1 << 30) */ /* (1 << 31) */ -#ifdef USE_FPU +#if defined(USE_FPU) #define CPU_FEATURES (CPU_FEATURE_CMOV|CPU_FEATURE_FPU) #else #define CPU_FEATURES (CPU_FEATURE_CMOV) #endif -#define CPU_REGS_BYTEL(n) cpu_regs.reg[(n)].b.l -#define CPU_REGS_BYTEH(n) cpu_regs.reg[(n)].b.h -#define CPU_REGS_WORD(n) cpu_regs.reg[(n)].w.w -#define CPU_REGS_DWORD(n) cpu_regs.reg[(n)].d -#define CPU_REGS_SREG(n) cpu_regs.sreg[(n)] - -#define CPU_STAT_SREG(n) cpu_stat.sreg[(n)] -#define CPU_STAT_SREGBASE(n) cpu_stat.sreg[(n)].u.seg.segbase -#define CPU_STAT_SREGEND(n) cpu_stat.sreg[(n)].u.seg.segend -#define CPU_STAT_SREGLIMIT(n) cpu_stat.sreg[(n)].u.seg.limit -#define CPU_STAT_SREG_CLEAR(n) \ -do { \ - memset(&CPU_STAT_SREG(n), 0, sizeof(descriptor_t)); \ -} while (/*CONSTCOND*/ 0) -#define CPU_STAT_SREG_INIT(n) \ -do { \ - descriptor_t sd; \ - memset(&CPU_STAT_SREG(n), 0, sizeof(CPU_STAT_SREG(n))); \ - memset(&sd, 0, sizeof(sd)); \ - sd.u.seg.limit = 0xffff; \ - CPU_SET_SEGDESC_DEFAULT(&sd, (n), 0); \ - CPU_STAT_SREG(n) = sd; \ -} while (/*CONSTCOND*/ 0) +#define CPU_REGS_BYTEL(n) CPU_STATSAVE.cpu_regs.reg[(n)].b.l +#define CPU_REGS_BYTEH(n) CPU_STATSAVE.cpu_regs.reg[(n)].b.h +#define CPU_REGS_WORD(n) CPU_STATSAVE.cpu_regs.reg[(n)].w.w +#define CPU_REGS_DWORD(n) CPU_STATSAVE.cpu_regs.reg[(n)].d +#define CPU_REGS_SREG(n) CPU_STATSAVE.cpu_regs.sreg[(n)] + +#define CPU_STAT_SREG(n) CPU_STATSAVE.cpu_stat.sreg[(n)] +#define CPU_STAT_SREGBASE(n) CPU_STAT_SREG((n)).u.seg.segbase +#define CPU_STAT_SREGLIMIT(n) CPU_STAT_SREG((n)).u.seg.limit #define CPU_AL CPU_REGS_BYTEL(CPU_EAX_INDEX) @@ -350,7 +380,7 @@ do { \ #define CPU_BP CPU_REGS_WORD(CPU_EBP_INDEX) #define CPU_SI CPU_REGS_WORD(CPU_ESI_INDEX) #define CPU_DI CPU_REGS_WORD(CPU_EDI_INDEX) -#define CPU_IP cpu_regs.eip.w.w +#define CPU_IP CPU_STATSAVE.cpu_regs.eip.w.w #define CPU_EAX CPU_REGS_DWORD(CPU_EAX_INDEX) #define CPU_ECX CPU_REGS_DWORD(CPU_ECX_INDEX) @@ -360,8 +390,9 @@ do { \ #define CPU_EBP CPU_REGS_DWORD(CPU_EBP_INDEX) #define CPU_ESI CPU_REGS_DWORD(CPU_ESI_INDEX) #define CPU_EDI CPU_REGS_DWORD(CPU_EDI_INDEX) -#define CPU_EIP cpu_regs.eip.d -#define CPU_PREV_EIP cpu_regs.prev_eip.d +#define CPU_EIP CPU_STATSAVE.cpu_regs.eip.d +#define CPU_PREV_EIP CPU_STATSAVE.cpu_regs.prev_eip.d +#define CPU_PREV_ESP CPU_STATSAVE.cpu_regs.prev_esp.d #define CPU_ES CPU_REGS_SREG(CPU_ES_INDEX) #define CPU_CS CPU_REGS_SREG(CPU_CS_INDEX) @@ -370,20 +401,27 @@ do { \ #define CPU_FS CPU_REGS_SREG(CPU_FS_INDEX) #define CPU_GS CPU_REGS_SREG(CPU_GS_INDEX) -#define ES_BASE cpu_stat.sreg[CPU_ES_INDEX].u.seg.segbase -#define CS_BASE cpu_stat.sreg[CPU_CS_INDEX].u.seg.segbase -#define SS_BASE cpu_stat.sreg[CPU_SS_INDEX].u.seg.segbase -#define DS_BASE cpu_stat.sreg[CPU_DS_INDEX].u.seg.segbase -#define FS_BASE cpu_stat.sreg[CPU_FS_INDEX].u.seg.segbase -#define GS_BASE cpu_stat.sreg[CPU_GS_INDEX].u.seg.segbase - -#define CPU_EFLAG cpu_regs.eflags.d -#define CPU_FLAG cpu_regs.eflags.w.w -#define CPU_FLAGL cpu_regs.eflags.b.l -#define CPU_FLAGH cpu_regs.eflags.b.h -#define CPU_TRAP cpu_stat.trap -#define CPU_INPORT cpu_stat.inport -#define CPU_OV cpu_stat.ovflag +#define CPU_ES_DESC CPU_STAT_SREG(CPU_ES_INDEX) +#define CPU_CS_DESC CPU_STAT_SREG(CPU_CS_INDEX) +#define CPU_SS_DESC CPU_STAT_SREG(CPU_SS_INDEX) +#define CPU_DS_DESC CPU_STAT_SREG(CPU_DS_INDEX) +#define CPU_FS_DESC CPU_STAT_SREG(CPU_FS_INDEX) +#define CPU_GS_DESC CPU_STAT_SREG(CPU_GS_INDEX) + +#define ES_BASE CPU_STAT_SREGBASE(CPU_ES_INDEX) +#define CS_BASE CPU_STAT_SREGBASE(CPU_CS_INDEX) +#define SS_BASE CPU_STAT_SREGBASE(CPU_SS_INDEX) +#define DS_BASE CPU_STAT_SREGBASE(CPU_DS_INDEX) +#define FS_BASE CPU_STAT_SREGBASE(CPU_FS_INDEX) +#define GS_BASE CPU_STAT_SREGBASE(CPU_GS_INDEX) + +#define CPU_EFLAG CPU_STATSAVE.cpu_regs.eflags.d +#define CPU_FLAG CPU_STATSAVE.cpu_regs.eflags.w.w +#define CPU_FLAGL CPU_STATSAVE.cpu_regs.eflags.b.l +#define CPU_FLAGH CPU_STATSAVE.cpu_regs.eflags.b.h +#define CPU_TRAP CPU_STATSAVE.cpu_stat.trap +#define CPU_INPORT CPU_STATSAVE.cpu_stat.inport +#define CPU_OV CPU_STATSAVE.cpu_stat.ovflag #define C_FLAG (1 << 0) #define P_FLAG (1 << 2) @@ -409,32 +447,46 @@ do { \ #define ALL_FLAG (SZAPC_FLAG|T_FLAG|I_FLAG|D_FLAG|O_FLAG|IOPL_FLAG|NT_FLAG) #define ALL_EFLAG (ALL_FLAG|RF_FLAG|VM_FLAG|AC_FLAG|VIF_FLAG|VIP_FLAG|ID_FLAG) -#define REAL_FLAGREG ((CPU_FLAG & 0xf7ff) | (CPU_OV ? O_FLAG : 0)) -#define REAL_EFLAGREG ((CPU_EFLAG & 0xfffff7ff) | (CPU_OV ? O_FLAG : 0)) +#define REAL_FLAGREG ((CPU_FLAG & 0xf7ff) | (CPU_OV ? O_FLAG : 0) | 2) +#define REAL_EFLAGREG ((CPU_EFLAG & 0xfffff7ff) | (CPU_OV ? O_FLAG : 0) | 2) -void set_flags(WORD new_flags, WORD mask); -void set_eflags(DWORD new_flags, DWORD mask); +void FASTCALL set_flags(UINT16 new_flags, UINT16 mask); +void FASTCALL set_eflags(UINT32 new_flags, UINT32 mask); -#define CPU_TYPE cpu_stat.cpu_type -#define CPUTYPE_V30 0x01 -#define CPU_INST_OP32 cpu_inst.op_32 -#define CPU_INST_AS32 cpu_inst.as_32 -#define CPU_INST_REPUSE cpu_inst.rep_used -#define CPU_INST_SEGUSE cpu_inst.seg_used -#define CPU_INST_SEGREG_INDEX cpu_inst.seg_base +#define CPU_INST_OP32 CPU_STATSAVE.cpu_inst.op_32 +#define CPU_INST_AS32 CPU_STATSAVE.cpu_inst.as_32 +#define CPU_INST_REPUSE CPU_STATSAVE.cpu_inst.rep_used +#define CPU_INST_SEGUSE CPU_STATSAVE.cpu_inst.seg_used +#define CPU_INST_SEGREG_INDEX CPU_STATSAVE.cpu_inst.seg_base #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 CPU_STAT_CS_BASE cpu_stat.sreg[CPU_CS_INDEX].u.seg.limit -#define CPU_STAT_CS_LIMIT cpu_stat.sreg[CPU_CS_INDEX].u.seg.limit -#define CPU_STAT_CS_END cpu_stat.sreg[CPU_CS_INDEX].u.seg.segend - -#define CPU_STAT_SS32 cpu_stat.ss_32 -#define CPU_STAT_PM cpu_stat.protected_mode -#define CPU_STAT_VM86 cpu_stat.vm86 -#define CPU_STAT_PAGING cpu_stat.paging -#define CPU_STAT_CPL cpu_stat.cpl +#define CPU_STAT_CS_BASE CPU_STAT_SREGBASE(CPU_CS_INDEX) +#define CPU_STAT_CS_LIMIT CPU_STAT_SREGLIMIT(CPU_CS_INDEX) + +#define CPU_STAT_ADRSMASK CPU_STATSAVE.cpu_stat.adrsmask +#define CPU_STAT_SS32 CPU_STATSAVE.cpu_stat.ss_32 +#define CPU_STAT_RESETREQ CPU_STATSAVE.cpu_stat.resetreq +#define CPU_STAT_PM CPU_STATSAVE.cpu_stat.protected_mode +#define CPU_STAT_PAGING CPU_STATSAVE.cpu_stat.paging +#define CPU_STAT_VM86 CPU_STATSAVE.cpu_stat.vm86 +#define CPU_STAT_WP CPU_STATSAVE.cpu_stat.page_wp +#define CPU_STAT_CPL CPU_CS_DESC.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_SET_PREV_ESP1(esp) \ +do { \ + CPU_STATSAVE.cpu_stat.backout_sp = 1; \ + CPU_PREV_ESP = (esp); \ +} while (/*CONSTCOND*/0) +#define CPU_SET_PREV_ESP() CPU_SET_PREV_ESP1(CPU_ESP) +#define CPU_CLEAR_PREV_ESP() \ +do { \ + CPU_STATSAVE.cpu_stat.backout_sp = 0; \ +} while (/*CONSTCOND*/0) + +#define CPU_STAT_HLT CPU_STATSAVE.cpu_stat.hlt #define CPU_STAT_IOPL ((CPU_EFLAG & IOPL_FLAG) >> 12) #define CPU_IOPL0 0 @@ -442,54 +494,71 @@ void set_eflags(DWORD new_flags, DWORD m #define CPU_IOPL2 2 #define CPU_IOPL3 3 -#define CPU_STAT_IOADDR cpu_stat.ioaddr -#define CPU_STAT_IOLIMIT cpu_stat.iolimit +#define CPU_STAT_IOADDR CPU_STATSAVE.cpu_stat.ioaddr +#define CPU_STAT_IOLIMIT CPU_STATSAVE.cpu_stat.iolimit + +#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_STAT_NERROR cpu_stat.nerror -#define CPU_STAT_PREV_EXCEPTION cpu_stat.prev_exception +#define CPU_MODE_SUPERVISER 0 +#define CPU_MODE_USER (1 << 3) -#define CPU_CLI do { CPU_FLAG &= ~I_FLAG; \ - CPU_TRAP = 0; } while (/*CONSTCOND*/ 0) -#define CPU_STI do { CPU_FLAG |= I_FLAG; \ - CPU_TRAP = (CPU_FLAG >> 8) & 1; } while (/*CONSTCOND*/0) - -#define CPU_GDTR_LIMIT cpu_sysregs.gdtr_limit -#define CPU_GDTR_BASE cpu_sysregs.gdtr_base -#define CPU_IDTR_LIMIT cpu_sysregs.idtr_limit -#define CPU_IDTR_BASE cpu_sysregs.idtr_base -#define CPU_LDTR cpu_sysregs.ldtr -#define CPU_LDTR_DESC cpu_sysregs.ldtr_desc -#define CPU_LDTR_BASE cpu_sysregs.ldtr_desc.u.seg.segbase -#define CPU_LDTR_END cpu_sysregs.ldtr_desc.u.seg.segend -#define CPU_LDTR_LIMIT cpu_sysregs.ldtr_desc.u.seg.limit -#define CPU_TR cpu_sysregs.tr -#define CPU_TR_DESC cpu_sysregs.tr_desc -#define CPU_TR_BASE cpu_sysregs.tr_desc.u.seg.segbase -#define CPU_TR_END cpu_sysregs.tr_desc.u.seg.segend -#define CPU_TR_LIMIT cpu_sysregs.tr_desc.u.seg.limit - -#define CPU_CR0 cpu_sysregs.cr0 -#define CPU_CR1 cpu_sysregs.cr1 -#define CPU_CR2 cpu_sysregs.cr2 -#define CPU_CR3 cpu_sysregs.cr3 -#define CPU_CR4 cpu_sysregs.cr4 -#define CPU_MXCSR cpu_sysregs.mxcsr - -#define CPU_CR0_PE (1 << 0) -#define CPU_CR0_MP (1 << 1) -#define CPU_CR0_EM (1 << 2) -#define CPU_CR0_TS (1 << 3) -#define CPU_CR0_ET (1 << 4) -#define CPU_CR0_NE (1 << 5) -#define CPU_CR0_WP (1 << 16) -#define CPU_CR0_AM (1 << 18) -#define CPU_CR0_NW (1 << 29) -#define CPU_CR0_CD (1 << 30) -#define CPU_CR0_PG (1 << 31) - -#define CPU_CR3_PD_MASK 0xfffff000 -#define CPU_CR3_PWT (1 << 3) -#define CPU_CR3_PCD (1 << 4) +#define CPU_CLI \ +do { \ + CPU_FLAG &= ~I_FLAG; \ + CPU_TRAP = 0; \ +} while (/*CONSTCOND*/0) + +#define CPU_STI \ +do { \ + CPU_FLAG |= I_FLAG; \ + CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG) ; \ +} while (/*CONSTCOND*/0) + +#define CPU_GDTR_LIMIT CPU_STATSAVE.cpu_sysregs.gdtr_limit +#define CPU_GDTR_BASE CPU_STATSAVE.cpu_sysregs.gdtr_base +#define CPU_IDTR_LIMIT CPU_STATSAVE.cpu_sysregs.idtr_limit +#define CPU_IDTR_BASE CPU_STATSAVE.cpu_sysregs.idtr_base +#define CPU_LDTR CPU_STATSAVE.cpu_sysregs.ldtr +#define CPU_LDTR_DESC CPU_STATSAVE.cpu_stat.ldtr +#define CPU_LDTR_BASE CPU_LDTR_DESC.u.seg.segbase +#define CPU_LDTR_LIMIT CPU_LDTR_DESC.u.seg.limit +#define CPU_TR CPU_STATSAVE.cpu_sysregs.tr +#define CPU_TR_DESC CPU_STATSAVE.cpu_stat.tr +#define CPU_TR_BASE CPU_TR_DESC.u.seg.segbase +#define CPU_TR_LIMIT CPU_TR_DESC.u.seg.limit + +/* + * control register + */ +#define CPU_MSW CPU_STATSAVE.cpu_sysregs.cr0 + +#define CPU_CR0 CPU_STATSAVE.cpu_sysregs.cr0 +#define CPU_CR1 CPU_STATSAVE.cpu_sysregs.cr1 +#define CPU_CR2 CPU_STATSAVE.cpu_sysregs.cr2 +#define CPU_CR3 CPU_STATSAVE.cpu_sysregs.cr3 +#define CPU_CR4 CPU_STATSAVE.cpu_sysregs.cr4 +#define CPU_MXCSR CPU_STATSAVE.cpu_sysregs.mxcsr + +#define CPU_CR0_PE (1 << 0) +#define CPU_CR0_MP (1 << 1) +#define CPU_CR0_EM (1 << 2) +#define CPU_CR0_TS (1 << 3) +#define CPU_CR0_ET (1 << 4) +#define CPU_CR0_NE (1 << 5) +#define CPU_CR0_WP (1 << 16) +#define CPU_CR0_AM (1 << 18) +#define CPU_CR0_NW (1 << 29) +#define CPU_CR0_CD (1 << 30) +#define CPU_CR0_PG (1 << 31) +#define CPU_CR0_ALL (CPU_CR0_PE|CPU_CR0_MP|CPU_CR0_EM|CPU_CR0_TS|CPU_CR0_ET|CPU_CR0_NE|CPU_CR0_WP|CPU_CR0_AM|CPU_CR0_NW|CPU_CR0_CD|CPU_CR0_PG) + +#define CPU_CR3_PD_MASK 0xfffff000 +#define CPU_CR3_PWT (1 << 3) +#define CPU_CR3_PCD (1 << 4) +#define CPU_CR3_MASK (CPU_CR3_PD_MASK|CPU_CR3_PWT|CPU_CR3_PCD) #define CPU_CR4_VME (1 << 0) #define CPU_CR4_PVI (1 << 1) @@ -503,25 +572,60 @@ void set_eflags(DWORD new_flags, DWORD m #define CPU_CR4_OSFXSR (1 << 9) #define CPU_CR4_OSXMMEXCPT (1 << 10) - -void ia32_initialize(void); +/* + * debug register + */ +#define CPU_DR(r) CPU_STATSAVE.cpu_regs.dr[(r)] +#define CPU_DR6 CPU_DR(6) +#define CPU_DR7 CPU_DR(7) + +#define CPU_STAT_BP CPU_STATSAVE.cpu_stat.bp +#define CPU_STAT_BP_EVENT CPU_STATSAVE.cpu_stat.bp_ev +#define CPU_STAT_BP_EVENT_B(r) (1 << (r)) +#define CPU_STAT_BP_EVENT_DR (1 << 4) /* fault */ +#define CPU_STAT_BP_EVENT_STEP (1 << 5) /* as CPU_TRAP */ +#define CPU_STAT_BP_EVENT_TASK (1 << 6) +#define CPU_STAT_BP_EVENT_RF (1 << 7) /* RF_FLAG */ + +#define CPU_DR6_B(r) (1 << (r)) +#define CPU_DR6_BD (1 << 13) +#define CPU_DR6_BS (1 << 14) +#define CPU_DR6_BT (1 << 15) + +#define CPU_DR7_L(r) (1 << ((r) * 2)) +#define CPU_DR7_G(r) (1 << ((r) * 2 + 1)) +#define CPU_DR7_LE (1 << 8) +#define CPU_DR7_GE (1 << 9) +#define CPU_DR7_GD (1 << 13) +#define CPU_DR7_RW(r) (3 << ((r) * 4 + 16)) +#define CPU_DR7_LEN(r) (3 << ((r) * 4 + 16 + 2)) + +#define CPU_DR7_GET_RW(r) ((CPU_DR7) >> (16 + (r) * 4)) +#define CPU_DR7_RW_CODE 0 +#define CPU_DR7_RW_RO 1 +#define CPU_DR7_RW_IO 2 +#define CPU_DR7_RW_RW 3 + +#define CPU_DR7_GET_LEN(r) ((CPU_DR7) >> (16 + 2 + (r) * 4)) + +void ia32_init(void); +void ia32_initreg(void); +void ia32_setextsize(UINT32 size); +void ia32_setemm(UINT frame, UINT32 addr); void ia32reset(void); +void ia32shut(void); +void ia32a20enable(BOOL enable); void ia32(void); -void ia32withtrap(void); -void ia32withdma(void); - void ia32_step(void); -void CPUCALL ia32_interrupt(BYTE vect); -void CPUCALL ia32_exception(DWORD vect, DWORD p1, DWORD p2); +void CPUCALL ia32_interrupt(int vect, int soft); +void CPUCALL ia32_exception(int vect, int p1, int p2); void exec_1step(void); #define INST_PREFIX (1 << 0) #define INST_STRING (1 << 1) #define REP_CHECKZF (1 << 7) -void disasm(WORD cs, DWORD maddr); - void ia32_printf(const char *buf, ...); void ia32_warning(const char *buf, ...); void ia32_panic(const char *buf, ...); @@ -530,58 +634,157 @@ void ia32_bioscall(void); void FASTCALL change_pm(BOOL onoff); void FASTCALL change_vm(BOOL onoff); +void FASTCALL change_pg(BOOL onoff); + +void FASTCALL set_cr3(UINT32 new_cr3); +void FASTCALL set_cpl(int new_cpl); -extern BYTE szpcflag[0x200]; -extern BYTE szpflag_w[0x10000]; +extern const UINT8 iflags[]; +#define szpcflag iflags +extern UINT8 szpflag_w[0x10000]; + +extern UINT8 *reg8_b20[0x100]; +extern UINT8 *reg8_b53[0x100]; +extern UINT16 *reg16_b20[0x100]; +extern UINT16 *reg16_b53[0x100]; +extern UINT32 *reg32_b20[0x100]; +extern UINT32 *reg32_b53[0x100]; + +extern const char *reg8_str[8]; +extern const char *reg16_str[8]; +extern const char *reg32_str[8]; + +char *cpu_reg2str(void); +#if defined(USE_FPU) +char *fpu_reg2str(void); +#endif +void put_cpuinfo(void); +void dbg_printf(const char *str, ...); -extern BYTE *reg8_b20[0x100]; -extern BYTE *reg8_b53[0x100]; -extern WORD *reg16_b20[0x100]; -extern WORD *reg16_b53[0x100]; -extern DWORD *reg32_b20[0x100]; -extern DWORD *reg32_b53[0x100]; +/* + * FPU + */ +#define FPU_REGS CPU_STATSAVE.fpu_regs +#define FPU_CTRLWORD FPU_REGS.control +#define FPU_STATUSWORD FPU_REGS.status +#define FPU_INSTPTR FPU_REGS.inst +#define FPU_DATAPTR FPU_REGS.data +#define FPU_LASTINSTOP FPU_REGS.op +#define FPU_INSTPTR_OFFSET FPU_REGS.inst.offset +#define FPU_INSTPTR_SEG FPU_REGS.inst.seg +#define FPU_DATAPTR_OFFSET FPU_REGS.data.offset +#define FPU_DATAPTR_SEG FPU_REGS.data.seg + +#define FPU_STAT CPU_STATSAVE.fpu_stat +#define FPU_STAT_TOP FPU_STAT.top +#define FPU_STAT_PC FPU_STAT.pc +#define FPU_STAT_RC FPU_STAT.rc + +#define FPU_ST(i) FPU_STAT.reg[((i) + FPU_STAT_TOP) & 7] +#define FPU_REG(i) FPU_STAT.reg[i] + +/* FPU status register */ +#define FP_IE_FLAG (1 << 0) /* 無効な動作 */ +#define FP_DE_FLAG (1 << 1) /* デノーマライズド・オペランド */ +#define FP_ZE_FLAG (1 << 2) /* ゼロによる除算 */ +#define FP_OE_FLAG (1 << 3) /* オーバーフロー */ +#define FP_UE_FLAG (1 << 4) /* アンダーフロー */ +#define FP_PE_FLAG (1 << 5) /* 精度 */ +#define FP_SF_FLAG (1 << 6) /* スタックフォルト */ +#define FP_ES_FLAG (1 << 7) /* エラーサマリステータス */ +#define FP_C0_FLAG (1 << 8) /* 条件コード */ +#define FP_C1_FLAG (1 << 9) /* 条件コード */ +#define FP_C2_FLAG (1 << 10) /* 条件コード */ +#define FP_TOP_FLAG (7 << 11) /* スタックポイントのトップ */ +#define FP_C3_FLAG (1 << 14) /* 条件コード */ +#define FP_B_FLAG (1 << 15) /* FPU ビジー */ + +#define FP_TOP_SHIFT 11 +#define FP_TOP_GET() ((FPU_STATUSWORD & FP_TOP_FLAG) >> FP_TOP_SHIFT) +#define FP_TOP_SET(v) ((FPU_STATUSWORD & ~FP_TOP_FLAG) | ((v) << FP_TOP_SHIFT)) -// ---- i286 +#define FPU_STAT_TOP_INC() \ +do { \ + FPU_STAT.top = (FPU_STAT.top + 1) & 7; \ +} while (/*CONSTCOND*/0) +#define FPU_STAT_TOP_DEC() \ +do { \ + FPU_STAT.top = (FPU_STAT.top - 1) & 7; \ +} while (/*CONSTCOND*/0) -typedef struct { - SINT32 remainclock; - SINT32 baseclock; - UINT32 clock; +/* FPU control register */ +#define FP_CTRL_PC_SHIFT 8 /* 精度制御 */ +#define FP_CTRL_RC_SHIFT 10 /* 丸め制御 */ + +#define FP_CTRL_PC_24 0 /* 単精度 */ +#define FP_CTRL_PC_53 1 /* 倍精度 */ +#define FP_CTRL_PC_64 3 /* 拡張精度 */ + +#define FP_CTRL_RC_NEAREST_EVEN 0 +#define FP_CTRL_RC_DOWN 1 +#define FP_CTRL_RC_UP 2 +#define FP_CTRL_RC_TO_ZERO 3 - UINT32 adrsmask; // ? - UINT32 inport; // ? - UINT8 resetreq; - UINT8 itfbank; -} I386STAT; -typedef struct { // for ver0.73 - BYTE *ext; - UINT32 extsize; -} I386EXT; +/* + * Misc. + */ +void memory_dump(int idx, UINT32 madr); +void gdtr_dump(UINT32 base, UINT limit); +void idtr_dump(UINT32 base, UINT limit); +void ldtr_dump(UINT32 base, UINT limit); +void tr_dump(UINT16 selector, UINT32 base, UINT limit); +UINT32 pde_dump(UINT32 base, int idx); +void segdesc_dump(descriptor_t *sdp); +UINT32 convert_laddr_to_paddr(UINT32 laddr); +UINT32 convert_vaddr_to_paddr(unsigned int idx, UINT32 offset); +/* + * disasm + */ +/* context */ typedef struct { - I386STAT s; // STATsaveされる奴 - I386EXT e; -} I386CORE; + UINT32 val; + + UINT32 eip; + BOOL op32; + BOOL as32; + + UINT32 baseaddr; + UINT8 opcode[3]; + UINT8 modrm; + UINT8 sib; -extern I386CORE i386core; + BOOL useseg; + int seg; -#define CPU_STATSAVE i386core.s + UINT8 opbyte[32]; + int nopbytes; -#define CPU_REMCLOCK i386core.s.remainclock -#define CPU_BASECLOCK i386core.s.baseclock -#define CPU_CLOCK i386core.s.clock -#define CPU_ADRSMASK i386core.s.adrsmask -#define CPU_RESETREQ i386core.s.resetreq -#define CPU_ITFBANK i386core.s.itfbank -#define CPU_INPADRS i386core.s.inport + char str[256]; + size_t remain; -#define CPU_EXTMEM i386core.e.ext -#define CPU_EXTMEMSIZE i386core.e.extsize + char *next; + char *prefix; + char *op; + char *arg[3]; + int narg; + + char pad; +} disasm_context_t; + +int disasm(UINT32 *eip, disasm_context_t *ctx); #ifdef __cplusplus } #endif +#include "cpu_io.h" +#include "cpu_mem.h" +#include "exception.h" +#include "paging.h" +#include "resolve.h" +#include "task.h" + #endif /* !IA32_CPU_CPU_H__ */