Changes list made after CVS service crash:
- Fixed critical bug in CPU code added with one of the prev commits - Disasm support for SSE4 - Rename PNI->SSE3 everywhere in the code - Correctly decode, disassemble and execute 'XCHG R8, rAX' x86-64 instruction - Correctly decode, disassemble and execute multi-byte NOP 0F F1 opcode - Fixed ENTER and LEAVE instructions in x86-64 mode - Added ability to turn ON instruction trace, only GUI support is missed. Instruction trace could be enabled if Bochs was compiled with disasm - More changes Bit32u -> bx_phy_address - Complete preliminary implementation of SMM in Bochs, SMI is still PANICs but if you press 'continue' everything should work OK - Small code cleanup - Update CHANGES and user docs
This commit is contained in:
parent
c2455e7c1e
commit
f8c3968d42
@ -1,22 +1,30 @@
|
||||
Changes after 2.2.6 release:
|
||||
|
||||
- Fixed bug in FSTENV instruction (Stanislav Shwartsman)
|
||||
- Recognize #XF exception (19) when SSE is enabled
|
||||
- Fixed bug in SYSRET instruction legacy mode
|
||||
- Fixed bug in PSRAW/PSRAD MMX and SSE instructions
|
||||
- Fixed bug in CALL/JMP far through call gate 64 in x86-64 mode
|
||||
- Fixed bug in ENTER instruction in x86-64 mode (Stanislav Shwartsman)
|
||||
- Fixes in Bochs debugger and disassembler
|
||||
- Save and restore RIP/RSP only for FAULT-type exceptions, not for traps
|
||||
- Moved configure time --enable-reset-on-triple-fault option to runtime,
|
||||
the 'cpu' option in .bochsrc is extended and the old configure option
|
||||
is deprecated (Stanislav Shwartsman)
|
||||
- Support for Dual Core and Intel(R) HyperThreading Technology. Now you
|
||||
could choose amount of cores per processor and amount of HT threads per
|
||||
core from .bochsrc for SMP simulation (Stanislav Shwartsman)
|
||||
- Removed --enable-pni configure option, to compile with PNI use
|
||||
--enable-sse=3 instead (Stanislav Shwartsman)
|
||||
- Raise A20 line after system reset (Stanislav Shwartsman)
|
||||
- CPU and internal debugger fixes
|
||||
- Fixed bug in FSTENV instruction (Stanislav Shwartsman)
|
||||
- Recognize #XF exception (19) when SSE is enabled
|
||||
- Fixed bug in SYSRET instruction legacy mode
|
||||
- Fixed bug in PSRAW/PSRAD MMX and SSE instructions
|
||||
- Fixed bug in CALL/JMP far through call gate 64 in x86-64 mode
|
||||
- Correctly decode, disassemble and execute 'XCHG R8, rAX' x86-64 instruction
|
||||
- Correctly decode, disassemble and execute multi-byte NOP 0F F1 opcode
|
||||
- Fixed ENTER and LEAVE instructions in x86-64 mode (Stanislav)
|
||||
- Save and restore RIP/RSP only for FAULT-type exceptions, not for traps
|
||||
- Raise A20 line after system reset (Stanislav Shwartsman)
|
||||
- Implemented NMI delivery (Stanislav)
|
||||
- Many fixes in Bochs debugger and disassembler
|
||||
|
||||
- SMP
|
||||
- Support for Dual Core and Intel(R) HyperThreading Technology. Now you
|
||||
could choose amount of cores per processor and amount of HT threads per
|
||||
core from .bochsrc for SMP simulation (Stanislav Shwartsman)
|
||||
|
||||
- Configure and compile
|
||||
- Moved configure time --enable-reset-on-triple-fault option to runtime,
|
||||
the 'cpu' option in .bochsrc is extended and the old configure option
|
||||
is deprecated (Stanislav Shwartsman)
|
||||
- Removed --enable-pni configure option, to compile with PNI use
|
||||
--enable-sse=3 instead (Stanislav Shwartsman)
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
Changes in 2.2.6 (January 29, 2006):
|
||||
|
@ -512,7 +512,7 @@ smm.o: smm.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
|
||||
../bx_debug/debug.h ../bxversion.h ../gui/siminterface.h ../cpu/cpu.h ../cpu/descriptor.h \
|
||||
../cpu/lazy_flags.h ../cpu/hostasm.h ../cpu/icache.h ../cpu/apic.h \
|
||||
../cpu/i387.h ../fpu/softfloat.h ../fpu/tag_w.h ../fpu/status_w.h \
|
||||
../fpu/control_w.h ../cpu/xmm.h ../memory/memory.h ../pc_system.h \
|
||||
../fpu/control_w.h ../cpu/xmm.h ../cpu/smm.h ../memory/memory.h ../pc_system.h \
|
||||
../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
|
||||
../gui/keymap.h ../instrument/stubs/instrument.h
|
||||
protect_ctrl.o: protect_ctrl.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: apic.cc,v 1.80 2006-03-06 22:02:51 sshwarts Exp $
|
||||
// $Id: apic.cc,v 1.81 2006-04-05 17:31:29 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -175,8 +175,8 @@ void bx_generic_apic_c::set_id(Bit8u newid)
|
||||
bx_bool bx_generic_apic_c::is_selected(bx_phy_address addr, unsigned len)
|
||||
{
|
||||
if((addr & ~0xfff) == get_base()) {
|
||||
if(((addr & 0xf) != 0) || (len != 4))
|
||||
BX_INFO(("warning: misaligned or wrong-size APIC access. len=%d, addr=%08x", len, addr));
|
||||
if((addr & 0xf) != 0)
|
||||
BX_INFO(("warning: misaligned APIC access. addr=%08x, len=%d", addr, len));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -665,6 +665,8 @@ bx_bool bx_local_apic_c::deliver(Bit8u vector, Bit8u delivery_mode, Bit8u trig_m
|
||||
return 0;
|
||||
case APIC_DM_NMI:
|
||||
BX_PANIC(("Delivery of NMI still not implemented !"));
|
||||
cpu->async_event = 1;
|
||||
cpu->nmi_pending = 1;
|
||||
return 0;
|
||||
case APIC_DM_INIT:
|
||||
BX_DEBUG(("Deliver INIT IPI"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.cc,v 1.141 2006-03-26 19:39:37 sshwarts Exp $
|
||||
// $Id: cpu.cc,v 1.142 2006-04-05 17:31:29 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -228,10 +228,10 @@ void BX_CPU_C::cpu_loop(Bit32s max_instr_count)
|
||||
// or the boundary fetch (across pages), by this point.
|
||||
BX_INSTR_FETCH_DECODE_COMPLETED(BX_CPU_ID, i);
|
||||
|
||||
#if BX_DEBUGGER
|
||||
#if BX_DISASM
|
||||
if (BX_CPU_THIS_PTR trace) {
|
||||
// print the instruction that is about to be executed.
|
||||
bx_dbg_disassemble_current(BX_CPU_ID, 1); // only one cpu, print time stamp
|
||||
// print the instruction that is about to be executed
|
||||
debug_disasm_instruction(BX_CPU_THIS_PTR prev_eip);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -573,10 +573,10 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
|
||||
// (bochs doesn't support these)
|
||||
if (BX_CPU_THIS_PTR smi_pending && ! BX_CPU_THIS_PTR smm_mode())
|
||||
{
|
||||
BX_PANIC(("SMI: system management mode still not implemented !"));
|
||||
// clear SMI pending flag and NMI disable flag when SMM was accepted
|
||||
// clear SMI pending flag and disable NMI when SMM was accepted
|
||||
BX_CPU_THIS_PTR smi_pending = 0;
|
||||
BX_CPU_THIS_PTR nmi_disable = 1;
|
||||
enter_system_management_mode();
|
||||
}
|
||||
|
||||
// Priority 4: Traps on Previous Instruction
|
||||
@ -687,9 +687,7 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
|
||||
else {
|
||||
// only bother comparing if any breakpoints enabled
|
||||
if (BX_CPU_THIS_PTR dr7 & 0x000000ff) {
|
||||
Bit32u iaddr =
|
||||
BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_CS) +
|
||||
BX_CPU_THIS_PTR prev_eip;
|
||||
Bit32u iaddr = BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_CS) + BX_CPU_THIS_PTR prev_eip;
|
||||
Bit32u dr6_bits;
|
||||
if ( (dr6_bits = hwdebug_compare(iaddr, 1, BX_HWDebugInstruction,
|
||||
BX_HWDebugInstruction)) )
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.275 2006-03-29 18:08:13 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.276 2006-04-05 17:31:30 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -903,9 +903,9 @@ typedef void (BX_CPU_C::*BxExecutePtr_tR)(bxInstruction_c *) BX_CPP_AttrRegparmN
|
||||
typedef bx_ptr_equiv_t bx_hostpageaddr_t;
|
||||
|
||||
typedef struct {
|
||||
bx_address lpf; // linear page frame
|
||||
Bit32u ppf; // physical page frame
|
||||
Bit32u accessBits; // Page Table Address for updating A & D bits
|
||||
bx_address lpf; // linear page frame
|
||||
bx_phy_address ppf; // physical page frame
|
||||
Bit32u accessBits; // Page Table Address for updating A & D bits
|
||||
bx_hostpageaddr_t hostPageAddr;
|
||||
} bx_TLB_entry;
|
||||
#endif // #if BX_USE_TLB
|
||||
@ -1102,11 +1102,11 @@ public: // for now...
|
||||
|
||||
/* Control registers */
|
||||
#if BX_CPU_LEVEL >= 2
|
||||
bx_cr0_t cr0;
|
||||
Bit32u cr1;
|
||||
bx_address cr2;
|
||||
bx_address cr3;
|
||||
bx_address cr3_masked;
|
||||
bx_cr0_t cr0;
|
||||
Bit32u cr1;
|
||||
bx_address cr2;
|
||||
bx_phy_address cr3;
|
||||
bx_phy_address cr3_masked;
|
||||
#endif
|
||||
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
@ -1232,7 +1232,7 @@ public: // for now...
|
||||
#if BX_SUPPORT_ICACHE
|
||||
bxICache_c iCache BX_CPP_AlignN(32);
|
||||
Bit32u fetchModeMask;
|
||||
Bit32u updateFetchModeMask(void);
|
||||
void updateFetchModeMask(void);
|
||||
#endif
|
||||
|
||||
struct {
|
||||
@ -1255,7 +1255,7 @@ public: // for now...
|
||||
virtual void ask (int level, const char *prefix, const char *fmt, va_list ap);
|
||||
#endif
|
||||
|
||||
void setEFlags(Bit32u val) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void setEFlags(Bit32u val) BX_CPP_AttrRegparmN(1);
|
||||
|
||||
#define lfMaskCF 0x0000000f
|
||||
#define lfMaskPF 0x000000f0
|
||||
@ -2622,7 +2622,6 @@ public: // for now...
|
||||
BX_SMF unsigned dbg_query_pending(void);
|
||||
BX_SMF Bit32u dbg_get_descriptor_l(bx_descriptor_t *);
|
||||
BX_SMF Bit32u dbg_get_descriptor_h(bx_descriptor_t *);
|
||||
BX_SMF Bit32u dbg_get_eflags(void);
|
||||
BX_SMF bx_bool dbg_is_begin_instr_bpoint(Bit16u cs, bx_address eip, bx_address laddr, bx_bool is_32, bx_bool is_64);
|
||||
BX_SMF bx_bool dbg_is_end_instr_bpoint(Bit16u cs, bx_address eip, bx_address laddr, bx_bool is_32, bx_bool is_64);
|
||||
#endif
|
||||
@ -2743,12 +2742,18 @@ public: // for now...
|
||||
BX_SMF void smram_save_state(Bit32u *smm_saved_state);
|
||||
BX_SMF bx_bool smram_restore_state(const Bit32u *smm_saved_state);
|
||||
BX_SMF int int_number(bx_segment_reg_t *seg);
|
||||
BX_SMF void CR3_change(bx_address value) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void SetCR0(Bit32u val_32);
|
||||
BX_SMF void CR3_change(bx_phy_address value) BX_CPP_AttrRegparmN(1);
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
BX_SMF bx_bool SetCR4(Bit32u val_32);
|
||||
#endif
|
||||
BX_SMF void pagingCR0Changed(Bit32u oldCR0, Bit32u newCR0) BX_CPP_AttrRegparmN(2);
|
||||
BX_SMF void pagingCR4Changed(Bit32u oldCR4, Bit32u newCR4) BX_CPP_AttrRegparmN(2);
|
||||
BX_SMF void pagingA20Changed(void);
|
||||
|
||||
BX_SMF void reset(unsigned source);
|
||||
BX_SMF void shutdown(void);
|
||||
BX_SMF void handleCpuModeChange(void);
|
||||
|
||||
BX_SMF void jump_protected(bxInstruction_c *, Bit16u cs, bx_address disp) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF void jmp_task_gate(bx_descriptor_t *gate_descriptor) BX_CPP_AttrRegparmN(1);
|
||||
@ -2802,6 +2807,8 @@ public: // for now...
|
||||
BX_SMF void parse_selector(Bit16u raw_selector, bx_selector_t *selector) BX_CPP_AttrRegparmN(2);
|
||||
BX_SMF void parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF Bit16u get_segment_ar_data(bx_descriptor_t *d) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF bx_bool set_segment_ar_data(bx_segment_reg_t *seg, Bit16u raw_selector,
|
||||
bx_address base, Bit32u limit, Bit16u ar_data);
|
||||
BX_SMF void load_ldtr(bx_selector_t *selector, bx_descriptor_t *descriptor);
|
||||
BX_SMF void check_cs(bx_descriptor_t *descriptor, Bit16u cs_raw, Bit8u check_rpl, Bit8u check_cpl);
|
||||
BX_SMF void load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cpl) BX_CPP_AttrRegparmN(3);
|
||||
@ -2922,18 +2929,13 @@ public: // for now...
|
||||
BX_SMF void check_exceptionsSSE(int);
|
||||
BX_SMF void print_state_SSE(void);
|
||||
#endif
|
||||
|
||||
BX_SMF void SetCR0(Bit32u val_32);
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
BX_SMF bx_bool SetCR4(Bit32u val_32);
|
||||
#endif
|
||||
};
|
||||
|
||||
#if BX_SUPPORT_ICACHE
|
||||
|
||||
BX_CPP_INLINE Bit32u BX_CPU_C::updateFetchModeMask(void)
|
||||
BX_CPP_INLINE void BX_CPU_C::updateFetchModeMask(void)
|
||||
{
|
||||
return (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b << 31)
|
||||
fetchModeMask = (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b << 31)
|
||||
#if BX_SUPPORT_X86_64
|
||||
| ((BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64)<<30)
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpuid.cc,v 1.34 2006-03-06 22:02:52 sshwarts Exp $
|
||||
// $Id: cpuid.cc,v 1.35 2006-04-05 17:31:30 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -246,7 +246,7 @@ void BX_CPU_C::CPUID(bxInstruction_c *i)
|
||||
// [23:16] Number of logical processors in one physical processor
|
||||
// [31:24] Local Apic ID
|
||||
// ECX: Feature Flags::Extended
|
||||
// [0:0] PNI
|
||||
// [0:0] SSE3
|
||||
// [2:1] Reserved
|
||||
// [3:3] MONITOR/MWAIT
|
||||
// [4:4] CPL qualified debug store available
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: data_xfer32.cc,v 1.37 2006-03-26 18:58:01 sshwarts Exp $
|
||||
// $Id: data_xfer32.cc,v 1.38 2006-04-05 17:31:30 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -34,13 +34,12 @@
|
||||
void BX_CPU_C::XCHG_ERXEAX(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u temp32 = EAX;
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
RAX = BX_CPU_THIS_PTR gen_reg[i->opcodeReg()].dword.erx;
|
||||
BX_CPU_THIS_PTR gen_reg[i->opcodeReg()].dword.erx = temp32;
|
||||
RAX = BX_READ_32BIT_REG(i->opcodeReg());
|
||||
BX_WRITE_32BIT_REGZ(i->opcodeReg(), temp32);
|
||||
#else
|
||||
EAX = BX_CPU_THIS_PTR gen_reg[i->opcodeReg()].dword.erx;
|
||||
BX_CPU_THIS_PTR gen_reg[i->opcodeReg()].dword.erx = temp32;
|
||||
EAX = BX_READ_32BIT_REG(i->opcodeReg());
|
||||
BX_WRITE_32BIT_REG(i->opcodeReg(), temp32);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: debugstuff.cc,v 1.62 2006-03-29 18:08:13 sshwarts Exp $
|
||||
// $Id: debugstuff.cc,v 1.63 2006-04-05 17:31:30 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -37,23 +37,34 @@ void BX_CPU_C::debug_disasm_instruction(bx_address offset)
|
||||
bx_bool valid;
|
||||
Bit32u phy_addr;
|
||||
Bit8u instr_buf[16];
|
||||
char char_buf[256];
|
||||
unsigned isize;
|
||||
char char_buf[512];
|
||||
unsigned isize, i=0;
|
||||
|
||||
static char letters[20] = "0123456789ABCDEF";
|
||||
static disassembler bx_disassemble;
|
||||
|
||||
dbg_xlate_linear2phy(BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_CS) + offset,
|
||||
&phy_addr, &valid);
|
||||
if (valid && BX_CPU_THIS_PTR mem!=NULL) {
|
||||
BX_CPU_THIS_PTR mem->dbg_fetch_mem(phy_addr, 16, instr_buf);
|
||||
char_buf[i++] = '>';
|
||||
char_buf[i++] = '>';
|
||||
char_buf[i++] = ' ';
|
||||
isize = bx_disassemble.disasm(
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b,
|
||||
BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64,
|
||||
BX_CPU_THIS_PTR get_segment_base(BX_SEG_REG_CS), offset,
|
||||
instr_buf, char_buf);
|
||||
for (unsigned j=0; j<isize; j++)
|
||||
BX_INFO((">> %02x", (unsigned) instr_buf[j]));
|
||||
BX_INFO((">> : %s", char_buf));
|
||||
instr_buf, char_buf+i);
|
||||
i=strlen(char_buf);
|
||||
char_buf[i++] = ' ';
|
||||
char_buf[i++] = ':';
|
||||
char_buf[i++] = ' ';
|
||||
for (unsigned j=0; j<isize; j++) {
|
||||
char_buf[i++] = letters[(instr_buf[j] >> 4) & 0xf];
|
||||
char_buf[i++] = letters[(instr_buf[j] >> 0) & 0xf];
|
||||
}
|
||||
char_buf[i] = 0;
|
||||
BX_INFO(("%s", char_buf));
|
||||
}
|
||||
else {
|
||||
BX_INFO(("(instruction unavailable) page not present"));
|
||||
@ -206,10 +217,8 @@ void BX_CPU_C::debug(bx_address offset)
|
||||
(unsigned) (BX_CPU_THIS_PTR cr0.val32), 0,
|
||||
(unsigned) (BX_CPU_THIS_PTR cr2 >> 32),
|
||||
(unsigned) (BX_CPU_THIS_PTR cr2 & 0xffffffff)));
|
||||
BX_INFO(("| CR3=0x%08x%08x CR4=0x%08x",
|
||||
(unsigned) (BX_CPU_THIS_PTR cr3 >> 32),
|
||||
(unsigned) (BX_CPU_THIS_PTR cr3 & 0xffffffff),
|
||||
BX_CPU_THIS_PTR cr4.getRegister()));
|
||||
BX_INFO(("| CR3=0x%08x CR4=0x%08x",
|
||||
(unsigned) BX_CPU_THIS_PTR cr3, BX_CPU_THIS_PTR cr4.getRegister()));
|
||||
#else
|
||||
BX_INFO(("| EIP=%08x (%08x)", (unsigned) EIP,
|
||||
(unsigned) BX_CPU_THIS_PTR prev_eip));
|
||||
@ -245,7 +254,7 @@ Bit32u BX_CPU_C::dbg_get_reg(unsigned reg)
|
||||
switch (reg) {
|
||||
case BX_DBG_REG_EIP: return(EIP);
|
||||
case BX_DBG_REG_EFLAGS:
|
||||
return_val32 = dbg_get_eflags();
|
||||
return_val32 = BX_CPU_THIS_PTR read_eflags();
|
||||
return(return_val32);
|
||||
case BX_DBG_REG_CS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
|
||||
case BX_DBG_REG_SS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
|
||||
@ -269,7 +278,7 @@ bx_bool BX_CPU_C::dbg_set_reg(unsigned reg, Bit32u val)
|
||||
case BX_DBG_REG_EIP: EIP = val; return(1);
|
||||
case BX_DBG_REG_EFLAGS:
|
||||
BX_INFO(("dbg_set_reg: can not handle eflags yet."));
|
||||
if ( val & 0xffff0000 ) {
|
||||
if (val & 0xffff0000) {
|
||||
BX_INFO(("dbg_set_reg: can not set upper 16 bits of eflags."));
|
||||
return(0);
|
||||
}
|
||||
@ -357,11 +366,6 @@ unsigned BX_CPU_C::dbg_query_pending(void)
|
||||
return(ret);
|
||||
}
|
||||
|
||||
Bit32u BX_CPU_C::dbg_get_eflags(void)
|
||||
{
|
||||
return (BX_CPU_THIS_PTR read_eflags());
|
||||
}
|
||||
|
||||
Bit32u BX_CPU_C::dbg_get_descriptor_l(bx_descriptor_t *d)
|
||||
{
|
||||
Bit32u val;
|
||||
@ -489,14 +493,13 @@ bx_bool BX_CPU_C::dbg_get_cpu(bx_dbg_cpu_t *cpu)
|
||||
cpu->ebx = EBX;
|
||||
cpu->ecx = ECX;
|
||||
cpu->edx = EDX;
|
||||
|
||||
cpu->ebp = EBP;
|
||||
cpu->esi = ESI;
|
||||
cpu->edi = EDI;
|
||||
cpu->esp = ESP;
|
||||
cpu->eip = EIP;
|
||||
|
||||
cpu->eflags = dbg_get_eflags();
|
||||
cpu->eip = EIP;
|
||||
cpu->eflags = BX_CPU_THIS_PTR read_eflags();
|
||||
|
||||
cpu->cs.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
|
||||
cpu->cs.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache);
|
||||
@ -552,7 +555,6 @@ bx_bool BX_CPU_C::dbg_get_cpu(bx_dbg_cpu_t *cpu)
|
||||
cpu->dr7 = BX_CPU_THIS_PTR dr7;
|
||||
|
||||
#if BX_CPU_LEVEL >= 2
|
||||
// cr0:32=pg,cd,nw,am,wp,ne,ts,em,mp,pe
|
||||
cpu->cr0 = BX_CPU_THIS_PTR cr0.val32;
|
||||
cpu->cr1 = 0;
|
||||
cpu->cr2 = BX_CPU_THIS_PTR cr2;
|
||||
@ -579,75 +581,75 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||
|
||||
// CS, SS, DS, ES, FS, GS descriptor checks
|
||||
if (!cpu->cs.valid) {
|
||||
BX_ERROR(( "Error: CS not valid" ));
|
||||
BX_ERROR(("Error: CS not valid"));
|
||||
return(0); // error
|
||||
}
|
||||
if ( (cpu->cs.des_h & 0x1000) == 0 ) {
|
||||
BX_ERROR(( "Error: CS not application type" ));
|
||||
if ((cpu->cs.des_h & 0x1000) == 0) {
|
||||
BX_ERROR(("Error: CS not application type"));
|
||||
return(0); // error
|
||||
}
|
||||
if ( (cpu->cs.des_h & 0x0800) == 0 ) {
|
||||
BX_ERROR(( "Error: CS not executable" ));
|
||||
if ((cpu->cs.des_h & 0x0800) == 0) {
|
||||
BX_ERROR(("Error: CS not executable"));
|
||||
return(0); // error
|
||||
}
|
||||
|
||||
if (!cpu->ss.valid) {
|
||||
BX_ERROR(( "Error: SS not valid" ));
|
||||
BX_ERROR(("Error: SS not valid"));
|
||||
return(0); // error
|
||||
}
|
||||
if ( (cpu->ss.des_h & 0x1000) == 0 ) {
|
||||
BX_ERROR(( "Error: SS not application type" ));
|
||||
if ((cpu->ss.des_h & 0x1000) == 0) {
|
||||
BX_ERROR(("Error: SS not application type"));
|
||||
return(0); // error
|
||||
}
|
||||
|
||||
if (cpu->ds.valid) {
|
||||
if ( (cpu->ds.des_h & 0x1000) == 0 ) {
|
||||
BX_ERROR(( "Error: DS not application type" ));
|
||||
if ((cpu->ds.des_h & 0x1000) == 0) {
|
||||
BX_ERROR(("Error: DS not application type"));
|
||||
return(0); // error
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu->es.valid) {
|
||||
if ( (cpu->es.des_h & 0x1000) == 0 ) {
|
||||
BX_ERROR(( "Error: ES not application type" ));
|
||||
if ((cpu->es.des_h & 0x1000) == 0) {
|
||||
BX_ERROR(("Error: ES not application type"));
|
||||
return(0); // error
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu->fs.valid) {
|
||||
if ( (cpu->fs.des_h & 0x1000) == 0 ) {
|
||||
BX_ERROR(( "Error: FS not application type" ));
|
||||
if ((cpu->fs.des_h & 0x1000) == 0) {
|
||||
BX_ERROR(("Error: FS not application type"));
|
||||
return(0); // error
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu->gs.valid) {
|
||||
if ( (cpu->gs.des_h & 0x1000) == 0 ) {
|
||||
BX_ERROR(( "Error: GS not application type" ));
|
||||
if ((cpu->gs.des_h & 0x1000) == 0) {
|
||||
BX_ERROR(("Error: GS not application type"));
|
||||
return(0); // error
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu->ldtr.valid) {
|
||||
if ( cpu->ldtr.des_h & 0x1000 ) {
|
||||
BX_ERROR(( "Error: LDTR not system type" ));
|
||||
if (cpu->ldtr.des_h & 0x1000) {
|
||||
BX_ERROR(("Error: LDTR not system type"));
|
||||
return(0); // error
|
||||
}
|
||||
if ( ((cpu->ldtr.des_h >> 8) & 0x0f) != 2 ) {
|
||||
BX_ERROR(( "Error: LDTR descriptor type not LDT" ));
|
||||
if (((cpu->ldtr.des_h >> 8) & 0x0f) != BX_SYS_SEGMENT_LDT) {
|
||||
BX_ERROR(("Error: LDTR descriptor type not LDT"));
|
||||
return(0); // error
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu->tr.valid) {
|
||||
if ( cpu->tr.des_h & 0x1000 ) {
|
||||
BX_ERROR(( "Error: TR not system type"));
|
||||
if (cpu->tr.des_h & 0x1000) {
|
||||
BX_ERROR(("Error: TR not system type"));
|
||||
return(0); // error
|
||||
}
|
||||
type = (cpu->tr.des_h >> 8) & 0x0f;
|
||||
|
||||
if ( (type != 1) && (type != 9) ) {
|
||||
BX_ERROR(( "Error: TR descriptor type not TSS" ));
|
||||
if ((type != 1) && (type != 9)) {
|
||||
BX_ERROR(("Error: TR descriptor type not TSS"));
|
||||
return(0); // error
|
||||
}
|
||||
}
|
||||
@ -664,33 +666,10 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||
ESI = cpu->esi;
|
||||
EDI = cpu->edi;
|
||||
ESP = cpu->esp;
|
||||
|
||||
// eflags
|
||||
val = cpu->eflags;
|
||||
BX_CPU_THIS_PTR set_CF(val & 0x01); val >>= 2;
|
||||
BX_CPU_THIS_PTR set_PF(val & 0x01); val >>= 2;
|
||||
BX_CPU_THIS_PTR set_AF(val & 0x01); val >>= 2;
|
||||
BX_CPU_THIS_PTR set_ZF(val & 0x01); val >>= 1;
|
||||
BX_CPU_THIS_PTR set_SF(val & 0x01); val >>= 1;
|
||||
BX_CPU_THIS_PTR set_TF (val & 0x01); val >>= 1;
|
||||
BX_CPU_THIS_PTR set_IF (val & 0x01); val >>= 1;
|
||||
BX_CPU_THIS_PTR set_DF (val & 0x01); val >>= 1;
|
||||
BX_CPU_THIS_PTR set_OF(val & 0x01); val >>= 1;
|
||||
BX_CPU_THIS_PTR set_IOPL (val & 0x03); val >>= 2;
|
||||
BX_CPU_THIS_PTR set_NT (val & 0x01); val >>= 2;
|
||||
BX_CPU_THIS_PTR set_RF (val & 0x01); val >>= 1;
|
||||
BX_CPU_THIS_PTR set_VM (val & 0x01); val >>= 1;
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
BX_CPU_THIS_PTR set_AC (val & 0x01); val >>= 1;
|
||||
//BX_CPU_THIS_PTR eflags.set_VIF (val & 0x01);
|
||||
val >>= 1;
|
||||
//BX_CPU_THIS_PTR eflags.set_VIP (val & 0x01);
|
||||
val >>= 1;
|
||||
BX_CPU_THIS_PTR set_ID (val & 0x01);
|
||||
#endif
|
||||
|
||||
EIP = cpu->eip;
|
||||
|
||||
setEFlags(cpu->eflags);
|
||||
|
||||
// CS:
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = cpu->cs.sel;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = cpu->cs.sel >> 3;
|
||||
@ -755,7 +734,6 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit;
|
||||
|
||||
|
||||
// DS:
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = cpu->ds.sel;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index = cpu->ds.sel >> 3;
|
||||
@ -786,7 +764,6 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit;
|
||||
|
||||
|
||||
// ES:
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = cpu->es.sel;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index = cpu->es.sel >> 3;
|
||||
@ -817,7 +794,6 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit;
|
||||
|
||||
|
||||
// FS:
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = cpu->fs.sel;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.index = cpu->fs.sel >> 3;
|
||||
@ -848,7 +824,6 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit;
|
||||
|
||||
|
||||
// GS:
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = cpu->gs.sel;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.index = cpu->gs.sel >> 3;
|
||||
@ -879,21 +854,21 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit;
|
||||
|
||||
// LDTR:
|
||||
// LDTR
|
||||
BX_CPU_THIS_PTR ldtr.selector.value = cpu->ldtr.sel;
|
||||
BX_CPU_THIS_PTR ldtr.selector.index = cpu->ldtr.sel >> 3;
|
||||
BX_CPU_THIS_PTR ldtr.selector.ti = (cpu->ldtr.sel >> 2) & 0x01;
|
||||
BX_CPU_THIS_PTR ldtr.selector.rpl = cpu->ldtr.sel & 0x03;
|
||||
|
||||
BX_CPU_THIS_PTR ldtr.cache.valid = cpu->ldtr.valid;
|
||||
BX_CPU_THIS_PTR ldtr.cache.p = (cpu->ldtr.des_h >> 15) & 0x01;
|
||||
BX_CPU_THIS_PTR ldtr.cache.dpl = (cpu->ldtr.des_h >> 13) & 0x03;
|
||||
BX_CPU_THIS_PTR ldtr.cache.segment = (cpu->ldtr.des_h >> 12) & 0x01;
|
||||
BX_CPU_THIS_PTR ldtr.cache.type = (cpu->ldtr.des_h >> 8) & 0x0f;
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.base = (cpu->ldtr.des_l >> 16);
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.base |= (cpu->ldtr.des_h & 0xff) << 16;
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.base |= (cpu->ldtr.des_h & 0xff000000);
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = (cpu->ldtr.des_l & 0xffff);
|
||||
BX_CPU_THIS_PTR ldtr.cache.valid = cpu->ldtr.valid;
|
||||
BX_CPU_THIS_PTR ldtr.cache.p = (cpu->ldtr.des_h >> 15) & 0x01;
|
||||
BX_CPU_THIS_PTR ldtr.cache.dpl = (cpu->ldtr.des_h >> 13) & 0x03;
|
||||
BX_CPU_THIS_PTR ldtr.cache.segment = (cpu->ldtr.des_h >> 12) & 0x01;
|
||||
BX_CPU_THIS_PTR ldtr.cache.type = (cpu->ldtr.des_h >> 8) & 0x0f;
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.base = (cpu->ldtr.des_l >> 16);
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.base |= (cpu->ldtr.des_h & 0xff) << 16;
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.base |= (cpu->ldtr.des_h & 0xff000000);
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = (cpu->ldtr.des_l & 0xffff);
|
||||
|
||||
// TR
|
||||
type = (cpu->tr.des_h >> 8) & 0x0f;
|
||||
@ -903,16 +878,16 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||
BX_CPU_THIS_PTR tr.selector.ti = (cpu->tr.sel >> 2) & 0x01;
|
||||
BX_CPU_THIS_PTR tr.selector.rpl = cpu->tr.sel & 0x03;
|
||||
|
||||
BX_CPU_THIS_PTR tr.cache.valid = cpu->tr.valid;
|
||||
BX_CPU_THIS_PTR tr.cache.p = (cpu->tr.des_h >> 15) & 0x01;
|
||||
BX_CPU_THIS_PTR tr.cache.dpl = (cpu->tr.des_h >> 13) & 0x03;
|
||||
BX_CPU_THIS_PTR tr.cache.segment = (cpu->tr.des_h >> 12) & 0x01;
|
||||
BX_CPU_THIS_PTR tr.cache.type = type;
|
||||
BX_CPU_THIS_PTR tr.cache.valid = cpu->tr.valid;
|
||||
BX_CPU_THIS_PTR tr.cache.p = (cpu->tr.des_h >> 15) & 0x01;
|
||||
BX_CPU_THIS_PTR tr.cache.dpl = (cpu->tr.des_h >> 13) & 0x03;
|
||||
BX_CPU_THIS_PTR tr.cache.segment = (cpu->tr.des_h >> 12) & 0x01;
|
||||
BX_CPU_THIS_PTR tr.cache.type = type;
|
||||
if (type == 1) { // 286 TSS
|
||||
BX_CPU_THIS_PTR tr.cache.u.tss286.base = (cpu->tr.des_l >> 16);
|
||||
BX_CPU_THIS_PTR tr.cache.u.tss286.base |= (cpu->tr.des_h & 0xff) << 16;
|
||||
BX_CPU_THIS_PTR tr.cache.u.tss286.limit = (cpu->tr.des_l & 0xffff);
|
||||
}
|
||||
}
|
||||
else { // type == 9, 386 TSS
|
||||
BX_CPU_THIS_PTR tr.cache.u.tss386.base = (cpu->tr.des_l >> 16);
|
||||
BX_CPU_THIS_PTR tr.cache.u.tss386.base |= (cpu->tr.des_h & 0xff) << 16;
|
||||
@ -921,14 +896,13 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||
BX_CPU_THIS_PTR tr.cache.u.tss386.limit |= (cpu->tr.des_h & 0x000f0000);
|
||||
BX_CPU_THIS_PTR tr.cache.u.tss386.g = (cpu->tr.des_h >> 23) & 0x01;
|
||||
BX_CPU_THIS_PTR tr.cache.u.tss386.avl = (cpu->tr.des_h >> 20) & 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// gdtr
|
||||
// GDTR
|
||||
BX_CPU_THIS_PTR gdtr.base = cpu->gdtr.base;
|
||||
BX_CPU_THIS_PTR gdtr.limit = cpu->gdtr.limit;
|
||||
|
||||
// idtr
|
||||
// IDTR
|
||||
BX_CPU_THIS_PTR idtr.base = cpu->idtr.base;
|
||||
BX_CPU_THIS_PTR idtr.limit = cpu->idtr.limit;
|
||||
|
||||
@ -945,7 +919,7 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||
SetCR0(cpu->cr0);
|
||||
BX_CPU_THIS_PTR cr1 = cpu->cr1;
|
||||
BX_CPU_THIS_PTR cr2 = cpu->cr2;
|
||||
BX_CPU_THIS_PTR cr3 = cpu->cr3;
|
||||
CR3_change(cpu->cr3);
|
||||
#endif
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
BX_CPU_THIS_PTR cr4.setRegister(cpu->cr4);
|
||||
@ -956,7 +930,6 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||
//
|
||||
// flush cached items, prefetch, paging, etc
|
||||
//
|
||||
BX_CPU_THIS_PTR CR3_change(cpu->cr3);
|
||||
BX_CPU_THIS_PTR invalidate_prefetch_q();
|
||||
BX_CPU_THIS_PTR async_event = 1;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: exception.cc,v 1.76 2006-03-06 22:02:53 sshwarts Exp $
|
||||
// $Id: exception.cc,v 1.77 2006-04-05 17:31:30 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -858,6 +858,7 @@ void BX_CPU_C::exception(unsigned vector, Bit16u error_code, bx_bool is_INT)
|
||||
else {
|
||||
BX_PANIC(("exception(): 3rd (%d) exception with no resolution", vector));
|
||||
BX_ERROR(("WARNING: Any simulation after this point is completely bogus !"));
|
||||
shutdown();
|
||||
}
|
||||
#if BX_DEBUGGER
|
||||
bx_guard.special_unwind_stack = true;
|
||||
|
@ -95,14 +95,13 @@ void bx_external_debugger(BX_CPU_C *cpu)
|
||||
regs.fsbase = cpu->sregs[BX_SEG_REG_FS].cache.u.segment.base;
|
||||
regs.gsbase = cpu->sregs[BX_SEG_REG_GS].cache.u.segment.base;
|
||||
#if BX_SUPPORT_X86_64
|
||||
regs.efer = cpu->get_EFER();
|
||||
regs.efer = cpu->get_EFER();
|
||||
#else
|
||||
regs.efer = 0;
|
||||
regs.efer = 0;
|
||||
#endif
|
||||
|
||||
if (debug_loaded == 0) {
|
||||
HINSTANCE hdbg;
|
||||
|
||||
debug_loaded = 1;
|
||||
hdbg = LoadLibrary("debug.dll");
|
||||
call_debugger = (void (*)(TRegs *,Bit8u *, Bit32u)) GetProcAddress(hdbg,"call_debugger");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode.cc,v 1.89 2006-03-22 20:47:11 sshwarts Exp $
|
||||
// $Id: fetchdecode.cc,v 1.90 2006-04-05 17:31:30 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -721,7 +721,11 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
|
||||
/* 0F 1C */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1D */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1E */ { 0, &BX_CPU_C::BxError },
|
||||
#if BX_CPU_LEVEL < 6
|
||||
/* 0F 1F */ { 0, &BX_CPU_C::BxError },
|
||||
#else
|
||||
/* 0F 1F */ { BxAnother, &BX_CPU_C::NOP }, // multi-byte NOP
|
||||
#endif
|
||||
/* 0F 20 */ { BxAnother, &BX_CPU_C::MOV_RdCd },
|
||||
/* 0F 21 */ { BxAnother, &BX_CPU_C::MOV_RdDd },
|
||||
/* 0F 22 */ { BxAnother, &BX_CPU_C::MOV_CdRd },
|
||||
@ -1267,7 +1271,11 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
|
||||
/* 0F 1C */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1D */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1E */ { 0, &BX_CPU_C::BxError },
|
||||
#if BX_CPU_LEVEL < 6
|
||||
/* 0F 1F */ { 0, &BX_CPU_C::BxError },
|
||||
#else
|
||||
/* 0F 1F */ { BxAnother, &BX_CPU_C::NOP }, // multi-byte NOP
|
||||
#endif
|
||||
/* 0F 20 */ { BxAnother, &BX_CPU_C::MOV_RdCd },
|
||||
/* 0F 21 */ { BxAnother, &BX_CPU_C::MOV_RdDd },
|
||||
/* 0F 22 */ { BxAnother, &BX_CPU_C::MOV_CdRd },
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode.h,v 1.21 2006-03-22 20:47:11 sshwarts Exp $
|
||||
// $Id: fetchdecode.h,v 1.22 2006-04-05 17:31:31 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2003 Stanislav Shwartsman
|
||||
@ -123,7 +123,7 @@ static BxOpcodeInfo_t BxOpcodeInfo_FPGroupD8[8] = {
|
||||
/* 0 */ { 0, &BX_CPU_C::FADD_SINGLE_REAL },
|
||||
/* 1 */ { 0, &BX_CPU_C::FMUL_SINGLE_REAL },
|
||||
/* 2 */ { 0, &BX_CPU_C::FCOM_SINGLE_REAL },
|
||||
/* 3 */ { 0, &BX_CPU_C::FCOM_SINGLE_REAL }, // FCOMP_SINGLE_REAL
|
||||
/* 3 */ { 0, &BX_CPU_C::FCOM_SINGLE_REAL }, // FCOMP_SINGLE_REAL
|
||||
/* 4 */ { 0, &BX_CPU_C::FSUB_SINGLE_REAL },
|
||||
/* 5 */ { 0, &BX_CPU_C::FSUBR_SINGLE_REAL },
|
||||
/* 6 */ { 0, &BX_CPU_C::FDIV_SINGLE_REAL },
|
||||
@ -171,7 +171,7 @@ static BxOpcodeInfo_t BxOpcodeInfo_FPGroupDC[8] = {
|
||||
/* 0 */ { 0, &BX_CPU_C::FADD_DOUBLE_REAL },
|
||||
/* 1 */ { 0, &BX_CPU_C::FMUL_DOUBLE_REAL },
|
||||
/* 2 */ { 0, &BX_CPU_C::FCOM_DOUBLE_REAL },
|
||||
/* 3 */ { 0, &BX_CPU_C::FCOM_DOUBLE_REAL }, // FCOMP_DOUBLE_REAL
|
||||
/* 3 */ { 0, &BX_CPU_C::FCOM_DOUBLE_REAL }, // FCOMP_DOUBLE_REAL
|
||||
/* 4 */ { 0, &BX_CPU_C::FSUB_DOUBLE_REAL },
|
||||
/* 5 */ { 0, &BX_CPU_C::FSUBR_DOUBLE_REAL },
|
||||
/* 6 */ { 0, &BX_CPU_C::FDIV_DOUBLE_REAL },
|
||||
@ -1037,8 +1037,8 @@ static BxOpcodeInfo_t BxOpcodeGroupSSE_0f11[4] = {
|
||||
static BxOpcodeInfo_t BxOpcodeGroupSSE_0f12[4] = {
|
||||
/* -- */ { 0, &BX_CPU_C::MOVLPS_VpsMq },
|
||||
/* 66 */ { 0, &BX_CPU_C::MOVLPD_VsdMq },
|
||||
/* F2 */ { 0, &BX_CPU_C::MOVDDUP_VpdWq }, // PNI
|
||||
/* F3 */ { 0, &BX_CPU_C::MOVSLDUP_VpsWps } // PNI
|
||||
/* F2 */ { 0, &BX_CPU_C::MOVDDUP_VpdWq }, // SSE3
|
||||
/* F3 */ { 0, &BX_CPU_C::MOVSLDUP_VpsWps } // SSE3
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t BxOpcodeGroupSSE_0f13[4] = {
|
||||
@ -1066,7 +1066,7 @@ static BxOpcodeInfo_t BxOpcodeGroupSSE_0f16[4] = {
|
||||
/* -- */ { 0, &BX_CPU_C::MOVHPS_VpsMq },
|
||||
/* 66 */ { 0, &BX_CPU_C::MOVHPD_VsdMq },
|
||||
/* F2 */ { 0, &BX_CPU_C::BxError },
|
||||
/* F3 */ { 0, &BX_CPU_C::MOVSHDUP_VpsWps } // PNI
|
||||
/* F3 */ { 0, &BX_CPU_C::MOVSHDUP_VpsWps } // SSE3
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t BxOpcodeGroupSSE_0f17[4] = {
|
||||
@ -1386,15 +1386,15 @@ static BxOpcodeInfo_t BxOpcodeGroupSSE_0f76[4] = {
|
||||
|
||||
static BxOpcodeInfo_t BxOpcodeGroupSSE_0f7c[4] = {
|
||||
/* -- */ { 0, &BX_CPU_C::BxError },
|
||||
/* 66 */ { 0, &BX_CPU_C::HADDPD_VpdWpd }, // PNI
|
||||
/* F2 */ { 0, &BX_CPU_C::HADDPS_VpsWps }, // PNI
|
||||
/* 66 */ { 0, &BX_CPU_C::HADDPD_VpdWpd }, // SSE3
|
||||
/* F2 */ { 0, &BX_CPU_C::HADDPS_VpsWps }, // SSE3
|
||||
/* F3 */ { 0, &BX_CPU_C::BxError }
|
||||
};
|
||||
|
||||
static BxOpcodeInfo_t BxOpcodeGroupSSE_0f7d[4] = {
|
||||
/* -- */ { 0, &BX_CPU_C::BxError },
|
||||
/* 66 */ { 0, &BX_CPU_C::HSUBPD_VpdWpd }, // PNI
|
||||
/* F2 */ { 0, &BX_CPU_C::HSUBPS_VpsWps }, // PNI
|
||||
/* 66 */ { 0, &BX_CPU_C::HSUBPD_VpdWpd }, // SSE3
|
||||
/* F2 */ { 0, &BX_CPU_C::HSUBPS_VpsWps }, // SSE3
|
||||
/* F3 */ { 0, &BX_CPU_C::BxError }
|
||||
};
|
||||
|
||||
@ -1449,8 +1449,8 @@ static BxOpcodeInfo_t BxOpcodeGroupSSE_0fc6[4] = {
|
||||
|
||||
static BxOpcodeInfo_t BxOpcodeGroupSSE_0fd0[4] = {
|
||||
/* -- */ { 0, &BX_CPU_C::BxError },
|
||||
/* 66 */ { 0, &BX_CPU_C::ADDSUBPD_VpdWpd }, // PNI
|
||||
/* F2 */ { 0, &BX_CPU_C::ADDSUBPS_VpsWps }, // PNI
|
||||
/* 66 */ { 0, &BX_CPU_C::ADDSUBPD_VpdWpd }, // SSE3
|
||||
/* F2 */ { 0, &BX_CPU_C::ADDSUBPS_VpsWps }, // SSE3
|
||||
/* F3 */ { 0, &BX_CPU_C::BxError }
|
||||
};
|
||||
|
||||
@ -1674,7 +1674,7 @@ static BxOpcodeInfo_t BxOpcodeGroupSSE_0fef[4] = {
|
||||
static BxOpcodeInfo_t BxOpcodeGroupSSE_0ff0[4] = {
|
||||
/* -- */ { 0, &BX_CPU_C::BxError },
|
||||
/* 66 */ { 0, &BX_CPU_C::BxError },
|
||||
/* F2 */ { 0, &BX_CPU_C::LDDQU_VdqMdq }, // PNI
|
||||
/* F2 */ { 0, &BX_CPU_C::LDDQU_VdqMdq }, // SSE3
|
||||
/* F3 */ { 0, &BX_CPU_C::BxError }
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode64.cc,v 1.89 2006-03-22 20:47:11 sshwarts Exp $
|
||||
// $Id: fetchdecode64.cc,v 1.90 2006-04-05 17:31:31 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -698,7 +698,7 @@ static BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
|
||||
/* 8D */ { BxAnother, &BX_CPU_C::LEA_GwM },
|
||||
/* 8E */ { BxAnother, &BX_CPU_C::MOV_SwEw },
|
||||
/* 8F */ { BxAnother, &BX_CPU_C::POP_Ew },
|
||||
/* 90 */ { 0, &BX_CPU_C::NOP },
|
||||
/* 90 */ { 0, &BX_CPU_C::XCHG_RXAX }, // handles XCHG R8w, AX
|
||||
/* 91 */ { 0, &BX_CPU_C::XCHG_RXAX },
|
||||
/* 92 */ { 0, &BX_CPU_C::XCHG_RXAX },
|
||||
/* 93 */ { 0, &BX_CPU_C::XCHG_RXAX },
|
||||
@ -754,8 +754,8 @@ static BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
|
||||
/* C5 */ { 0, &BX_CPU_C::BxError },
|
||||
/* C6 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::MOV_EbIb },
|
||||
/* C7 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::MOV_EwIw },
|
||||
/* C8 */ { BxImmediate_IwIb, &BX_CPU_C::ENTER64_IwIb },
|
||||
/* C9 */ { 0, &BX_CPU_C::LEAVE64 },
|
||||
/* C8 */ { BxImmediate_IwIb, &BX_CPU_C::ENTER_IwIb },
|
||||
/* C9 */ { 0, &BX_CPU_C::LEAVE },
|
||||
/* CA */ { BxImmediate_Iw, &BX_CPU_C::RETfar16_Iw },
|
||||
/* CB */ { 0, &BX_CPU_C::RETfar16 },
|
||||
/* CC */ { 0, &BX_CPU_C::INT3 },
|
||||
@ -848,7 +848,7 @@ static BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
|
||||
/* 0F 1C */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1D */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1E */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1F */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1F */ { BxAnother, &BX_CPU_C::NOP }, // multi-byte NOP
|
||||
/* 0F 20 */ { BxAnother, &BX_CPU_C::MOV_RqCq },
|
||||
/* 0F 21 */ { BxAnother, &BX_CPU_C::MOV_RdDd },
|
||||
/* 0F 22 */ { BxAnother, &BX_CPU_C::MOV_CqRq },
|
||||
@ -1219,7 +1219,7 @@ static BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
|
||||
/* 8D */ { BxAnother, &BX_CPU_C::LEA_GdM },
|
||||
/* 8E */ { BxAnother, &BX_CPU_C::MOV_SwEw },
|
||||
/* 8F */ { BxAnother, &BX_CPU_C::POP_Eq },
|
||||
/* 90 */ { 0, &BX_CPU_C::NOP },
|
||||
/* 90 */ { 0, &BX_CPU_C::XCHG_ERXEAX }, // handles XCHG R8d, EAX
|
||||
/* 91 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
|
||||
/* 92 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
|
||||
/* 93 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
|
||||
@ -1369,7 +1369,7 @@ static BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
|
||||
/* 0F 1C */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1D */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1E */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1F */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1F */ { BxAnother, &BX_CPU_C::NOP }, // multi-byte NOP
|
||||
/* 0F 20 */ { BxAnother, &BX_CPU_C::MOV_RqCq },
|
||||
/* 0F 21 */ { BxAnother, &BX_CPU_C::MOV_RdDd },
|
||||
/* 0F 22 */ { BxAnother, &BX_CPU_C::MOV_CqRq },
|
||||
@ -1740,7 +1740,7 @@ static BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
|
||||
/* 8D */ { BxAnother, &BX_CPU_C::LEA_GqM },
|
||||
/* 8E */ { BxAnother, &BX_CPU_C::MOV_SwEw },
|
||||
/* 8F */ { BxAnother, &BX_CPU_C::POP_Eq },
|
||||
/* 90 */ { 0, &BX_CPU_C::NOP },
|
||||
/* 90 */ { 0, &BX_CPU_C::XCHG_RRXRAX }, // handles XCHG R8, RAX
|
||||
/* 91 */ { 0, &BX_CPU_C::XCHG_RRXRAX },
|
||||
/* 92 */ { 0, &BX_CPU_C::XCHG_RRXRAX },
|
||||
/* 93 */ { 0, &BX_CPU_C::XCHG_RRXRAX },
|
||||
@ -1890,7 +1890,7 @@ static BxOpcodeInfo_t BxOpcodeInfo64[512*3] = {
|
||||
/* 0F 1C */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1D */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1E */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1F */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 1F */ { BxAnother, &BX_CPU_C::NOP }, // multi-byte NOP
|
||||
/* 0F 20 */ { BxAnother, &BX_CPU_C::MOV_RqCq },
|
||||
/* 0F 21 */ { BxAnother, &BX_CPU_C::MOV_RqDq },
|
||||
/* 0F 22 */ { BxAnother, &BX_CPU_C::MOV_CqRq },
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: flag_ctrl_pro.cc,v 1.23 2006-03-06 22:02:59 sshwarts Exp $
|
||||
// $Id: flag_ctrl_pro.cc,v 1.24 2006-04-05 17:31:31 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -36,14 +36,14 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::setEFlags(Bit32u val)
|
||||
// VM flag could not be set from long mode
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (IsLongMode()) {
|
||||
if (get_VM()) BX_PANIC(("VM is set in long mode !"));
|
||||
if (BX_CPU_THIS_PTR get_VM()) BX_PANIC(("VM is set in long mode !"));
|
||||
val &= ~EFlagsVMMask;
|
||||
}
|
||||
#endif
|
||||
|
||||
BX_CPU_THIS_PTR eflags.val32 = val;
|
||||
BX_CPU_THIS_PTR lf_flags_status = 0; // OSZAPC flags are known.
|
||||
set_VM(val & EFlagsVMMask);
|
||||
BX_CPU_THIS_PTR set_VM(val & EFlagsVMMask);
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(2)
|
||||
@ -66,7 +66,7 @@ BX_CPU_C::writeEFlags(Bit32u flags, Bit32u changeMask)
|
||||
|
||||
newEFlags = (BX_CPU_THIS_PTR eflags.val32 & ~changeMask) |
|
||||
(flags & changeMask);
|
||||
BX_CPU_THIS_PTR setEFlags(newEFlags);
|
||||
setEFlags(newEFlags);
|
||||
// OSZAPC flags are known - done in setEFlags(newEFlags)
|
||||
|
||||
if (newEFlags & EFlagsTFMask) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: init.cc,v 1.95 2006-03-27 18:02:07 sshwarts Exp $
|
||||
// $Id: init.cc,v 1.96 2006-04-05 17:31:31 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -619,6 +619,8 @@ void BX_CPU_C::reset(unsigned source)
|
||||
BX_CPU_THIS_PTR in_smm = 0;
|
||||
BX_CPU_THIS_PTR nmi_disable = 0;
|
||||
|
||||
BX_CPU_THIS_PTR smbase = 0x30000;
|
||||
|
||||
#if BX_CPU_LEVEL >= 2
|
||||
// MSW (Machine Status Word), so called on 286
|
||||
// CR0 (Control Register 0), so called on 386+
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: paging.cc,v 1.70 2006-03-28 16:53:02 sshwarts Exp $
|
||||
// $Id: paging.cc,v 1.71 2006-04-05 17:31:31 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -439,14 +439,14 @@ BX_CPU_C::pagingCR0Changed(Bit32u oldCR0, Bit32u newCR0)
|
||||
BX_CPU_C::pagingCR4Changed(Bit32u oldCR4, Bit32u newCR4)
|
||||
{
|
||||
// Modification of PGE,PAE,PSE flushes TLB cache according to docs.
|
||||
if ( (oldCR4 & 0x000000b0) != (newCR4 & 0x000000b0) )
|
||||
if ((oldCR4 & 0x000000b0) != (newCR4 & 0x000000b0))
|
||||
TLB_flush(1); // 1 = Flush Global entries also.
|
||||
|
||||
if (bx_dbg.paging)
|
||||
BX_INFO(("pagingCR4Changed: (0x%x -> 0x%x)", oldCR4, newCR4));
|
||||
|
||||
#if BX_SUPPORT_PAE
|
||||
if ( (oldCR4 & 0x00000020) != (newCR4 & 0x00000020) ) {
|
||||
if ((oldCR4 & 0x00000020) != (newCR4 & 0x00000020)) {
|
||||
if (BX_CPU_THIS_PTR cr4.get_PAE())
|
||||
BX_CPU_THIS_PTR cr3_masked = BX_CPU_THIS_PTR cr3 & 0xffffffe0;
|
||||
else
|
||||
@ -456,7 +456,7 @@ BX_CPU_C::pagingCR4Changed(Bit32u oldCR4, Bit32u newCR4)
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::CR3_change(bx_address value)
|
||||
BX_CPU_C::CR3_change(bx_phy_address value)
|
||||
{
|
||||
if (bx_dbg.paging) {
|
||||
BX_INFO(("CR3_change(): flush TLB cache"));
|
||||
@ -621,7 +621,8 @@ BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigned rw, unsigned
|
||||
|
||||
// note - we assume physical memory < 4gig so for brevity & speed, we'll use
|
||||
// 32 bit entries although cr3 is expanded to 64 bits.
|
||||
Bit32u ppf, poffset, paddress;
|
||||
Bit32u ppf, poffset;
|
||||
bx_phy_address paddress;
|
||||
|
||||
bx_bool isWrite = (rw >= BX_WRITE); // write or r-m-w
|
||||
|
||||
@ -629,8 +630,8 @@ BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigned rw, unsigned
|
||||
if (BX_CPU_THIS_PTR cr4.get_PAE())
|
||||
{
|
||||
bx_address pde, pdp;
|
||||
Bit32u pde_addr;
|
||||
Bit32u pdp_addr;
|
||||
bx_phy_address pde_addr;
|
||||
bx_phy_address pdp_addr;
|
||||
|
||||
lpf = laddr & BX_CONST64(0xfffffffffffff000); // linear page frame
|
||||
poffset = laddr & 0x00000fff; // physical offset
|
||||
@ -659,10 +660,10 @@ BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigned rw, unsigned
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR msr.lma)
|
||||
{
|
||||
bx_address pml4;
|
||||
Bit64u pml4;
|
||||
|
||||
// Get PML4 entry
|
||||
Bit32u pml4_addr = BX_CPU_THIS_PTR cr3_masked |
|
||||
bx_phy_address pml4_addr = BX_CPU_THIS_PTR cr3_masked |
|
||||
((laddr & BX_CONST64(0x0000ff8000000000)) >> 36);
|
||||
BX_CPU_THIS_PTR mem->readPhysicalPage(BX_CPU_THIS, pml4_addr, 8, &pml4);
|
||||
|
||||
@ -770,7 +771,7 @@ BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigned rw, unsigned
|
||||
bx_address pte;
|
||||
|
||||
// Get page table entry
|
||||
Bit32u pte_addr = (pde & 0xfffff000) | ((laddr & 0x001ff000) >> 9);
|
||||
bx_phy_address pte_addr = (pde & 0xfffff000) | ((laddr & 0x001ff000) >> 9);
|
||||
|
||||
BX_CPU_THIS_PTR mem->readPhysicalPage(BX_CPU_THIS, pte_addr, sizeof(bx_address), &pte);
|
||||
|
||||
@ -851,7 +852,8 @@ BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigned rw, unsigned
|
||||
|
||||
InstrTLB_Increment(tlbMisses);
|
||||
|
||||
Bit32u pde, pde_addr;
|
||||
Bit32u pde;
|
||||
bx_phy_address pde_addr;
|
||||
|
||||
// Get page dir entry
|
||||
pde_addr = BX_CPU_THIS_PTR cr3_masked | ((laddr & 0xffc00000) >> 20);
|
||||
@ -902,7 +904,7 @@ BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigned rw, unsigned
|
||||
else // Else normal 4Kbyte page...
|
||||
#endif
|
||||
{
|
||||
Bit32u pte, pte_addr;
|
||||
Bit32u pte;
|
||||
|
||||
#if (BX_CPU_LEVEL < 6)
|
||||
// update PDE if A bit was not set before
|
||||
@ -913,7 +915,7 @@ BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigned rw, unsigned
|
||||
#endif
|
||||
|
||||
// Get page table entry
|
||||
pte_addr = (pde & 0xfffff000) | ((laddr & 0x003ff000) >> 10);
|
||||
bx_phy_address pte_addr = (pde & 0xfffff000) | ((laddr & 0x003ff000) >> 10);
|
||||
|
||||
BX_CPU_THIS_PTR mem->readPhysicalPage(BX_CPU_THIS, pte_addr, 4, &pte);
|
||||
|
||||
@ -1431,7 +1433,7 @@ BX_CPU_C::access_linear(bx_address laddr, unsigned length, unsigned pl,
|
||||
|
||||
// stub functions for non-support of paging
|
||||
|
||||
void BX_CPU_C::CR3_change(bx_address value32)
|
||||
void BX_CPU_C::CR3_change(bx_phy_address value32)
|
||||
{
|
||||
BX_INFO(("CR3_change(): flush TLB cache"));
|
||||
BX_INFO(("Page Directory Base %08x", (unsigned) value32));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: proc_ctrl.cc,v 1.143 2006-03-27 18:02:07 sshwarts Exp $
|
||||
// $Id: proc_ctrl.cc,v 1.144 2006-04-05 17:31:32 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -59,6 +59,11 @@ void BX_CPU_C::PREFETCH(bxInstruction_c *i)
|
||||
#endif
|
||||
}
|
||||
|
||||
void BX_CPU_C::shutdown(void)
|
||||
{
|
||||
BX_PANIC(("Entering to shutdown state still not implemented"));
|
||||
}
|
||||
|
||||
void BX_CPU_C::HLT(bxInstruction_c *i)
|
||||
{
|
||||
// hack to panic if HLT comes from BIOS
|
||||
@ -1240,6 +1245,42 @@ void BX_CPU_C::LOADALL(bxInstruction_c *i)
|
||||
}
|
||||
#endif
|
||||
|
||||
void BX_CPU_C::handleCpuModeChange(void)
|
||||
{
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR msr.lma) {
|
||||
if (! BX_CPU_THIS_PTR cr0.pe) {
|
||||
BX_PANIC(("change_cpu_mode: EFER.LMA is set when CR0.PE=0 !"));
|
||||
}
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.l) {
|
||||
BX_CPU_THIS_PTR cpu_mode = BX_MODE_LONG_64;
|
||||
BX_DEBUG(("Long Mode Activated"));
|
||||
}
|
||||
else {
|
||||
BX_CPU_THIS_PTR cpu_mode = BX_MODE_LONG_COMPAT;
|
||||
BX_DEBUG(("Compatibility Mode Activated"));
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (BX_CPU_THIS_PTR cr0.pe) {
|
||||
if (BX_CPU_THIS_PTR get_VM()) {
|
||||
BX_CPU_THIS_PTR cpu_mode = BX_MODE_IA32_V8086;
|
||||
BX_DEBUG(("VM8086 Mode Activated"));
|
||||
}
|
||||
else {
|
||||
BX_CPU_THIS_PTR cpu_mode = BX_MODE_IA32_PROTECTED;
|
||||
BX_DEBUG(("Protected Mode Activated"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
BX_CPU_THIS_PTR cpu_mode = BX_MODE_IA32_REAL;
|
||||
BX_DEBUG(("Real Mode Activated"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BX_CPU_C::SetCR0(Bit32u val_32)
|
||||
{
|
||||
bx_bool pe = val_32 & 0x01;
|
||||
@ -1319,8 +1360,6 @@ void BX_CPU_C::SetCR0(Bit32u val_32)
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
BX_CPU_THIS_PTR msr.lma = 1;
|
||||
BX_DEBUG(("Enter Compatibility Mode"));
|
||||
BX_CPU_THIS_PTR cpu_mode = BX_MODE_LONG_COMPAT;
|
||||
}
|
||||
}
|
||||
else if (prev_pg==1 && BX_CPU_THIS_PTR cr0.pg==0) {
|
||||
@ -1329,18 +1368,12 @@ void BX_CPU_C::SetCR0(Bit32u val_32)
|
||||
BX_PANIC(("SetCR0: attempt to leave x86-64 LONG mode with RIP upper != 0 !!!"));
|
||||
}
|
||||
BX_CPU_THIS_PTR msr.lma = 0;
|
||||
if (BX_CPU_THIS_PTR cr0.pe) {
|
||||
BX_DEBUG(("Enter Protected Mode"));
|
||||
BX_CPU_THIS_PTR cpu_mode = BX_MODE_IA32_PROTECTED;
|
||||
}
|
||||
else {
|
||||
BX_DEBUG(("Enter Real Mode"));
|
||||
BX_CPU_THIS_PTR cpu_mode = BX_MODE_IA32_REAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // #if BX_SUPPORT_X86_64
|
||||
|
||||
handleCpuModeChange();
|
||||
|
||||
// Give the paging unit a chance to look for changes in bits
|
||||
// it cares about, like {PG,PE}, so it can flush cache entries etc.
|
||||
pagingCR0Changed(oldCR0, newCR0);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: segment_ctrl_pro.cc,v 1.57 2006-03-29 18:08:13 sshwarts Exp $
|
||||
// $Id: segment_ctrl_pro.cc,v 1.58 2006-04-05 17:31:32 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -317,7 +317,7 @@ BX_CPU_C::parse_selector(Bit16u raw_selector, bx_selector_t *selector)
|
||||
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
Bit16u BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::get_segment_ar_data(bx_descriptor_t *d)
|
||||
BX_CPU_C::get_segment_ar_data(bx_descriptor_t *d) // used for SMM
|
||||
{
|
||||
Bit16u val = 0;
|
||||
|
||||
@ -360,6 +360,85 @@ BX_CPU_C::get_segment_ar_data(bx_descriptor_t *d)
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
bx_bool BX_CPU_C::set_segment_ar_data(bx_segment_reg_t *seg,
|
||||
Bit16u raw_selector, bx_address base, Bit32u limit, Bit16u ar_data)
|
||||
{
|
||||
parse_selector(raw_selector, &seg->selector);
|
||||
|
||||
bx_descriptor_t *d = &seg->cache;
|
||||
|
||||
d->p = (ar_data >> 7) & 0x01;
|
||||
d->dpl = (ar_data >> 5) & 0x03;
|
||||
d->segment = (ar_data >> 4) & 0x01;
|
||||
d->type = (ar_data & 0x0f);
|
||||
|
||||
if (d->segment) { /* data/code segment descriptors */
|
||||
d->u.segment.executable = (ar_data >> 3) & 0x01;
|
||||
d->u.segment.c_ed = (ar_data >> 2) & 0x01;
|
||||
d->u.segment.r_w = (ar_data >> 1) & 0x01;
|
||||
d->u.segment.a = (ar_data >> 0) & 0x01;
|
||||
d->u.segment.g = (ar_data >> 15) & 0x01;
|
||||
d->u.segment.d_b = (ar_data >> 14) & 0x01;
|
||||
#if BX_SUPPORT_X86_64
|
||||
d->u.segment.l = (ar_data >> 13) & 0x01;
|
||||
#endif
|
||||
d->u.segment.avl = (ar_data >> 12) & 0x01;
|
||||
|
||||
d->u.segment.base = base;
|
||||
d->u.segment.limit = limit;
|
||||
|
||||
if (d->u.segment.g) {
|
||||
if ((d->u.segment.executable==0) && (d->u.segment.c_ed))
|
||||
d->u.segment.limit_scaled = (d->u.segment.limit << 12);
|
||||
else
|
||||
d->u.segment.limit_scaled = (d->u.segment.limit << 12) | 0x0fff;
|
||||
}
|
||||
else
|
||||
d->u.segment.limit_scaled = d->u.segment.limit;
|
||||
|
||||
d->valid = 1;
|
||||
}
|
||||
else {
|
||||
switch(d->type) {
|
||||
case BX_SYS_SEGMENT_LDT:
|
||||
d->valid = 1;
|
||||
d->u.ldt.base = base;
|
||||
d->u.ldt.limit = limit;
|
||||
break;
|
||||
|
||||
case BX_SYS_SEGMENT_AVAIL_286_TSS:
|
||||
case BX_SYS_SEGMENT_BUSY_286_TSS:
|
||||
d->valid = 1;
|
||||
d->u.tss286.base = base;
|
||||
d->u.tss286.limit = limit;
|
||||
break;
|
||||
|
||||
case BX_SYS_SEGMENT_AVAIL_386_TSS:
|
||||
case BX_SYS_SEGMENT_BUSY_386_TSS:
|
||||
d->valid = 1;
|
||||
d->u.tss386.avl = (ar_data >> 12) & 0x01;
|
||||
d->u.tss386.g = (ar_data >> 15) & 0x01;
|
||||
d->u.tss386.base = base;
|
||||
d->u.tss386.limit = limit;
|
||||
if (d->u.tss386.g)
|
||||
d->u.tss386.limit_scaled = (d->u.tss386.limit << 12) | 0x0fff;
|
||||
else
|
||||
d->u.tss386.limit_scaled = (d->u.tss386.limit);
|
||||
break;
|
||||
|
||||
default:
|
||||
BX_PANIC(("set_segment_ar_data(): case %u unsupported", (unsigned) d->type));
|
||||
}
|
||||
}
|
||||
|
||||
/* invalidate if null selector */
|
||||
if ((raw_selector & 0xfffc) == 0) {
|
||||
seg->cache.valid = 0;
|
||||
}
|
||||
|
||||
return seg->cache.valid;
|
||||
}
|
||||
#endif
|
||||
|
||||
void BX_CPP_AttrRegparmN(3)
|
||||
@ -531,8 +610,9 @@ BX_CPU_C::fetch_raw_descriptor(const bx_selector_t *selector,
|
||||
BX_CPU_THIS_PTR gdtr.limit));
|
||||
exception(exception_no, selector->value & 0xfffc, 0);
|
||||
}
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8, 4, 0, BX_READ, dword1);
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8+4, 4, 0, BX_READ, dword2);
|
||||
bx_address offset = BX_CPU_THIS_PTR gdtr.base + selector->index*8;
|
||||
access_linear(offset, 4, 0, BX_READ, dword1);
|
||||
access_linear(offset + 4, 4, 0, BX_READ, dword2);
|
||||
}
|
||||
else { /* LDT */
|
||||
if (BX_CPU_THIS_PTR ldtr.cache.valid==0) {
|
||||
@ -545,8 +625,9 @@ BX_CPU_C::fetch_raw_descriptor(const bx_selector_t *selector,
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit));
|
||||
exception(exception_no, selector->value & 0xfffc, 0);
|
||||
}
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8, 4, 0, BX_READ, dword1);
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8+4, 4, 0, BX_READ, dword2);
|
||||
bx_address offset = BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8;
|
||||
access_linear(offset, 4, 0, BX_READ, dword1);
|
||||
access_linear(offset + 4, 4, 0, BX_READ, dword2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -556,8 +637,9 @@ BX_CPU_C::fetch_raw_descriptor2(const bx_selector_t *selector, Bit32u *dword1, B
|
||||
if (selector->ti == 0) { /* GDT */
|
||||
if ((selector->index*8 + 7) > BX_CPU_THIS_PTR gdtr.limit)
|
||||
return(0);
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8, 4, 0, BX_READ, dword1);
|
||||
access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8+4, 4, 0, BX_READ, dword2);
|
||||
bx_address offset = BX_CPU_THIS_PTR gdtr.base + selector->index*8;
|
||||
access_linear(offset, 4, 0, BX_READ, dword1);
|
||||
access_linear(offset + 4, 4, 0, BX_READ, dword2);
|
||||
return(1);
|
||||
}
|
||||
else { /* LDT */
|
||||
@ -567,8 +649,9 @@ BX_CPU_C::fetch_raw_descriptor2(const bx_selector_t *selector, Bit32u *dword1, B
|
||||
}
|
||||
if ((selector->index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit)
|
||||
return(0);
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8, 4, 0, BX_READ, dword1);
|
||||
access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8+4, 4, 0, BX_READ, dword2);
|
||||
bx_address offset = BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8;
|
||||
access_linear(offset, 4, 0, BX_READ, dword1);
|
||||
access_linear(offset + 4, 4, 0, BX_READ, dword2);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
@ -586,11 +669,11 @@ void BX_CPU_C::fetch_raw_descriptor64(const bx_selector_t *selector,
|
||||
BX_CPU_THIS_PTR gdtr.limit));
|
||||
exception(exception_no, selector->value & 0xfffc, 0);
|
||||
}
|
||||
bx_address base = BX_CPU_THIS_PTR gdtr.base;
|
||||
access_linear(base + selector->index*8, 4, 0, BX_READ, dword1);
|
||||
access_linear(base + selector->index*8 + 4, 4, 0, BX_READ, dword2);
|
||||
access_linear(base + selector->index*8 + 8, 4, 0, BX_READ, dword3);
|
||||
access_linear(base + selector->index*8 + 12, 4, 0, BX_READ, &dword4);
|
||||
bx_address offset = BX_CPU_THIS_PTR gdtr.base + selector->index*8;
|
||||
access_linear(offset, 4, 0, BX_READ, dword1);
|
||||
access_linear(offset + 4, 4, 0, BX_READ, dword2);
|
||||
access_linear(offset + 8, 4, 0, BX_READ, dword3);
|
||||
access_linear(offset + 12, 4, 0, BX_READ, &dword4);
|
||||
}
|
||||
else { /* LDT */
|
||||
if (BX_CPU_THIS_PTR ldtr.cache.valid==0) {
|
||||
@ -603,11 +686,11 @@ void BX_CPU_C::fetch_raw_descriptor64(const bx_selector_t *selector,
|
||||
BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit));
|
||||
exception(exception_no, selector->value & 0xfffc, 0);
|
||||
}
|
||||
bx_address base = BX_CPU_THIS_PTR ldtr.cache.u.ldt.base;
|
||||
access_linear(base + selector->index*8, 4, 0, BX_READ, dword1);
|
||||
access_linear(base + selector->index*8 + 4, 4, 0, BX_READ, dword2);
|
||||
access_linear(base + selector->index*8 + 8, 4, 0, BX_READ, dword3);
|
||||
access_linear(base + selector->index*8 + 12, 4, 0, BX_READ, &dword4);
|
||||
bx_address offset = BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8;
|
||||
access_linear(offset, 4, 0, BX_READ, dword1);
|
||||
access_linear(offset + 4, 4, 0, BX_READ, dword2);
|
||||
access_linear(offset + 8, 4, 0, BX_READ, dword3);
|
||||
access_linear(offset + 12, 4, 0, BX_READ, &dword4);
|
||||
}
|
||||
|
||||
if (dword4 != 0) {
|
||||
|
729
bochs/cpu/smm.cc
729
bochs/cpu/smm.cc
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: smm.cc,v 1.12 2006-03-29 19:16:24 sshwarts Exp $
|
||||
// $Id: smm.cc,v 1.13 2006-04-05 17:31:32 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2006 Stanislav Shwartsman
|
||||
@ -24,6 +24,7 @@
|
||||
#define NEED_CPU_REG_SHORTCUTS 1
|
||||
#include "bochs.h"
|
||||
#include "cpu.h"
|
||||
#include "smm.h"
|
||||
#define LOG_THIS BX_CPU_THIS_PTR
|
||||
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
@ -61,7 +62,7 @@
|
||||
// 5. LDTR, TR
|
||||
// fields: base, limit, something more ?
|
||||
// 6. Debug Registers DR0-DR7, only DR6 and DR7 are saved
|
||||
// 7. Control Regsiters: CR0, CR1 is always 0, CR2 is NOT saved, CR3, CR4
|
||||
// 7. Control Regsiters: CR0, CR1 is always 0, CR2 is NOT saved, CR3, CR4, EFER
|
||||
// 8. SMBASE
|
||||
// 9. MSR/FPU/XMM/APIC are NOT saved accoring to Intel docs
|
||||
//
|
||||
@ -77,13 +78,13 @@ void BX_CPU_C::RSM(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INFO(("RSM: System Management Mode not implemented yet"));
|
||||
|
||||
UndefinedOpcode(i); // remove later, when SMM become stable
|
||||
BX_INFO(("RSM: Resuming from System Management Mode !"));
|
||||
|
||||
BX_CPU_THIS_PTR nmi_disable = 0;
|
||||
BX_CPU_THIS_PTR in_smm = 0;
|
||||
|
||||
Bit32u saved_state[SMM_SAVE_STATE_MAP_SIZE], n;
|
||||
|
||||
// reset reserved bits
|
||||
for(n=0;n<SMM_SAVE_STATE_MAP_SIZE;n++) saved_state[n] = 0;
|
||||
|
||||
@ -97,21 +98,25 @@ void BX_CPU_C::RSM(bxInstruction_c *i)
|
||||
// restore the CPU state from SMRAM
|
||||
if (! smram_restore_state(saved_state)) {
|
||||
BX_PANIC(("RSM: Incorrect state when restoring CPU state - shutdown !"));
|
||||
shutdown();
|
||||
}
|
||||
|
||||
BX_CPU_THIS_PTR nmi_disable = 0;
|
||||
BX_CPU_THIS_PTR in_smm = 0;
|
||||
debug(RIP);
|
||||
}
|
||||
|
||||
void BX_CPU_C::enter_system_management_mode(void)
|
||||
{
|
||||
invalidate_prefetch_q();
|
||||
|
||||
Bit32u saved_state[SMM_SAVE_STATE_MAP_SIZE], n;
|
||||
debug(BX_CPU_THIS_PTR prev_eip);
|
||||
|
||||
BX_INFO(("Enter to System Management Mode !"));
|
||||
|
||||
BX_CPU_THIS_PTR in_smm = 1;
|
||||
|
||||
Bit32u saved_state[SMM_SAVE_STATE_MAP_SIZE], n;
|
||||
// reset reserved bits
|
||||
for(n=0;n<SMM_SAVE_STATE_MAP_SIZE;n++) saved_state[n] = 0;
|
||||
|
||||
// prepare CPU state to be saved in the SMRAM
|
||||
BX_CPU_THIS_PTR smram_save_state(saved_state);
|
||||
|
||||
@ -123,7 +128,7 @@ void BX_CPU_C::enter_system_management_mode(void)
|
||||
}
|
||||
|
||||
BX_CPU_THIS_PTR setEFlags(0x2); // Bit1 is always set
|
||||
BX_CPU_THIS_PTR prev_eip = RIP = 0x000080000;
|
||||
BX_CPU_THIS_PTR prev_eip = RIP = 0x00008000;
|
||||
BX_CPU_THIS_PTR dr7 = 0x00000400;
|
||||
|
||||
// CR0 - PE, EM, TS, and PG flags set to 0; others unmodified
|
||||
@ -148,7 +153,7 @@ void BX_CPU_C::enter_system_management_mode(void)
|
||||
BX_CPU_THIS_PTR msr.lma = 0;
|
||||
#endif
|
||||
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = BX_CPU_THIS_PTR smbase << 4;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = BX_CPU_THIS_PTR smbase >> 4;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = 0;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti = 0;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = 0;
|
||||
@ -166,7 +171,7 @@ void BX_CPU_C::enter_system_management_mode(void)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = 0xffff;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xffffffff;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g = 0; /* byte granular */
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g = 1; /* page granular */
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 0; /* 16bit default size */
|
||||
#if BX_SUPPORT_X86_64
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.l = 0; /* 16bit default size */
|
||||
@ -195,7 +200,7 @@ void BX_CPU_C::enter_system_management_mode(void)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit = 0xffff;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled = 0xffffffff;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.avl = 0;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g = 0; /* byte granular */
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g = 1; /* byte granular */
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b = 0; /* 16bit default size */
|
||||
#if BX_SUPPORT_X86_64
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.l = 0; /* 16bit default size */
|
||||
@ -208,284 +213,636 @@ void BX_CPU_C::enter_system_management_mode(void)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS] = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS];
|
||||
}
|
||||
|
||||
#define SMRAM_TRANSLATE(addr) (((0x8000 - (addr)) >> 2) - 1)
|
||||
#define SMM_SAVED_STATE(state, addr) (state[SMRAM_TRANSLATE(addr)])
|
||||
#define SMRAM_TRANSLATE(addr) (((0x8000 - (addr)) >> 2) - 1)
|
||||
#define SMRAM_FIELD(state, addr) (state[SMRAM_TRANSLATE(addr)])
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
|
||||
// for x86-64 configuration using AMD Athlon 64 512-byte SMM save state map
|
||||
#define SMM_REVISION_ID 0x00000000
|
||||
|
||||
void BX_CPU_C::smram_save_state(Bit32u *saved_state)
|
||||
{
|
||||
// --- General Purpose Registers --- //
|
||||
SMM_SAVED_STATE(saved_state, 0x7ffc) = RAX >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7ff8) = RAX & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7ff4) = RCX >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7ff0) = RCX & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fec) = RDX >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fe8) = RDX & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fe4) = RBX >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fe0) = RBX & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fdc) = RSP >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fd8) = RSP & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fd4) = RBP >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fd0) = RBP & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fcc) = RSI >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fc8) = RSI & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fc4) = RDI >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fc0) = RDI & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fbc) = R8 >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fb8) = R8 & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fb4) = R9 >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fb0) = R9 & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fac) = R10 >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fa8) = R10 & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fa4) = R11 >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fa0) = R11 & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f9c) = R12 >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f98) = R12 & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f94) = R13 >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f90) = R13 & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f8c) = R14 >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f88) = R14 & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f84) = R15 >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f80) = R15 & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f7c) = RIP >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f78) = RIP & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f70) = read_eflags();
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RAX_HI32) = RAX >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RAX_LO32) = RAX & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RCX_HI32) = RCX >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RCX_LO32) = RCX & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RDX_HI32) = RDX >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RDX_LO32) = RDX & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RBX_HI32) = RBX >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RBX_LO32) = RBX & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RSP_HI32) = RSP >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RSP_LO32) = RSP & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RBP_HI32) = RBP >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RBP_LO32) = RBP & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RSI_HI32) = RSI >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RSI_LO32) = RSI & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RDI_HI32) = RDI >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RDI_LO32) = RDI & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R8_HI32) = R8 >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R8_LO32) = R8 & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R9_HI32) = R9 >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R9_LO32) = R9 & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R10_HI32) = R10 >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R10_LO32) = R10 & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R11_HI32) = R11 >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R11_LO32) = R11 & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R12_HI32) = R12 >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R12_LO32) = R12 & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R13_HI32) = R13 >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R13_LO32) = R13 & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R14_HI32) = R14 >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R14_LO32) = R14 & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R15_HI32) = R15 >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R15_LO32) = R15 & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RIP_HI32) = RIP >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RIP_LO32) = RIP & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RFLAGS32) = read_eflags();
|
||||
|
||||
// --- Debug and Control Registers --- //
|
||||
SMM_SAVED_STATE(saved_state, 0x7f68) = BX_CPU_THIS_PTR dr6;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f60) = BX_CPU_THIS_PTR dr7;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f58) = BX_CPU_THIS_PTR cr0.val32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f54) = BX_CPU_THIS_PTR cr3 >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f50) = BX_CPU_THIS_PTR cr3 & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f48) = BX_CPU_THIS_PTR cr4.getRegister();
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR6) = BX_CPU_THIS_PTR dr6;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR7) = BX_CPU_THIS_PTR dr7;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR0) = BX_CPU_THIS_PTR cr0.val32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR3) = BX_CPU_THIS_PTR cr3;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR4) = BX_CPU_THIS_PTR cr4.getRegister();
|
||||
/* base+0x7f44 to base+0x7f04 is reserved */
|
||||
SMM_SAVED_STATE(saved_state, 0x7f00) = BX_CPU_THIS_PTR smbase;
|
||||
SMM_SAVED_STATE(saved_state, 0x7efc) = SMM_REVISION_ID;
|
||||
SMRAM_FIELD(saved_state, SMRAM_SMBASE_OFFSET) = BX_CPU_THIS_PTR smbase;
|
||||
SMRAM_FIELD(saved_state, SMRAM_SMM_REVISION_ID) = SMM_REVISION_ID;
|
||||
/* base+0x7ef8 to base+0x7ed8 is reserved */
|
||||
SMM_SAVED_STATE(saved_state, 0x7ed0) = BX_CPU_THIS_PTR get_EFER();
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EFER) = BX_CPU_THIS_PTR get_EFER();
|
||||
/* base+0x7ecc is reserved */
|
||||
/* base+0x7ec8 is I/O Instruction Restart, Auto-Halt Restart and NMI Mask */
|
||||
/* base+0x7ec4 is reserved */
|
||||
/* base+0x7ec0 is SMM I/O Trap */
|
||||
/* base+0x7ebc to base+0x7ea4 is reserved */
|
||||
/* base+0x7ebc to base+0x7ea0 is reserved */
|
||||
|
||||
// --- Task Register --- //
|
||||
if (BX_CPU_THIS_PTR tr.cache.type <= 3) {
|
||||
SMM_SAVED_STATE(saved_state, 0x7e98) = BX_CPU_THIS_PTR tr.cache.u.tss286.base;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e94) = BX_CPU_THIS_PTR tr.cache.u.tss286.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_BASE_LO32) = BX_CPU_THIS_PTR tr.cache.u.tss286.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_LIMIT) = BX_CPU_THIS_PTR tr.cache.u.tss286.limit;
|
||||
} else {
|
||||
SMM_SAVED_STATE(saved_state, 0x7e9c) = BX_CPU_THIS_PTR tr.cache.u.tss386.base >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e98) = BX_CPU_THIS_PTR tr.cache.u.tss386.base & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e94) = BX_CPU_THIS_PTR tr.cache.u.tss386.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_BASE_HI32) = BX_CPU_THIS_PTR tr.cache.u.tss386.base >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_BASE_LO32) = BX_CPU_THIS_PTR tr.cache.u.tss386.base & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_LIMIT) = BX_CPU_THIS_PTR tr.cache.u.tss386.limit;
|
||||
}
|
||||
SMM_SAVED_STATE(saved_state, 0x7e90) = BX_CPU_THIS_PTR tr.selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) = BX_CPU_THIS_PTR tr.selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&BX_CPU_THIS_PTR tr.cache)) << 16);
|
||||
|
||||
// --- IDTR --- //
|
||||
SMM_SAVED_STATE(saved_state, 0x7e8c) = BX_CPU_THIS_PTR idtr.base >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e88) = BX_CPU_THIS_PTR idtr.base & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e84) = BX_CPU_THIS_PTR idtr.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_IDTR_BASE_HI32) = BX_CPU_THIS_PTR idtr.base >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_IDTR_BASE_LO32) = BX_CPU_THIS_PTR idtr.base & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_IDTR_LIMIT) = BX_CPU_THIS_PTR idtr.limit;
|
||||
// --- LDTR --- //
|
||||
SMM_SAVED_STATE(saved_state, 0x7e7c) = BX_CPU_THIS_PTR ldtr.cache.u.ldt.base >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e78) = BX_CPU_THIS_PTR ldtr.cache.u.ldt.base & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e74) = BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e70) = BX_CPU_THIS_PTR ldtr.selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_BASE_HI32) = BX_CPU_THIS_PTR ldtr.cache.u.ldt.base >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_BASE_LO32) = BX_CPU_THIS_PTR ldtr.cache.u.ldt.base & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_LIMIT) = BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) = BX_CPU_THIS_PTR ldtr.selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&BX_CPU_THIS_PTR ldtr.cache)) << 16);
|
||||
// --- GDTR --- //
|
||||
SMM_SAVED_STATE(saved_state, 0x7e6c) = BX_CPU_THIS_PTR gdtr.base >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e68) = BX_CPU_THIS_PTR gdtr.base & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e64) = BX_CPU_THIS_PTR gdtr.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_GDTR_BASE_HI32) = BX_CPU_THIS_PTR gdtr.base >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_GDTR_BASE_LO32) = BX_CPU_THIS_PTR gdtr.base & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_GDTR_LIMIT) = BX_CPU_THIS_PTR gdtr.limit;
|
||||
// --- GS selector --- //
|
||||
bx_segment_reg_t *seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS]);
|
||||
SMM_SAVED_STATE(saved_state, 0x7e5c) = seg->cache.u.segment.base >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e58) = seg->cache.u.segment.base & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e54) = seg->cache.u.segment.limit;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e50) = seg->selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_BASE_HI32) = seg->cache.u.segment.base >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_BASE_LO32) = seg->cache.u.segment.base & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_LIMIT) = seg->cache.u.segment.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) = seg->selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
|
||||
// --- FS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS]);
|
||||
SMM_SAVED_STATE(saved_state, 0x7e4c) = seg->cache.u.segment.base >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e48) = seg->cache.u.segment.base & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e44) = seg->cache.u.segment.limit;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e40) = seg->selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_BASE_HI32) = seg->cache.u.segment.base >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_BASE_LO32) = seg->cache.u.segment.base & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_LIMIT) = seg->cache.u.segment.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) = seg->selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
|
||||
// --- DS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS]);
|
||||
SMM_SAVED_STATE(saved_state, 0x7e3c) = seg->cache.u.segment.base >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e38) = seg->cache.u.segment.base & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e34) = seg->cache.u.segment.limit;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e30) = seg->selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_BASE_HI32) = seg->cache.u.segment.base >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_BASE_LO32) = seg->cache.u.segment.base & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_LIMIT) = seg->cache.u.segment.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) = seg->selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
|
||||
// --- SS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS]);
|
||||
SMM_SAVED_STATE(saved_state, 0x7e2c) = seg->cache.u.segment.base >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e28) = seg->cache.u.segment.base & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e24) = seg->cache.u.segment.limit;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e20) = seg->selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_BASE_HI32) = seg->cache.u.segment.base >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_BASE_LO32) = seg->cache.u.segment.base & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_LIMIT) = seg->cache.u.segment.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) = seg->selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
|
||||
// --- CS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS]);
|
||||
SMM_SAVED_STATE(saved_state, 0x7e1c) = seg->cache.u.segment.base >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e18) = seg->cache.u.segment.base & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e14) = seg->cache.u.segment.limit;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e10) = seg->selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_BASE_HI32) = seg->cache.u.segment.base >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_BASE_LO32) = seg->cache.u.segment.base & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_LIMIT) = seg->cache.u.segment.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) = seg->selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
|
||||
// --- ES selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES]);
|
||||
SMM_SAVED_STATE(saved_state, 0x7e0c) = seg->cache.u.segment.base >> 32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e08) = seg->cache.u.segment.base & 0xffffffff;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e04) = seg->cache.u.segment.limit;
|
||||
SMM_SAVED_STATE(saved_state, 0x7e00) = seg->selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_BASE_HI32) = seg->cache.u.segment.base >> 32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_BASE_LO32) = seg->cache.u.segment.base & 0xffffffff;
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_LIMIT) = seg->cache.u.segment.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) = seg->selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
|
||||
}
|
||||
|
||||
#define SMRAM_FIELD64(state, addr) ((Bit64u) state[SMRAM_TRANSLATE(addr)])
|
||||
|
||||
bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
{
|
||||
Bit32u temp_cr0 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR0);
|
||||
Bit32u temp_eflags = SMRAM_FIELD(saved_state, SMRAM_OFFSET_RFLAGS32);
|
||||
Bit32u temp_efer = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EFER);
|
||||
|
||||
bx_bool pe = (temp_cr0 & 0x01);
|
||||
bx_bool nw = (temp_cr0 >> 29) & 0x01;
|
||||
bx_bool cd = (temp_cr0 >> 30) & 0x01;
|
||||
bx_bool pg = (temp_cr0 >> 31) & 0x01;
|
||||
|
||||
// check CR0 conditions for entering to shutdown state
|
||||
if (pg && !pe) {
|
||||
BX_PANIC(("SMM restore: attempt to set CR0.PG with CR0.PE cleared !"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nw && !cd) {
|
||||
BX_PANIC(("SMM restore: attempt to set CR0.NW with CR0.CD cleared !"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// shutdown if write to reserved CR4 bits
|
||||
if (! SetCR4(SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR4))) {
|
||||
BX_PANIC(("SMM restore: incorrect CR4 state !"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
BX_CPU_THIS_PTR msr.sce = (temp_efer >> 0) & 1;
|
||||
BX_CPU_THIS_PTR msr.lme = (temp_efer >> 8) & 1;
|
||||
BX_CPU_THIS_PTR msr.lma = (temp_efer >> 10) & 1;
|
||||
BX_CPU_THIS_PTR msr.nxe = (temp_efer >> 11) & 1;
|
||||
BX_CPU_THIS_PTR msr.ffxsr = (temp_efer >> 14) & 1;
|
||||
|
||||
if (BX_CPU_THIS_PTR msr.lma) {
|
||||
if (temp_eflags & EFlagsVMMask) {
|
||||
BX_PANIC(("SMM restore: If EFER.LMA = 1 => RFLAGS.VM=0 !"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!BX_CPU_THIS_PTR cr4.get_PAE() || !pg || !pe || !BX_CPU_THIS_PTR msr.lme) {
|
||||
BX_PANIC(("SMM restore: If EFER.LMA = 1 <=> CR4.PAE, CR0.PG, CR0.PE, EFER.LME=1 !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR cr4.get_PAE() && pg && pe && BX_CPU_THIS_PTR msr.lme) {
|
||||
if (! BX_CPU_THIS_PTR msr.lma) {
|
||||
BX_PANIC(("SMM restore: If EFER.LMA = 1 <=> CR4.PAE, CR0.PG, CR0.PE, EFER.LME=1 !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// hack CR0 to be able to back to long mode correctly
|
||||
BX_CPU_THIS_PTR cr0.pe = 0; // real mode (bit 0)
|
||||
BX_CPU_THIS_PTR cr0.pg = 0; // paging disabled (bit 31)
|
||||
BX_CPU_THIS_PTR cr0.val32 &= 0x7ffffffe;
|
||||
SetCR0(temp_cr0);
|
||||
setEFlags(temp_eflags);
|
||||
|
||||
bx_address temp_cr3 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RAX_HI32) << 32;
|
||||
temp_cr3 |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RAX_LO32);
|
||||
CR3_change(temp_cr3);
|
||||
|
||||
RAX = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RAX_HI32) << 32;
|
||||
RAX |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RAX_LO32);
|
||||
RBX = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RBX_HI32) << 32;
|
||||
RBX |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RBX_LO32);
|
||||
RCX = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RCX_HI32) << 32;
|
||||
RCX |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RCX_LO32);
|
||||
RDX = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RDX_HI32) << 32;
|
||||
RDX |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RDX_LO32);
|
||||
RSP = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RSP_HI32) << 32;
|
||||
RSP |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RSP_LO32);
|
||||
RBP = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RBP_HI32) << 32;
|
||||
RBP |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RBP_LO32);
|
||||
RSI = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RSI_HI32) << 32;
|
||||
RSI |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RSI_LO32);
|
||||
RDI = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RDI_HI32) << 32;
|
||||
RDI |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RDI_LO32);
|
||||
R8 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R8_HI32) << 32;
|
||||
R8 |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R8_LO32);
|
||||
R9 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R9_HI32) << 32;
|
||||
R9 |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R9_LO32);
|
||||
R10 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R10_HI32) << 32;
|
||||
R10 |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R10_LO32);
|
||||
R11 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R11_HI32) << 32;
|
||||
R11 |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R11_LO32);
|
||||
R12 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R12_HI32) << 32;
|
||||
R12 |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R12_LO32);
|
||||
R13 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R13_HI32) << 32;
|
||||
R13 |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R13_LO32);
|
||||
R14 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R14_HI32) << 32;
|
||||
R14 |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R14_LO32);
|
||||
R15 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R15_HI32) << 32;
|
||||
R15 |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R15_LO32);
|
||||
RIP = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RIP_HI32) << 32;
|
||||
RIP |= SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RIP_LO32);
|
||||
|
||||
BX_CPU_THIS_PTR dr6 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR6);
|
||||
BX_CPU_THIS_PTR dr7 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR7);
|
||||
|
||||
BX_CPU_THIS_PTR gdtr.base = SMRAM_FIELD64(saved_state, SMRAM_GDTR_BASE_HI32) << 32;
|
||||
BX_CPU_THIS_PTR gdtr.base |= SMRAM_FIELD64(saved_state, SMRAM_GDTR_BASE_LO32);
|
||||
BX_CPU_THIS_PTR gdtr.limit = SMRAM_FIELD(saved_state, SMRAM_GDTR_LIMIT);
|
||||
|
||||
BX_CPU_THIS_PTR idtr.base = SMRAM_FIELD64(saved_state, SMRAM_IDTR_BASE_HI32) << 32;
|
||||
BX_CPU_THIS_PTR idtr.base |= SMRAM_FIELD64(saved_state, SMRAM_IDTR_BASE_LO32);
|
||||
BX_CPU_THIS_PTR idtr.limit = SMRAM_FIELD(saved_state, SMRAM_IDTR_LIMIT);
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS],
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_CS_BASE_LO32) |
|
||||
SMRAM_FIELD64(saved_state, SMRAM_CS_BASE_HI32) << 32,
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment CS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
handleCpuModeChange();
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS],
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_DS_BASE_LO32) |
|
||||
SMRAM_FIELD64(saved_state, SMRAM_DS_BASE_HI32) << 32,
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment DS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS],
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_SS_BASE_LO32) |
|
||||
SMRAM_FIELD64(saved_state, SMRAM_SS_BASE_HI32) << 32,
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment SS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES],
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_ES_BASE_LO32) |
|
||||
SMRAM_FIELD64(saved_state, SMRAM_ES_BASE_HI32) << 32,
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment ES !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS],
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_FS_BASE_LO32) |
|
||||
SMRAM_FIELD64(saved_state, SMRAM_FS_BASE_HI32) << 32,
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment FS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS],
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_GS_BASE_LO32) |
|
||||
SMRAM_FIELD64(saved_state, SMRAM_GS_BASE_HI32) << 32,
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment GS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR ldtr,
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_LDTR_BASE_HI32) |
|
||||
SMRAM_FIELD64(saved_state, SMRAM_LDTR_BASE_LO32) << 32,
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (BX_CPU_THIS_PTR ldtr.cache.type != BX_SYS_SEGMENT_LDT) {
|
||||
BX_PANIC(("SMM restore: LDTR is not LDT descriptor type !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR tr,
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_TR_BASE_HI32) |
|
||||
SMRAM_FIELD64(saved_state, SMRAM_TR_BASE_LO32) << 32,
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_AVAIL_286_TSS &&
|
||||
BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_BUSY_286_TSS &&
|
||||
BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_AVAIL_386_TSS &&
|
||||
BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_BUSY_386_TSS)
|
||||
{
|
||||
BX_PANIC(("SMM restore: TR is not TSS descriptor type !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
|
||||
BX_CPU_THIS_PTR smbase = SMRAM_FIELD(saved_state, SMRAM_SMBASE_OFFSET);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else /* BX_SUPPORT_X86_64 == 0 */
|
||||
|
||||
// for IA32 configuration using Intel P6 512-byte SMM save state map
|
||||
#define SMM_REVISION_ID 0x00000000
|
||||
|
||||
// source for Intel P6 SMM save state map used: www.sandpile.org
|
||||
|
||||
void BX_CPU_C::smram_save_state(Bit32u *saved_state)
|
||||
{
|
||||
SMM_SAVED_STATE(saved_state, 0x7ffc) = BX_CPU_THIS_PTR cr0.val32;
|
||||
SMM_SAVED_STATE(saved_state, 0x7ff8) = BX_CPU_THIS_PTR cr3;
|
||||
SMM_SAVED_STATE(saved_state, 0x7ff4) = read_eflags();
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR0) = BX_CPU_THIS_PTR cr0.val32;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR3) = BX_CPU_THIS_PTR cr3;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EFLAGS) = read_eflags();
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EIP) = EIP;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EDI) = EDI;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_ESI) = ESI;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EBP) = EBP;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_ESP) = ESP;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EBX) = EBX;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EDX) = EDX;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_ECX) = ECX;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EAX) = EAX;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR6) = BX_CPU_THIS_PTR dr6;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR7) = BX_CPU_THIS_PTR dr7;
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR) = BX_CPU_THIS_PTR tr.selector.value;
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR) = BX_CPU_THIS_PTR ldtr.selector.value;
|
||||
|
||||
SMM_SAVED_STATE(saved_state, 0x7ff0) = EIP;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fec) = EDI;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fe8) = ESI;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fe4) = EBP;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fe0) = ESP;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fdc) = EBX;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fd8) = EDX;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fd4) = ECX;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fd0) = EAX;
|
||||
|
||||
SMM_SAVED_STATE(saved_state, 0x7fcc) = BX_CPU_THIS_PTR dr6;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fc8) = BX_CPU_THIS_PTR dr7;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fc4) = BX_CPU_THIS_PTR tr.selector.value;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fc0) = BX_CPU_THIS_PTR ldtr.selector.value;
|
||||
|
||||
SMM_SAVED_STATE(saved_state, 0x7fbc) =
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR) =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fb8) =
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR) =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fb4) =
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR) =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fb0) =
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR) =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fac) =
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR) =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fa8) =
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR) =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value;
|
||||
|
||||
// --- SS selector --- //
|
||||
bx_segment_reg_t *seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS]);
|
||||
SMM_SAVED_STATE(saved_state, 0x7fa4) = seg->cache.u.segment.base;
|
||||
SMM_SAVED_STATE(saved_state, 0x7fa0) = seg->cache.u.segment.limit;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f9c) = seg->selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_BASE) = seg->cache.u.segment.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_LIMIT) = seg->cache.u.segment.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) = seg->selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
|
||||
// --- CS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS]);
|
||||
SMM_SAVED_STATE(saved_state, 0x7f98) = seg->cache.u.segment.base;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f94) = seg->cache.u.segment.limit;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f90) = seg->selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_BASE) = seg->cache.u.segment.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_LIMIT) = seg->cache.u.segment.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) = seg->selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
|
||||
// --- ES selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES]);
|
||||
SMM_SAVED_STATE(saved_state, 0x7f8c) = seg->cache.u.segment.base;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f88) = seg->cache.u.segment.limit;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f84) = seg->selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_BASE) = seg->cache.u.segment.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_LIMIT) = seg->cache.u.segment.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) = seg->selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
|
||||
// --- LDTR --- //
|
||||
SMM_SAVED_STATE(saved_state, 0x7f80) = BX_CPU_THIS_PTR ldtr.cache.u.ldt.base;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f7c) = BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f78) = BX_CPU_THIS_PTR ldtr.selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_BASE) = BX_CPU_THIS_PTR ldtr.cache.u.ldt.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_LIMIT) = BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) = BX_CPU_THIS_PTR ldtr.selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&BX_CPU_THIS_PTR ldtr.cache)) << 16);
|
||||
// --- GDTR --- //
|
||||
SMM_SAVED_STATE(saved_state, 0x7f74) = BX_CPU_THIS_PTR gdtr.base;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f70) = BX_CPU_THIS_PTR gdtr.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_GDTR_BASE) = BX_CPU_THIS_PTR gdtr.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_GDTR_LIMIT) = BX_CPU_THIS_PTR gdtr.limit;
|
||||
/* base+0x7f6c is reserved */
|
||||
/* base+0x7f68 is reserved */
|
||||
|
||||
// --- Task Register --- //
|
||||
if (BX_CPU_THIS_PTR tr.cache.type <= 3) {
|
||||
SMM_SAVED_STATE(saved_state, 0x7f64) = BX_CPU_THIS_PTR tr.cache.u.tss286.base;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f60) = BX_CPU_THIS_PTR tr.cache.u.tss286.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_BASE) = BX_CPU_THIS_PTR tr.cache.u.tss286.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_LIMIT) = BX_CPU_THIS_PTR tr.cache.u.tss286.limit;
|
||||
} else {
|
||||
SMM_SAVED_STATE(saved_state, 0x7f64) = BX_CPU_THIS_PTR tr.cache.u.tss386.base;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f60) = BX_CPU_THIS_PTR tr.cache.u.tss386.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_BASE) = BX_CPU_THIS_PTR tr.cache.u.tss386.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_LIMIT) = BX_CPU_THIS_PTR tr.cache.u.tss386.limit;
|
||||
}
|
||||
SMM_SAVED_STATE(saved_state, 0x7f5c) = BX_CPU_THIS_PTR tr.selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) = BX_CPU_THIS_PTR tr.selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&BX_CPU_THIS_PTR tr.cache)) << 16);
|
||||
|
||||
// --- IDTR --- //
|
||||
SMM_SAVED_STATE(saved_state, 0x7f58) = BX_CPU_THIS_PTR idtr.base;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f54) = BX_CPU_THIS_PTR idtr.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_IDTR_BASE) = BX_CPU_THIS_PTR idtr.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_IDTR_LIMIT) = BX_CPU_THIS_PTR idtr.limit;
|
||||
/* base+0x7f50 is reserved */
|
||||
// --- GS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS]);
|
||||
SMM_SAVED_STATE(saved_state, 0x7f4c) = seg->cache.u.segment.base;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f48) = seg->cache.u.segment.limit;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f44) = seg->selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_BASE) = seg->cache.u.segment.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_LIMIT) = seg->cache.u.segment.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) = seg->selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
|
||||
// --- FS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS]);
|
||||
SMM_SAVED_STATE(saved_state, 0x7f40) = seg->cache.u.segment.base;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f3c) = seg->cache.u.segment.limit;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f38) = seg->selector.value |
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_BASE) = seg->cache.u.segment.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_LIMIT) = seg->cache.u.segment.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) = seg->selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
|
||||
// --- DS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS]);
|
||||
SMM_SAVED_STATE(saved_state, 0x7f34) = seg->cache.u.segment.base;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f30) = seg->cache.u.segment.limit;
|
||||
SMM_SAVED_STATE(saved_state, 0x7f2c) = seg->selector.value |
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_BASE) = seg->cache.u.segment.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_LIMIT) = seg->cache.u.segment.limit;
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) = seg->selector.value |
|
||||
(((Bit32u) get_segment_ar_data(&seg->cache)) << 16);
|
||||
|
||||
/* base+0x7f28 to base+7f18 is reserved */
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
SMM_SAVED_STATE(saved_state, 0x7f14) = BX_CPU_THIS_PTR cr4.getRegister();
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR4) = BX_CPU_THIS_PTR cr4.getRegister();
|
||||
#endif
|
||||
/* base+0x7f10 is I/O restart EIP */
|
||||
/* base+0x7f0c is I/O restart ESI */
|
||||
/* base+0x7f08 is I/O restart ECX */
|
||||
/* base+0x7f04 is I/O restart EDI */
|
||||
|
||||
/* base+0x7f02 is Auto HALT restart field (2 byte) */
|
||||
/* base+0x7f00 is I/O restart field (2 byte) */
|
||||
SMM_SAVED_STATE(saved_state, 0x7efc) = SMM_REVISION_ID;
|
||||
SMM_SAVED_STATE(saved_state, 0x7ef8) = BX_CPU_THIS_PTR smbase;
|
||||
SMRAM_FIELD(saved_state, SMRAM_SMM_REVISION_ID) = SMM_REVISION_ID;
|
||||
SMRAM_FIELD(saved_state, SMRAM_SMBASE_OFFSET) = BX_CPU_THIS_PTR smbase;
|
||||
/* base+0x7ef4 to base+0x7e00 is reserved */
|
||||
}
|
||||
|
||||
bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
{
|
||||
SetCR0(SMM_SAVED_STATE(saved_state, 0x7ffc));
|
||||
CR3_change(SMM_SAVED_STATE(saved_state, 0x7ff8));
|
||||
BX_CPU_THIS_PTR setEFlags(SMM_SAVED_STATE(saved_state, 0x7ff4));
|
||||
Bit32u temp_cr0 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR0);
|
||||
Bit32u temp_eflags = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EFLAGS);
|
||||
Bit32u temp_cr3 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR3);
|
||||
|
||||
EIP = SMM_SAVED_STATE(saved_state, 0x7ff0);
|
||||
EIP = SMM_SAVED_STATE(saved_state, 0x7ff0);
|
||||
EDI = SMM_SAVED_STATE(saved_state, 0x7fec);
|
||||
ESI = SMM_SAVED_STATE(saved_state, 0x7fe8);
|
||||
EBP = SMM_SAVED_STATE(saved_state, 0x7fe4);
|
||||
ESP = SMM_SAVED_STATE(saved_state, 0x7fe0);
|
||||
EBX = SMM_SAVED_STATE(saved_state, 0x7fdc);
|
||||
EDX = SMM_SAVED_STATE(saved_state, 0x7fd8);
|
||||
ECX = SMM_SAVED_STATE(saved_state, 0x7fd4);
|
||||
EAX = SMM_SAVED_STATE(saved_state, 0x7fd0);
|
||||
bx_bool pe = (temp_cr0 & 0x01);
|
||||
bx_bool nw = (temp_cr0 >> 29) & 0x01;
|
||||
bx_bool cd = (temp_cr0 >> 30) & 0x01;
|
||||
bx_bool pg = (temp_cr0 >> 31) & 0x01;
|
||||
|
||||
BX_CPU_THIS_PTR dr6 = SMM_SAVED_STATE(saved_state, 0x7fcc);
|
||||
BX_CPU_THIS_PTR dr7 = SMM_SAVED_STATE(saved_state, 0x7fc8);
|
||||
// check conditions for entering to shutdown state
|
||||
if (pg && !pe) {
|
||||
BX_PANIC(("SMM restore: attempt to set CR0.PG with CR0.PE cleared !"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nw && !cd) {
|
||||
BX_PANIC(("SMM restore: attempt to set CR0.NW with CR0.CD cleared !"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
SetCR0(temp_cr0);
|
||||
CR3_change(temp_cr3);
|
||||
setEFlags(temp_eflags);
|
||||
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
if (! SetCR4(SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR4))) {
|
||||
BX_PANIC(("SMM restore: incorrect CR4 state !"));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
EIP = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EIP);
|
||||
EDI = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EDI);
|
||||
ESI = SMRAM_FIELD(saved_state, SMRAM_OFFSET_ESI);
|
||||
EBP = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EBP);
|
||||
ESP = SMRAM_FIELD(saved_state, SMRAM_OFFSET_ESP);
|
||||
EBX = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EBX);
|
||||
EDX = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EDX);
|
||||
ECX = SMRAM_FIELD(saved_state, SMRAM_OFFSET_ECX);
|
||||
EAX = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EAX);
|
||||
|
||||
BX_CPU_THIS_PTR dr6 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR6);
|
||||
BX_CPU_THIS_PTR dr7 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR7);
|
||||
|
||||
BX_CPU_THIS_PTR gdtr.base = SMRAM_FIELD(saved_state, SMRAM_GDTR_BASE);
|
||||
BX_CPU_THIS_PTR gdtr.limit = SMRAM_FIELD(saved_state, SMRAM_GDTR_LIMIT);
|
||||
BX_CPU_THIS_PTR idtr.base = SMRAM_FIELD(saved_state, SMRAM_IDTR_BASE);
|
||||
BX_CPU_THIS_PTR idtr.limit = SMRAM_FIELD(saved_state, SMRAM_IDTR_LIMIT);
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS],
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment CS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
handleCpuModeChange();
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS],
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment DS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS],
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment SS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES],
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment ES !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS],
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment FS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS],
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment GS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR ldtr,
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (BX_CPU_THIS_PTR ldtr.cache.type != BX_SYS_SEGMENT_LDT) {
|
||||
BX_PANIC(("SMM restore: LDTR is not LDT descriptor type !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR tr,
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_LIMIT),
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) >> 16))
|
||||
{
|
||||
if (BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_AVAIL_286_TSS &&
|
||||
BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_BUSY_286_TSS &&
|
||||
BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_AVAIL_386_TSS &&
|
||||
BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_BUSY_386_TSS)
|
||||
{
|
||||
BX_PANIC(("SMM restore: TR is not TSS descriptor type !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) {
|
||||
BX_CPU_THIS_PTR smbase = SMRAM_FIELD(saved_state, SMRAM_SMBASE_OFFSET);
|
||||
#if BX_CPU_LEVEL < 6
|
||||
if (BX_CPU_THIS_PTR smbase & 0x7fff) {
|
||||
BX_PANIC(("SMM restore: SMBASE must be aligned to 32K !"));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: sse.cc,v 1.38 2006-03-06 22:03:02 sshwarts Exp $
|
||||
// $Id: sse.cc,v 1.39 2006-04-05 17:31:32 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2003 Stanislav Shwartsman
|
||||
@ -1550,10 +1550,11 @@ void BX_CPU_C::PMADDWD_VdqWdq(bxInstruction_c *i)
|
||||
if(op1.xmm32u(j) == 0x80008000 && op2.xmm32u(j) == 0x80008000) {
|
||||
result.xmm32u(j) = 0x80000000;
|
||||
}
|
||||
else
|
||||
else {
|
||||
result.xmm32u(j) =
|
||||
Bit32s(op1.xmm16s(2*j+0)) * Bit32s(op2.xmm16s(2*j+0)) +
|
||||
Bit32s(op1.xmm16s(2*j+1)) * Bit32s(op2.xmm16s(2*j+1));
|
||||
}
|
||||
}
|
||||
|
||||
/* now write result back to destination */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: sse_pfp.cc,v 1.26 2006-03-06 22:03:04 sshwarts Exp $
|
||||
// $Id: sse_pfp.cc,v 1.27 2006-04-05 17:31:33 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2003 Stanislav Shwartsman
|
||||
@ -2483,7 +2483,7 @@ void BX_CPU_C::HADDPD_VpdWpd(bxInstruction_c *i)
|
||||
BX_WRITE_XMM_REG(i->nnn(), result);
|
||||
|
||||
#else
|
||||
BX_INFO(("HADDPD_VpdWpd: required PNI, use --enable-pni option"));
|
||||
BX_INFO(("HADDPD_VpdWpd: required SSE3, use --enable-sse option"));
|
||||
UndefinedOpcode(i);
|
||||
#endif
|
||||
}
|
||||
@ -2537,7 +2537,7 @@ void BX_CPU_C::HADDPS_VpsWps(bxInstruction_c *i)
|
||||
BX_WRITE_XMM_REG(i->nnn(), result);
|
||||
|
||||
#else
|
||||
BX_INFO(("HADDPS_VpsWps: required PNI, use --enable-pni option"));
|
||||
BX_INFO(("HADDPS_VpsWps: required SSE3, use --enable-sse option"));
|
||||
UndefinedOpcode(i);
|
||||
#endif
|
||||
}
|
||||
@ -2583,7 +2583,7 @@ void BX_CPU_C::HSUBPD_VpdWpd(bxInstruction_c *i)
|
||||
BX_WRITE_XMM_REG(i->nnn(), result);
|
||||
|
||||
#else
|
||||
BX_INFO(("HSUBPD_VpdWpd: required PNI, use --enable-pni option"));
|
||||
BX_INFO(("HSUBPD_VpdWpd: required SSE3, use --enable-sse option"));
|
||||
UndefinedOpcode(i);
|
||||
#endif
|
||||
}
|
||||
@ -2637,7 +2637,7 @@ void BX_CPU_C::HSUBPS_VpsWps(bxInstruction_c *i)
|
||||
BX_WRITE_XMM_REG(i->nnn(), result);
|
||||
|
||||
#else
|
||||
BX_INFO(("HSUBPS_VpsWps: required PNI, use --enable-pni option"));
|
||||
BX_INFO(("HSUBPS_VpsWps: required SSE3, use --enable-sse option"));
|
||||
UndefinedOpcode(i);
|
||||
#endif
|
||||
}
|
||||
@ -2943,7 +2943,7 @@ void BX_CPU_C::ADDSUBPD_VpdWpd(bxInstruction_c *i)
|
||||
BX_WRITE_XMM_REG(i->nnn(), result);
|
||||
|
||||
#else
|
||||
BX_INFO(("ADDSUBPD_VpdWpd: required PNI, use --enable-pni option"));
|
||||
BX_INFO(("ADDSUBPD_VpdWpd: required SSE3, use --enable-sse option"));
|
||||
UndefinedOpcode(i);
|
||||
#endif
|
||||
}
|
||||
@ -2997,7 +2997,7 @@ void BX_CPU_C::ADDSUBPS_VpsWps(bxInstruction_c *i)
|
||||
BX_WRITE_XMM_REG(i->nnn(), result);
|
||||
|
||||
#else
|
||||
BX_INFO(("ADDSUBPS_VpsWps: required PNI, use --enable-pni option"));
|
||||
BX_INFO(("ADDSUBPS_VpsWps: required SSE3, use --enable-sse option"));
|
||||
UndefinedOpcode(i);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: stack32.cc,v 1.31 2006-03-06 22:03:04 sshwarts Exp $
|
||||
// $Id: stack32.cc,v 1.32 2006-04-05 17:31:34 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -30,11 +30,6 @@
|
||||
#include "cpu.h"
|
||||
#define LOG_THIS BX_CPU_THIS_PTR
|
||||
|
||||
#if BX_SUPPORT_X86_64==0
|
||||
// Make life easier for merging 64&32-bit code.
|
||||
#define RBP EBP
|
||||
#endif
|
||||
|
||||
void BX_CPU_C::POP_Ed(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u val32;
|
||||
@ -315,7 +310,7 @@ void BX_CPU_C::ENTER_IwIb(bxInstruction_c *i)
|
||||
} /* if (level > 0) ... */
|
||||
|
||||
if (ss32) {
|
||||
RBP = frame_ptr32;
|
||||
EBP = frame_ptr32;
|
||||
ESP -= imm16;
|
||||
}
|
||||
else {
|
||||
@ -363,7 +358,7 @@ void BX_CPU_C::LEAVE(bxInstruction_c *i)
|
||||
if (i->os32L()) {
|
||||
Bit32u temp32;
|
||||
pop_32(&temp32);
|
||||
RBP = temp32;
|
||||
EBP = temp32;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -30,9 +30,9 @@ static const unsigned char instruction_has_modrm[512] = {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||||
/* ------------------------------- */
|
||||
1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0F 00 */
|
||||
1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 0F 10 */
|
||||
1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 0F 10 */
|
||||
1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 0F 20 */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0F 30 */
|
||||
0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 0F 30 */
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 40 */
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 50 */
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0F 60 */
|
||||
@ -60,6 +60,7 @@ x86_insn disassembler::decode(bx_bool is_32, bx_bool is_64, bx_address base, bx_
|
||||
x86_insn insn(is_32, is_64);
|
||||
const Bit8u *instruction_begin = instruction = instr;
|
||||
resolve_modrm = NULL;
|
||||
unsigned b3 = 0;
|
||||
|
||||
db_eip = ip;
|
||||
db_base = base; // cs linear base (base for PM & cs<<4 for RM & VM)
|
||||
@ -183,6 +184,9 @@ x86_insn disassembler::decode(bx_bool is_32, bx_bool is_64, bx_address base, bx_
|
||||
|
||||
entry = opcode_table + insn.b1;
|
||||
|
||||
// will require 3rd byte for 3-byte opcode
|
||||
if (entry->Attr & _GRP3BTAB) b3 = fetch_byte();
|
||||
|
||||
if (instruction_has_modrm[insn.b1])
|
||||
{
|
||||
decode_modrm(&insn);
|
||||
@ -232,6 +236,14 @@ x86_insn disassembler::decode(bx_bool is_32, bx_bool is_64, bx_address base, bx_
|
||||
entry = &(BxDisasm3DNowGroup[peek_byte()]);
|
||||
break;
|
||||
|
||||
case _GRP3BTAB:
|
||||
entry = &(OPCODE_TABLE(entry)[b3 >> 4]);
|
||||
break;
|
||||
|
||||
case _GRP3BOP:
|
||||
entry = &(OPCODE_TABLE(entry)[b3 & 15]);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Internal disassembler error - unknown attribute !\n");
|
||||
return x86_insn(is_32, is_64);
|
||||
@ -272,6 +284,11 @@ x86_insn disassembler::decode(bx_bool is_32, bx_bool is_64, bx_address base, bx_
|
||||
if (insn.b1 == 0xE3 && insn.as_32 && !insn.as_64)
|
||||
opcode = &Ia_jecxz_Jb;
|
||||
|
||||
// fix nop opcode
|
||||
if (insn.b1 == 0x90 && !insn.rex_b) {
|
||||
opcode = &Ia_nop;
|
||||
}
|
||||
|
||||
// print instruction disassembly
|
||||
if (intel_mode)
|
||||
print_disassembly_intel(&insn, opcode);
|
||||
|
@ -8,6 +8,8 @@
|
||||
#define _GRP3DNOW 4
|
||||
#define _GRPSSE 5
|
||||
#define _GRPRM 6
|
||||
#define _GRP3BOP 7
|
||||
#define _GRP3BTAB 8
|
||||
|
||||
/* ************************************************************************ */
|
||||
#define GRPSSE(n) _GRPSSE, BxDisasmGroupSSE_##n
|
||||
@ -16,6 +18,8 @@
|
||||
#define GRPMOD(n) _SPLIT11B, BxDisasmGroupMod##n
|
||||
#define GRPFP(n) _GRPFP, BxDisasmFPGroup##n
|
||||
#define GRP3DNOW _GRP3DNOW, BxDisasm3DNowGroup
|
||||
#define GR3BOP(n) _GRP3BOP, BxDisasm3ByteOp##n
|
||||
#define GR3BTAB(n) _GRP3BTAB, BxDisasm3ByteTable##n
|
||||
/* ************************************************************************ */
|
||||
|
||||
#define Apw &disassembler::Apw
|
||||
|
@ -154,6 +154,118 @@ static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f2f[4] = {
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f3800[4] = {
|
||||
/* -- */ { 0, &Ia_pshufb_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_pshufb_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f3801[4] = {
|
||||
/* -- */ { 0, &Ia_phaddw_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_phaddw_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f3802[4] = {
|
||||
/* -- */ { 0, &Ia_phaddd_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_phaddd_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f3803[4] = {
|
||||
/* -- */ { 0, &Ia_phaddsw_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_phaddsw_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f3804[4] = {
|
||||
/* -- */ { 0, &Ia_pmaddubsw_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_pmaddubsw_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f3805[4] = {
|
||||
/* -- */ { 0, &Ia_phsubw_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_phsubw_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f3806[4] = {
|
||||
/* -- */ { 0, &Ia_phsubd_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_phsubd_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f3807[4] = {
|
||||
/* -- */ { 0, &Ia_phsubsw_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_phsubsw_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f3808[4] = {
|
||||
/* -- */ { 0, &Ia_psignb_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_psignb_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f3809[4] = {
|
||||
/* -- */ { 0, &Ia_psignw_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_psignw_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f380a[4] = {
|
||||
/* -- */ { 0, &Ia_psignd_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_psignd_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f380b[4] = {
|
||||
/* -- */ { 0, &Ia_pmulhrsw_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_pmulhrsw_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f381c[4] = {
|
||||
/* -- */ { 0, &Ia_pabsb_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_pabsb_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f381d[4] = {
|
||||
/* -- */ { 0, &Ia_pabsw_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_pabsw_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f381e[4] = {
|
||||
/* -- */ { 0, &Ia_pabsd_Pq_Qq }, // SSE4
|
||||
/* 66 */ { 0, &Ia_pabsd_Vdq_Wdq },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f3a0f[4] = {
|
||||
/* -- */ { 0, &Ia_palignr_Pq_Qq_Ib }, // SSE4
|
||||
/* 66 */ { 0, &Ia_palignr_Vdq_Wdq_Ib },
|
||||
/* F2 */ { 0, &Ia_Invalid },
|
||||
/* F3 */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasmGroupSSE_0f50[4] = {
|
||||
/* -- */ { 0, &Ia_movmskps_Gd_Vps },
|
||||
/* 66 */ { 0, &Ia_movmskpd_Gd_Vpd },
|
||||
@ -2268,6 +2380,107 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodeInfoFP[512] = {
|
||||
/* DF FF */ { 0, &Ia_Invalid },
|
||||
};
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* 3-byte opcode table (Table A-4, 0F 38) */
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasm3ByteOp0f380x[16] = {
|
||||
/* 00 */ { GRPSSE(0f3800) },
|
||||
/* 01 */ { GRPSSE(0f3801) },
|
||||
/* 02 */ { GRPSSE(0f3802) },
|
||||
/* 03 */ { GRPSSE(0f3803) },
|
||||
/* 04 */ { GRPSSE(0f3804) },
|
||||
/* 05 */ { GRPSSE(0f3805) },
|
||||
/* 06 */ { GRPSSE(0f3806) },
|
||||
/* 07 */ { GRPSSE(0f3807) },
|
||||
/* 08 */ { GRPSSE(0f3808) },
|
||||
/* 09 */ { GRPSSE(0f3809) },
|
||||
/* 0A */ { GRPSSE(0f380a) },
|
||||
/* 0B */ { GRPSSE(0f380b) },
|
||||
/* 0C */ { 0, &Ia_Invalid },
|
||||
/* 0D */ { 0, &Ia_Invalid },
|
||||
/* 0E */ { 0, &Ia_Invalid },
|
||||
/* 0F */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasm3ByteOp0f381x[16] = {
|
||||
/* 00 */ { 0, &Ia_Invalid },
|
||||
/* 01 */ { 0, &Ia_Invalid },
|
||||
/* 02 */ { 0, &Ia_Invalid },
|
||||
/* 03 */ { 0, &Ia_Invalid },
|
||||
/* 04 */ { 0, &Ia_Invalid },
|
||||
/* 05 */ { 0, &Ia_Invalid },
|
||||
/* 06 */ { 0, &Ia_Invalid },
|
||||
/* 07 */ { 0, &Ia_Invalid },
|
||||
/* 08 */ { 0, &Ia_Invalid },
|
||||
/* 09 */ { 0, &Ia_Invalid },
|
||||
/* 0A */ { 0, &Ia_Invalid },
|
||||
/* 0B */ { 0, &Ia_Invalid },
|
||||
/* 0C */ { GRPSSE(0f381c) },
|
||||
/* 0D */ { GRPSSE(0f381d) },
|
||||
/* 0E */ { GRPSSE(0f381e) },
|
||||
/* 0F */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasm3ByteTableA4[16] = {
|
||||
/* 00 */ { GR3BOP(0f380x) },
|
||||
/* 01 */ { GR3BOP(0f381x) },
|
||||
/* 02 */ { 0, &Ia_Invalid },
|
||||
/* 03 */ { 0, &Ia_Invalid },
|
||||
/* 04 */ { 0, &Ia_Invalid },
|
||||
/* 05 */ { 0, &Ia_Invalid },
|
||||
/* 06 */ { 0, &Ia_Invalid },
|
||||
/* 07 */ { 0, &Ia_Invalid },
|
||||
/* 08 */ { 0, &Ia_Invalid },
|
||||
/* 09 */ { 0, &Ia_Invalid },
|
||||
/* 0A */ { 0, &Ia_Invalid },
|
||||
/* 0B */ { 0, &Ia_Invalid },
|
||||
/* 0C */ { 0, &Ia_Invalid },
|
||||
/* 0D */ { 0, &Ia_Invalid },
|
||||
/* 0E */ { 0, &Ia_Invalid },
|
||||
/* 0F */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* 3-byte opcode table (Table A-5, 0F 3A) */
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasm3ByteOp0f3a0x[16] = {
|
||||
/* 00 */ { 0, &Ia_Invalid },
|
||||
/* 01 */ { 0, &Ia_Invalid },
|
||||
/* 02 */ { 0, &Ia_Invalid },
|
||||
/* 03 */ { 0, &Ia_Invalid },
|
||||
/* 04 */ { 0, &Ia_Invalid },
|
||||
/* 05 */ { 0, &Ia_Invalid },
|
||||
/* 06 */ { 0, &Ia_Invalid },
|
||||
/* 07 */ { 0, &Ia_Invalid },
|
||||
/* 08 */ { 0, &Ia_Invalid },
|
||||
/* 09 */ { 0, &Ia_Invalid },
|
||||
/* 0A */ { 0, &Ia_Invalid },
|
||||
/* 0B */ { 0, &Ia_Invalid },
|
||||
/* 0C */ { 0, &Ia_Invalid },
|
||||
/* 0D */ { 0, &Ia_Invalid },
|
||||
/* 0E */ { 0, &Ia_Invalid },
|
||||
/* 0F */ { GRPSSE(0f3a0f) }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeTable_t BxDisasm3ByteTableA5[16] = {
|
||||
/* 00 */ { GR3BOP(0f3a0x) },
|
||||
/* 01 */ { 0, &Ia_Invalid },
|
||||
/* 02 */ { 0, &Ia_Invalid },
|
||||
/* 03 */ { 0, &Ia_Invalid },
|
||||
/* 04 */ { 0, &Ia_Invalid },
|
||||
/* 05 */ { 0, &Ia_Invalid },
|
||||
/* 06 */ { 0, &Ia_Invalid },
|
||||
/* 07 */ { 0, &Ia_Invalid },
|
||||
/* 08 */ { 0, &Ia_Invalid },
|
||||
/* 09 */ { 0, &Ia_Invalid },
|
||||
/* 0A */ { 0, &Ia_Invalid },
|
||||
/* 0B */ { 0, &Ia_Invalid },
|
||||
/* 0C */ { 0, &Ia_Invalid },
|
||||
/* 0D */ { 0, &Ia_Invalid },
|
||||
/* 0E */ { 0, &Ia_Invalid },
|
||||
/* 0F */ { 0, &Ia_Invalid }
|
||||
};
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* 16-bit operand size */
|
||||
|
||||
@ -2562,7 +2775,7 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodes16[256*2] = {
|
||||
/* 0F 1C */ { 0, &Ia_Invalid },
|
||||
/* 0F 1D */ { 0, &Ia_Invalid },
|
||||
/* 0F 1E */ { 0, &Ia_Invalid },
|
||||
/* 0F 1F */ { 0, &Ia_Invalid },
|
||||
/* 0F 1F */ { 0, &Ia_multibyte_nop },
|
||||
/* 0F 20 */ { 0, &Ia_movl_Rd_Cd },
|
||||
/* 0F 21 */ { 0, &Ia_movl_Rd_Dd },
|
||||
/* 0F 22 */ { 0, &Ia_movl_Cd_Rd },
|
||||
@ -2587,9 +2800,9 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodes16[256*2] = {
|
||||
/* 0F 35 */ { 0, &Ia_sysexit },
|
||||
/* 0F 36 */ { 0, &Ia_Invalid },
|
||||
/* 0F 37 */ { 0, &Ia_Invalid },
|
||||
/* 0F 38 */ { 0, &Ia_Invalid },
|
||||
/* 0F 38 */ { GR3BTAB(A4) },
|
||||
/* 0F 39 */ { 0, &Ia_Invalid },
|
||||
/* 0F 3A */ { 0, &Ia_Invalid },
|
||||
/* 0F 3A */ { GR3BTAB(A5) },
|
||||
/* 0F 3B */ { 0, &Ia_Invalid },
|
||||
/* 0F 3C */ { 0, &Ia_Invalid },
|
||||
/* 0F 3D */ { 0, &Ia_Invalid },
|
||||
@ -3083,7 +3296,7 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodes32[256*2] = {
|
||||
/* 0F 1C */ { 0, &Ia_Invalid },
|
||||
/* 0F 1D */ { 0, &Ia_Invalid },
|
||||
/* 0F 1E */ { 0, &Ia_Invalid },
|
||||
/* 0F 1F */ { 0, &Ia_Invalid },
|
||||
/* 0F 1F */ { 0, &Ia_multibyte_nop },
|
||||
/* 0F 20 */ { 0, &Ia_movl_Rd_Cd },
|
||||
/* 0F 21 */ { 0, &Ia_movl_Rd_Dd },
|
||||
/* 0F 22 */ { 0, &Ia_movl_Cd_Rd },
|
||||
@ -3108,9 +3321,9 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodes32[256*2] = {
|
||||
/* 0F 35 */ { 0, &Ia_sysexit },
|
||||
/* 0F 36 */ { 0, &Ia_Invalid },
|
||||
/* 0F 37 */ { 0, &Ia_Invalid },
|
||||
/* 0F 38 */ { 0, &Ia_Invalid },
|
||||
/* 0F 38 */ { GR3BTAB(A4) },
|
||||
/* 0F 39 */ { 0, &Ia_Invalid },
|
||||
/* 0F 3A */ { 0, &Ia_Invalid },
|
||||
/* 0F 3A */ { GR3BTAB(A5) },
|
||||
/* 0F 3B */ { 0, &Ia_Invalid },
|
||||
/* 0F 3C */ { 0, &Ia_Invalid },
|
||||
/* 0F 3D */ { 0, &Ia_Invalid },
|
||||
@ -3459,7 +3672,7 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodes64w[256*2] = {
|
||||
/* 8D */ { 0, &Ia_leaw_Gw_Mw },
|
||||
/* 8E */ { 0, &Ia_movw_Sw_Ew },
|
||||
/* 8F */ { 0, &Ia_popw_Ew },
|
||||
/* 90 */ { 0, &Ia_nop },
|
||||
/* 90 */ { 0, &Ia_xchgw_RX_AX }, // handle XCHG R8w, AX
|
||||
/* 91 */ { 0, &Ia_xchgw_RX_AX },
|
||||
/* 92 */ { 0, &Ia_xchgw_RX_AX },
|
||||
/* 93 */ { 0, &Ia_xchgw_RX_AX },
|
||||
@ -3604,7 +3817,7 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodes64w[256*2] = {
|
||||
/* 0F 1C */ { 0, &Ia_Invalid },
|
||||
/* 0F 1D */ { 0, &Ia_Invalid },
|
||||
/* 0F 1E */ { 0, &Ia_Invalid },
|
||||
/* 0F 1F */ { 0, &Ia_Invalid },
|
||||
/* 0F 1F */ { 0, &Ia_multibyte_nop },
|
||||
/* 0F 20 */ { 0, &Ia_movq_Rq_Cq },
|
||||
/* 0F 21 */ { 0, &Ia_movl_Rd_Dd },
|
||||
/* 0F 22 */ { 0, &Ia_movq_Cq_Rq },
|
||||
@ -3629,9 +3842,9 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodes64w[256*2] = {
|
||||
/* 0F 35 */ { 0, &Ia_sysexit },
|
||||
/* 0F 36 */ { 0, &Ia_Invalid },
|
||||
/* 0F 37 */ { 0, &Ia_Invalid },
|
||||
/* 0F 38 */ { 0, &Ia_Invalid },
|
||||
/* 0F 38 */ { GR3BTAB(A4) },
|
||||
/* 0F 39 */ { 0, &Ia_Invalid },
|
||||
/* 0F 3A */ { 0, &Ia_Invalid },
|
||||
/* 0F 3A */ { GR3BTAB(A5) },
|
||||
/* 0F 3B */ { 0, &Ia_Invalid },
|
||||
/* 0F 3C */ { 0, &Ia_Invalid },
|
||||
/* 0F 3D */ { 0, &Ia_Invalid },
|
||||
@ -3977,7 +4190,7 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodes64d[256*2] = {
|
||||
/* 8D */ { 0, &Ia_leal_Gd_Md },
|
||||
/* 8E */ { 0, &Ia_movw_Sw_Ew },
|
||||
/* 8F */ { 0, &Ia_popq_Eq },
|
||||
/* 90 */ { 0, &Ia_nop },
|
||||
/* 90 */ { 0, &Ia_xchgl_ERX_EAX }, // handle XCHG R8d, EAX
|
||||
/* 91 */ { 0, &Ia_xchgl_ERX_EAX },
|
||||
/* 92 */ { 0, &Ia_xchgl_ERX_EAX },
|
||||
/* 93 */ { 0, &Ia_xchgl_ERX_EAX },
|
||||
@ -4122,7 +4335,7 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodes64d[256*2] = {
|
||||
/* 0F 1C */ { 0, &Ia_Invalid },
|
||||
/* 0F 1D */ { 0, &Ia_Invalid },
|
||||
/* 0F 1E */ { 0, &Ia_Invalid },
|
||||
/* 0F 1F */ { 0, &Ia_Invalid },
|
||||
/* 0F 1F */ { 0, &Ia_multibyte_nop },
|
||||
/* 0F 20 */ { 0, &Ia_movq_Rq_Cq },
|
||||
/* 0F 21 */ { 0, &Ia_movl_Rd_Dd },
|
||||
/* 0F 22 */ { 0, &Ia_movq_Cq_Rq },
|
||||
@ -4147,9 +4360,9 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodes64d[256*2] = {
|
||||
/* 0F 35 */ { 0, &Ia_sysexit },
|
||||
/* 0F 36 */ { 0, &Ia_Invalid },
|
||||
/* 0F 37 */ { 0, &Ia_Invalid },
|
||||
/* 0F 38 */ { 0, &Ia_Invalid },
|
||||
/* 0F 38 */ { GR3BTAB(A4) },
|
||||
/* 0F 39 */ { 0, &Ia_Invalid },
|
||||
/* 0F 3A */ { 0, &Ia_Invalid },
|
||||
/* 0F 3A */ { GR3BTAB(A5) },
|
||||
/* 0F 3B */ { 0, &Ia_Invalid },
|
||||
/* 0F 3C */ { 0, &Ia_Invalid },
|
||||
/* 0F 3D */ { 0, &Ia_Invalid },
|
||||
@ -4495,7 +4708,7 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodes64q[256*2] = {
|
||||
/* 8D */ { 0, &Ia_leaq_Gq_Mq },
|
||||
/* 8E */ { 0, &Ia_movw_Sw_Ew },
|
||||
/* 8F */ { 0, &Ia_popq_Eq },
|
||||
/* 90 */ { 0, &Ia_nop },
|
||||
/* 90 */ { 0, &Ia_xchgq_RRX_RAX }, // handle XCHG R8, RAX
|
||||
/* 91 */ { 0, &Ia_xchgq_RRX_RAX },
|
||||
/* 92 */ { 0, &Ia_xchgq_RRX_RAX },
|
||||
/* 93 */ { 0, &Ia_xchgq_RRX_RAX },
|
||||
@ -4640,7 +4853,7 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodes64q[256*2] = {
|
||||
/* 0F 1C */ { 0, &Ia_Invalid },
|
||||
/* 0F 1D */ { 0, &Ia_Invalid },
|
||||
/* 0F 1E */ { 0, &Ia_Invalid },
|
||||
/* 0F 1F */ { 0, &Ia_Invalid },
|
||||
/* 0F 1F */ { 0, &Ia_multibyte_nop },
|
||||
/* 0F 20 */ { 0, &Ia_movq_Rq_Cq },
|
||||
/* 0F 21 */ { 0, &Ia_movq_Rq_Dq },
|
||||
/* 0F 22 */ { 0, &Ia_movq_Cq_Rq },
|
||||
@ -4665,9 +4878,9 @@ static BxDisasmOpcodeTable_t BxDisasmOpcodes64q[256*2] = {
|
||||
/* 0F 35 */ { 0, &Ia_sysexit },
|
||||
/* 0F 36 */ { 0, &Ia_Invalid },
|
||||
/* 0F 37 */ { 0, &Ia_Invalid },
|
||||
/* 0F 38 */ { 0, &Ia_Invalid },
|
||||
/* 0F 38 */ { GR3BTAB(A4) },
|
||||
/* 0F 39 */ { 0, &Ia_Invalid },
|
||||
/* 0F 3A */ { 0, &Ia_Invalid },
|
||||
/* 0F 3A */ { GR3BTAB(A5) },
|
||||
/* 0F 3B */ { 0, &Ia_Invalid },
|
||||
/* 0F 3C */ { 0, &Ia_Invalid },
|
||||
/* 0F 3D */ { 0, &Ia_Invalid },
|
||||
|
@ -16,30 +16,22 @@
|
||||
}
|
||||
|
||||
// will be used in future
|
||||
#define IA_8086 0x00000000 /* 8086 instruction */
|
||||
#define IA_286 0x00000000 /* 286+ instruction */
|
||||
#define IA_386 0x00000000 /* 386+ instruction */
|
||||
#define IA_FPU 0x00000000
|
||||
#define IA_486 0x00000000 /* 486+ instruction */
|
||||
#define IA_PENTIUM 0x00000000 /* Pentium instruction */
|
||||
#define IA_P6 0x00000000 /* P6 instruction */
|
||||
#define IA_KATMAI 0x00000000 /* Katmai instruction */
|
||||
#define IA_WILLAMETTE 0x00000000 /* Willamette instruction */
|
||||
#define IA_PRESCOTT 0x00000000 /* Prescott instruction */
|
||||
#define IA_X86_64 0x00000000 /* x86-64 specific instruction */
|
||||
|
||||
#define IF_ARITHMETIC 0x00000000 /* arithmetic instruction */
|
||||
#define IF_LOGIC 0x00000000 /* logic instruction */
|
||||
#define IF_SYSTEM 0x00000000 /* system instruction (require CPL=0) */
|
||||
#define IF_BRANCH 0x00000000 /* branch instruction */
|
||||
#define IF_FPU 0x00000000 /* FPU instruction */
|
||||
#define IF_MMX 0x00000000 /* MMX instruction */
|
||||
#define IF_3DNOW 0x00000000 /* 3DNow! instruction */
|
||||
#define IF_KNI 0x00000000 /* Katmai new instruction */
|
||||
#define IF_PREFETCH 0x00000000 /* Prefetch instruction */
|
||||
#define IF_SSE 0x00000000 /* SSE instruction */
|
||||
#define IF_SSE2 0x00000000 /* SSE2 instruction */
|
||||
#define IF_PNI 0x00000000 /* Prescott new instruction */
|
||||
#define IA_286 0x00000001 /* 286+ instruction */
|
||||
#define IA_386 0x00000002 /* 386+ instruction */
|
||||
#define IA_486 0x00000004 /* 486+ instruction */
|
||||
#define IA_PENTIUM 0x00000008 /* Pentium+ instruction */
|
||||
#define IA_P6 0x00000010 /* P6 new instruction */
|
||||
#define IA_SYSTEM 0x00000020 /* system instruction (require CPL=0) */
|
||||
#define IA_LEGACY 0x00000040 /* legacy instruction */
|
||||
#define IA_X87 0x00000080 /* FPU (X87) instruction */
|
||||
#define IA_MMX 0x00000100 /* MMX instruction */
|
||||
#define IA_3DNOW 0x00000200 /* 3DNow! instruction */
|
||||
#define IA_PREFETCH 0x00000400 /* Prefetch instruction */
|
||||
#define IA_SSE 0x00000800 /* SSE instruction */
|
||||
#define IA_SSE2 0x00001000 /* SSE2 instruction */
|
||||
#define IA_SSE3 0x00002000 /* SSE3 instruction */
|
||||
#define IA_SSE4 0x00004000 /* SSE4 instruction */
|
||||
#define IA_X86_64 0x00008000 /* x86-64 instruction */
|
||||
|
||||
/* general purpose bit register */
|
||||
enum {
|
||||
|
@ -667,6 +667,7 @@ Ia_mulps_Vps_Wps = { "mulps", "mulps", Vps, Wps, XX },
|
||||
Ia_mulq_RAX_Eq = { "mul", "mulq", RAX, Eq, XX },
|
||||
Ia_mulsd_Vsd_Wsd = { "mulsd", "mulsd", Vsd, Wsd, XX },
|
||||
Ia_mulss_Vss_Wss = { "mulss", "mulss", Vss, Wss, XX },
|
||||
Ia_multibyte_nop = { "multibyte nop", "multibyte nop", XX, XX, XX },
|
||||
Ia_mulw_AX_Ew = { "mul", "mulw", AX, Ew, XX },
|
||||
Ia_mwait = { "mwait", "mwait", XX, XX, XX },
|
||||
Ia_negb_Eb = { "neg", "negb", Eb, XX, XX },
|
||||
@ -708,6 +709,12 @@ Ia_outsl_DX_Xd = { "outsd", "outsl", DX, Xd, XX },
|
||||
Ia_outsw_DX_Xw = { "outsw", "outsw", DX, Xw, XX },
|
||||
Ia_outw_DX_AX = { "out", "outw", DX, AX, XX },
|
||||
Ia_outw_Ib_AX = { "out", "outw", Ib, AX, XX },
|
||||
Ia_pabsb_Pq_Qq = { "pabsb", "pabsb", Pq, Qq, XX },
|
||||
Ia_pabsb_Vdq_Wdq = { "pabsb", "pabsb", Vdq, Wdq, XX },
|
||||
Ia_pabsd_Pq_Qq = { "pabsd", "pabsd", Pq, Qq, XX },
|
||||
Ia_pabsd_Vdq_Wdq = { "pabsd", "pabsd", Vdq, Wdq, XX },
|
||||
Ia_pabsw_Pq_Qq = { "pabsw", "pabsw", Pq, Qq, XX },
|
||||
Ia_pabsw_Vdq_Wdq = { "pabsw", "pabsw", Vdq, Wdq, XX },
|
||||
Ia_packssdw_Pq_Qq = { "packssdw", "packssdw", Pq, Qq, XX },
|
||||
Ia_packssdw_Vdq_Wdq = { "packssdw", "packssdw", Vdq, Wdq, XX },
|
||||
Ia_packsswb_Pq_Qq = { "packsswb", "packsswb", Pq, Qq, XX },
|
||||
@ -730,6 +737,8 @@ Ia_paddusw_Pq_Qq = { "paddusw", "paddusw", Pq, Qq, XX },
|
||||
Ia_paddusw_Vdq_Wdq = { "paddusw", "paddusw", Vdq, Wdq, XX },
|
||||
Ia_paddw_Pq_Qq = { "paddw", "paddw", Pq, Qq, XX },
|
||||
Ia_paddw_Vdq_Wdq = { "paddw", "paddw", Vdq, Wdq, XX },
|
||||
Ia_palignr_Pq_Qq_Ib = { "palignr", "palignr", Pq, Qq, Ib },
|
||||
Ia_palignr_Vdq_Wdq_Ib = { "palignr", "palignr", Vdq, Wdq, Ib },
|
||||
Ia_pand_Pq_Qq = { "pand", "pand", Pq, Qq, XX },
|
||||
Ia_pand_Vdq_Wdq = { "pand", "pand", Vdq, Wdq, XX },
|
||||
Ia_pandn_Pq_Qq = { "pandn", "pandn", Pq, Qq, XX },
|
||||
@ -772,10 +781,24 @@ Ia_pfrsqit1_Pq_Qq = { "pfrsqit1", "pfrsqit1", Pq, Qq, XX },
|
||||
Ia_pfrsqrt_Pq_Qq = { "pfrsqrt", "pfrsqrt", Pq, Qq, XX },
|
||||
Ia_pfsub_Pq_Qq = { "pfsub", "pfsub", Pq, Qq, XX },
|
||||
Ia_pfsubr_Pq_Qq = { "pfsubr", "pfsubr", Pq, Qq, XX },
|
||||
Ia_phaddd_Pq_Qq = { "phaddd", "phaddd", Pq, Qq, XX },
|
||||
Ia_phaddd_Vdq_Wdq = { "phaddd", "phaddd", Vdq, Wdq, XX },
|
||||
Ia_phaddsw_Pq_Qq = { "phaddsw", "phaddsw", Pq, Qq, XX },
|
||||
Ia_phaddsw_Vdq_Wdq = { "phaddsw", "phaddsw", Vdq, Wdq, XX },
|
||||
Ia_phaddw_Pq_Qq = { "phaddw", "phaddw", Pq, Qq, XX },
|
||||
Ia_phaddw_Vdq_Wdq = { "phaddw", "phaddw", Vdq, Wdq, XX },
|
||||
Ia_phsubd_Pq_Qq = { "phsubd", "phsubd", Pq, Qq, XX },
|
||||
Ia_phsubd_Vdq_Wdq = { "phsubd", "phsubd", Vdq, Wdq, XX },
|
||||
Ia_phsubsw_Pq_Qq = { "phsubsw", "phsubsw", Pq, Qq, XX },
|
||||
Ia_phsubsw_Vdq_Wdq = { "phsubsw", "phsubsw", Vdq, Wdq, XX },
|
||||
Ia_phsubw_Pq_Qq = { "phsubw", "phsubw", Pq, Qq, XX },
|
||||
Ia_phsubw_Vdq_Wdq = { "phsubw", "phsubw", Vdq, Wdq, XX },
|
||||
Ia_pi2fd_Pq_Qq = { "pi2fd", "pi2fd", Pq, Qq, XX },
|
||||
Ia_pi2fw_Pq_Qq = { "pi2fw", "pi2fw", Pq, Qq, XX },
|
||||
Ia_pinsrw_Pq_Ed_Ib = { "pinsrw", "pinsrw", Pq, Ed, Ib },
|
||||
Ia_pinsrw_Vdq_Ed_Ib = { "pinsrw", "pinsrw", Vdq, Ed, Ib },
|
||||
Ia_pmaddubsw_Pq_Qq = { "pmaddubsw", "pmaddubsw", Pq, Qq, XX },
|
||||
Ia_pmaddubsw_Vdq_Wdq = { "pmaddubsw", "pmaddubsw", Vdq, Wdq, XX },
|
||||
Ia_pmaddwd_Pq_Qq = { "pmaddwd", "pmaddwd", Pq, Qq, XX },
|
||||
Ia_pmaddwd_Vdq_Wdq = { "pmaddwd", "pmaddwd", Vdq, Wdq, XX },
|
||||
Ia_pmaxub_Pq_Qq = { "pmaxub", "pmaxub", Pq, Qq, XX },
|
||||
@ -788,6 +811,8 @@ Ia_pminub_Pq_Qq = { "pminub", "pminub", Pq, Qq, XX },
|
||||
Ia_pminub_Vdq_Wdq = { "pminub", "pminub", Vdq, Wdq, XX },
|
||||
Ia_pmovmskb_Gd_Nq = { "pmovmskb", "pmovmskb", Gd, Nq, XX },
|
||||
Ia_pmovmskb_Gd_Udq = { "pmovmskb", "pmovmskb", Gd, Udq, XX },
|
||||
Ia_pmulhrsw_Pq_Qq = { "pmulhrsw", "pmulhrsw", Pq, Qq, XX },
|
||||
Ia_pmulhrsw_Vdq_Wdq = { "pmulhrsw", "pmulhrsw", Vdq, Wdq, XX },
|
||||
Ia_pmulhrw_Pq_Qq = { "pmulhrw", "pmulhrw", Pq, Qq, XX },
|
||||
Ia_pmulhuw_Pq_Qq = { "pmulhuw", "pmulhuw", Pq, Qq, XX },
|
||||
Ia_pmulhuw_Vdq_Wdq = { "pmulhuw", "pmulhuw", Vdq, Wdq, XX },
|
||||
@ -841,10 +866,18 @@ Ia_prefix_rex = { "rex", "rex", XX, XX, XX },
|
||||
Ia_prefix_ss = { "ss", "ss", XX, XX, XX },
|
||||
Ia_psadbw_Pq_Qq = { "psadbw", "psadbw", Pq, Qq, XX },
|
||||
Ia_psadbw_Vdq_Wdq = { "psadbw", "psadbw", Vdq, Wdq, XX },
|
||||
Ia_pshufb_Pq_Qq = { "pshufb", "pshufb", Pq, Qq, XX },
|
||||
Ia_pshufb_Vdq_Wdq = { "pshufb", "pshufb", Vdq, Wdq, XX },
|
||||
Ia_pshufd_Vdq_Wdq_Ib = { "pshufd", "pshufd", Vdq, Wdq, Ib },
|
||||
Ia_pshufhw_Vq_Wq_Ib = { "pshufhw", "pshufhw", Vq, Wq, Ib },
|
||||
Ia_pshuflw_Vq_Wq_Ib = { "pshuflw", "pshuflw", Vq, Wq, Ib },
|
||||
Ia_pshufw_Pq_Qq_Ib = { "pshufw", "pshufw", Pq, Qq, Ib },
|
||||
Ia_psignb_Pq_Qq = { "psignb", "psignb", Pq, Qq, XX },
|
||||
Ia_psignb_Vdq_Wdq = { "psignb", "psignb", Vdq, Wdq, XX },
|
||||
Ia_psignd_Pq_Qq = { "psignd", "psignd", Pq, Qq, XX },
|
||||
Ia_psignd_Vdq_Wdq = { "psignd", "psignd", Vdq, Wdq, XX },
|
||||
Ia_psignw_Pq_Qq = { "psignw", "psignw", Pq, Qq, XX },
|
||||
Ia_psignw_Vdq_Wdq = { "psignw", "psignw", Vdq, Wdq, XX },
|
||||
Ia_pslld_Nq_Ib = { "pslld", "pslld", Nq, Ib, XX },
|
||||
Ia_pslld_Pq_Qq = { "pslld", "pslld", Pq, Qq, XX },
|
||||
Ia_pslld_Udq_Ib = { "pslld", "pslld", Udq, Ib, XX },
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!--
|
||||
================================================================
|
||||
doc/docbook/user/user.dbk
|
||||
$Id: user.dbk,v 1.208 2006-02-11 21:57:04 sshwarts Exp $
|
||||
$Id: user.dbk,v 1.209 2006-04-05 17:31:35 sshwarts Exp $
|
||||
|
||||
This is the top level file for the Bochs Users Manual.
|
||||
================================================================
|
||||
@ -35,7 +35,7 @@ This is the top level file for the Bochs Users Manual.
|
||||
<para>
|
||||
Bochs is a program that simulates a complete Intel x86 computer. It
|
||||
can be configured to act like a <!--286,--> 386, 486, Pentium, Pentium Pro, or
|
||||
AMD64 CPU, including optional MMX, SSE, SSE2 and 3DNow! instructions.
|
||||
AMD64 CPU, including optional MMX, SSE, SSE2, SSE3 and 3DNow! instructions.
|
||||
Bochs interprets every instruction from power-up to reboot, and has
|
||||
device models for all of the standard PC peripherals: keyboard, mouse,
|
||||
VGA card/monitor, disks, timer chips, network card, etc. Because Bochs
|
||||
@ -2210,14 +2210,9 @@ turn it off.
|
||||
<entry>no</entry>
|
||||
<entry>
|
||||
Add support for SSE instructions, written by Stanislav Shwartsman.
|
||||
For SSE only, use --enable-sse=1. For SSE and SSE2, use --enable-sse=2.
|
||||
Any of SSE/SSE2/SSE3 instruction sets are supported.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>--enable-pni</entry>
|
||||
<entry>no</entry>
|
||||
<entry>Add support for PNI (SSE3) instructions</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>--enable-sep</entry>
|
||||
<entry>no</entry>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fpu_load_store.cc,v 1.10 2006-03-06 22:03:04 sshwarts Exp $
|
||||
// $Id: fpu_load_store.cc,v 1.11 2006-04-05 17:31:35 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2003 Stanislav Shwartsman
|
||||
@ -600,7 +600,7 @@ void BX_CPU_C::FISTTP16(bxInstruction_c *i)
|
||||
write_virtual_word(i->seg(), RMAddr(i), (Bit16u*)(&save_reg));
|
||||
BX_CPU_THIS_PTR the_i387.FPU_pop();
|
||||
#else
|
||||
BX_INFO(("FISTTP16: required PNI, configure --enable-pni"));
|
||||
BX_INFO(("FISTTP16: required SSE3, use --enable-sse option"));
|
||||
UndefinedOpcode(i);
|
||||
#endif
|
||||
}
|
||||
@ -636,7 +636,7 @@ void BX_CPU_C::FISTTP32(bxInstruction_c *i)
|
||||
write_virtual_dword(i->seg(), RMAddr(i), (Bit32u*)(&save_reg));
|
||||
BX_CPU_THIS_PTR the_i387.FPU_pop();
|
||||
#else
|
||||
BX_INFO(("FISTTP32: required PNI, configure --enable-pni"));
|
||||
BX_INFO(("FISTTP32: required SSE3, use --enable-sse option"));
|
||||
UndefinedOpcode(i);
|
||||
#endif
|
||||
}
|
||||
@ -672,7 +672,7 @@ void BX_CPU_C::FISTTP64(bxInstruction_c *i)
|
||||
write_virtual_qword(i->seg(), RMAddr(i), (Bit64u*)(&save_reg));
|
||||
BX_CPU_THIS_PTR the_i387.FPU_pop();
|
||||
#else
|
||||
BX_INFO(("FISTTP64: required PNI, configure --enable-pni"));
|
||||
BX_INFO(("FISTTP64: required SSE3, use --enable-sse option"));
|
||||
UndefinedOpcode(i);
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user