stack direct access optimization - 5% emu speedup to all 32-bit guests, for 64-bit guests speedup is less because they have less stack accesses
This commit is contained in:
parent
c43cf378f4
commit
3ca29cbdf3
@ -1,6 +1,8 @@
|
||||
Changes after 2.5.1 release:
|
||||
|
||||
- CPU
|
||||
- Another 10% CPU emulation speedup with even more optimal lazy flags
|
||||
handling and stack access optimizations
|
||||
- Support for AMD's SVM hardware emulation in Bochs CPU, to enable
|
||||
configure with --enable-svm option
|
||||
- Implemented AMD Extended XAPIC support, to enable set .bochsrc CPU
|
||||
@ -14,7 +16,7 @@ Changes after 2.5.1 release:
|
||||
- Implemented new debugger command 'info device [string]' that shows the
|
||||
state of the device specified in 'string'
|
||||
- Improved debug dump for pci, pic and vga/cirrus devices
|
||||
- Added debug dump for pci2isa and DMA controller devices
|
||||
- Added debug dump for pci2isa, floppy and DMA controller devices
|
||||
|
||||
- Configure and compile
|
||||
- Moved networking, sound and USB devices to subdirectories in iodev
|
||||
|
@ -75,6 +75,7 @@ OBJS = \
|
||||
shift32.o \
|
||||
shift8.o \
|
||||
arith8.o \
|
||||
stack.o \
|
||||
stack16.o \
|
||||
protect_ctrl.o \
|
||||
mult8.o \
|
||||
@ -741,6 +742,13 @@ sse_string.o: sse_string.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
|
||||
descriptor.h instr.h ia_opcodes.h lazy_flags.h icache.h apic.h i387.h \
|
||||
../fpu/softfloat.h ../fpu/tag_w.h ../fpu/status_w.h ../fpu/control_w.h \
|
||||
xmm.h vmx.h svm.h stack.h
|
||||
stack.o: stack.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
|
||||
../bx_debug/debug.h ../config.h ../osdep.h ../gui/siminterface.h \
|
||||
../cpudb.h ../gui/paramtree.h ../memory/memory.h ../pc_system.h \
|
||||
../gui/gui.h ../instrument/stubs/instrument.h cpu.h cpuid.h crregs.h \
|
||||
descriptor.h instr.h ia_opcodes.h lazy_flags.h icache.h apic.h i387.h \
|
||||
../fpu/softfloat.h ../fpu/tag_w.h ../fpu/status_w.h ../fpu/control_w.h \
|
||||
xmm.h vmx.h svm.h stack.h
|
||||
stack16.o: stack16.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
|
||||
../bx_debug/debug.h ../config.h ../osdep.h ../gui/siminterface.h \
|
||||
../cpudb.h ../gui/paramtree.h ../memory/memory.h ../pc_system.h \
|
||||
|
@ -353,7 +353,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::call_gate(bx_descriptor_t *gate_descriptor
|
||||
|
||||
for (unsigned n=param_count; n>0; n--) {
|
||||
temp_ESP -= 4;
|
||||
Bit32u param = read_virtual_dword_32(BX_SEG_REG_SS, return_ESP + (n-1)*4);
|
||||
Bit32u param = stack_read_dword(return_ESP + (n-1)*4);
|
||||
write_new_stack_dword_32(&new_stack, temp_ESP, cs_descriptor.dpl, param);
|
||||
}
|
||||
// push return address onto new stack
|
||||
@ -368,7 +368,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::call_gate(bx_descriptor_t *gate_descriptor
|
||||
|
||||
for (unsigned n=param_count; n>0; n--) {
|
||||
temp_ESP -= 2;
|
||||
Bit16u param = read_virtual_word_32(BX_SEG_REG_SS, return_ESP + (n-1)*2);
|
||||
Bit16u param = stack_read_word(return_ESP + (n-1)*2);
|
||||
write_new_stack_word_32(&new_stack, temp_ESP, cs_descriptor.dpl, param);
|
||||
}
|
||||
// push return address onto new stack
|
||||
@ -390,7 +390,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::call_gate(bx_descriptor_t *gate_descriptor
|
||||
|
||||
for (unsigned n=param_count; n>0; n--) {
|
||||
temp_SP -= 4;
|
||||
Bit32u param = read_virtual_dword_32(BX_SEG_REG_SS, return_ESP + (n-1)*4);
|
||||
Bit32u param = stack_read_dword(return_ESP + (n-1)*4);
|
||||
write_new_stack_dword_32(&new_stack, temp_SP, cs_descriptor.dpl, param);
|
||||
}
|
||||
// push return address onto new stack
|
||||
@ -405,7 +405,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::call_gate(bx_descriptor_t *gate_descriptor
|
||||
|
||||
for (unsigned n=param_count; n>0; n--) {
|
||||
temp_SP -= 2;
|
||||
Bit16u param = read_virtual_word_32(BX_SEG_REG_SS, return_ESP + (n-1)*2);
|
||||
Bit16u param = stack_read_word(return_ESP + (n-1)*2);
|
||||
write_new_stack_word_32(&new_stack, temp_SP, cs_descriptor.dpl, param);
|
||||
}
|
||||
// push return address onto new stack
|
||||
|
@ -1117,12 +1117,18 @@ public: // for now...
|
||||
jmp_buf jmp_buf_env;
|
||||
Bit8u curr_exception;
|
||||
|
||||
// Boundaries of current page, based on EIP
|
||||
// Boundaries of current code page, based on EIP
|
||||
bx_address eipPageBias;
|
||||
Bit32u eipPageWindowSize;
|
||||
const Bit8u *eipFetchPtr;
|
||||
bx_phy_address pAddrFetchPage; // Guest physical address of current instruction page
|
||||
|
||||
// Boundaries of current stack page, based on ESP
|
||||
bx_address espPageBias; // Linear address of current stack page
|
||||
Bit32u espPageWindowSize;
|
||||
const Bit8u *espHostPtr;
|
||||
bx_phy_address pAddrStackPage; // Guest physical address of current stack page
|
||||
|
||||
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
|
||||
unsigned alignment_check_mask;
|
||||
#endif
|
||||
@ -1464,6 +1470,9 @@ public: // for now...
|
||||
BX_SMF BX_INSF_TYPE MOV32_GdEdM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF BX_INSF_TYPE MOV32_EdGdM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
|
||||
BX_SMF BX_INSF_TYPE MOV32S_GdEdM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF BX_INSF_TYPE MOV32S_EdGdM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
|
||||
BX_SMF BX_INSF_TYPE MOV_EwSwM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF BX_INSF_TYPE MOV_EwSwR(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF BX_INSF_TYPE MOV_SwEw(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
@ -3306,6 +3315,9 @@ public: // for now...
|
||||
BX_SMF BX_INSF_TYPE MOV_EqIdR(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF BX_INSF_TYPE MOV_EqIdM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
|
||||
BX_SMF BX_INSF_TYPE MOV64S_EqGqM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF BX_INSF_TYPE MOV64S_GqEqM(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
|
||||
// repeatable instructions
|
||||
BX_SMF BX_INSF_TYPE REP_MOVSQ_XqYq(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF BX_INSF_TYPE REP_CMPSQ_XqYq(bxInstruction_c *) BX_CPP_AttrRegparmN(1);
|
||||
@ -3637,6 +3649,11 @@ public: // for now...
|
||||
BX_CPU_THIS_PTR eipPageWindowSize = 0;
|
||||
}
|
||||
|
||||
BX_SMF BX_CPP_INLINE void invalidate_stack_cache(void)
|
||||
{
|
||||
BX_CPU_THIS_PTR espPageWindowSize = 0;
|
||||
}
|
||||
|
||||
BX_SMF bx_bool write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned len) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF bx_bool read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned len) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF bx_bool execute_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned len) BX_CPP_AttrRegparmN(3);
|
||||
@ -3889,6 +3906,18 @@ public: // for now...
|
||||
|
||||
#endif
|
||||
|
||||
BX_SMF void stack_write_byte(bx_address offset, Bit8u data) BX_CPP_AttrRegparmN(2);
|
||||
BX_SMF void stack_write_word(bx_address offset, Bit16u data) BX_CPP_AttrRegparmN(2);
|
||||
BX_SMF void stack_write_dword(bx_address offset, Bit32u data) BX_CPP_AttrRegparmN(2);
|
||||
BX_SMF void stack_write_qword(bx_address offset, Bit64u data) BX_CPP_AttrRegparmN(2);
|
||||
|
||||
BX_SMF Bit8u stack_read_byte(bx_address offset) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF Bit16u stack_read_word(bx_address offset) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF Bit32u stack_read_dword(bx_address offset) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF Bit64u stack_read_qword(bx_address offset) BX_CPP_AttrRegparmN(1);
|
||||
|
||||
BX_SMF void stackPrefetch(bx_address offset, unsigned len) BX_CPP_AttrRegparmN(2);
|
||||
|
||||
BX_SMF Bit8u system_read_byte(bx_address laddr) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF Bit16u system_read_word(bx_address laddr) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF Bit32u system_read_dword(bx_address laddr) BX_CPP_AttrRegparmN(1);
|
||||
@ -4016,6 +4045,7 @@ public: // for now...
|
||||
BX_SMF void reset(unsigned source);
|
||||
BX_SMF void shutdown(void);
|
||||
BX_SMF void handleCpuModeChange(void);
|
||||
BX_SMF void handleCpuContextChange(void);
|
||||
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
|
||||
BX_SMF void handleAlignmentCheck(void);
|
||||
#endif
|
||||
@ -4848,6 +4878,7 @@ enum {
|
||||
|
||||
#define BxTraceEnd 0x4000 // bit 14
|
||||
|
||||
|
||||
#ifdef BX_TRACE_CACHE_NO_SPECULATIVE_TRACING
|
||||
#define BxTraceJCC BxTraceEnd
|
||||
#else
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2011 The Bochs Project
|
||||
// Copyright (C) 2001-2012 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -49,7 +49,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear64_Iw(bxInstruction_c *i)
|
||||
BX_CPU_THIS_PTR show_flag |= Flag_ret;
|
||||
#endif
|
||||
|
||||
Bit64u return_RIP = read_virtual_qword_64(BX_SEG_REG_SS, RSP);
|
||||
Bit64u return_RIP = stack_read_qword(RSP);
|
||||
|
||||
if (! IsCanonical(return_RIP)) {
|
||||
BX_ERROR(("RETnear64_Iw: canonical RIP violation"));
|
||||
@ -70,7 +70,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RETnear64(bxInstruction_c *i)
|
||||
BX_CPU_THIS_PTR show_flag |= Flag_ret;
|
||||
#endif
|
||||
|
||||
Bit64u return_RIP = read_virtual_qword_64(BX_SEG_REG_SS, RSP);
|
||||
Bit64u return_RIP = stack_read_qword(RSP);
|
||||
|
||||
if (! IsCanonical(return_RIP)) {
|
||||
BX_ERROR(("RETnear64: canonical RIP violation %08x%08x", GET32H(return_RIP), GET32L(return_RIP)));
|
||||
@ -113,7 +113,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_Jq(bxInstruction_c *i)
|
||||
#endif
|
||||
|
||||
/* push 64 bit EA of next instruction */
|
||||
write_virtual_qword_64(BX_SEG_REG_SS, RSP-8, RIP);
|
||||
stack_write_qword(RSP-8, RIP);
|
||||
|
||||
if (! IsCanonical(new_RIP)) {
|
||||
BX_ERROR(("CALL_Jq: canonical RIP violation"));
|
||||
@ -137,7 +137,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CALL_EqR(bxInstruction_c *i)
|
||||
Bit64u new_RIP = BX_READ_64BIT_REG(i->rm());
|
||||
|
||||
/* push 64 bit EA of next instruction */
|
||||
write_virtual_qword_64(BX_SEG_REG_SS, RSP-8, RIP);
|
||||
stack_write_qword(RSP-8, RIP);
|
||||
|
||||
if (! IsCanonical(new_RIP))
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2011 The Bochs Project
|
||||
// Copyright (C) 2001-2012 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -55,6 +55,15 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV32_EdGdM(bxInstruction_c *i)
|
||||
BX_NEXT_INSTR(i);
|
||||
}
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV32S_EdGdM(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u eaddr = (Bit32u) BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
||||
|
||||
stack_write_dword(eaddr, BX_READ_32BIT_REG(i->nnn()));
|
||||
|
||||
BX_NEXT_INSTR(i);
|
||||
}
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GdEdR(bxInstruction_c *i)
|
||||
{
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), BX_READ_32BIT_REG(i->rm()));
|
||||
@ -65,8 +74,18 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GdEdR(bxInstruction_c *i)
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV32_GdEdM(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u eaddr = (Bit32u) BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
||||
|
||||
Bit32u val32 = read_virtual_dword_32(i->seg(), eaddr);
|
||||
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), val32);
|
||||
|
||||
BX_NEXT_INSTR(i);
|
||||
}
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV32S_GdEdM(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u eaddr = (Bit32u) BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
||||
Bit32u val32 = stack_read_dword(eaddr);
|
||||
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), val32);
|
||||
|
||||
BX_NEXT_INSTR(i);
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2011 The Bochs Project
|
||||
// Copyright (C) 2001-2012 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -45,8 +45,8 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RRXIq(bxInstruction_c *i)
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV64_GdEdM(bxInstruction_c *i)
|
||||
{
|
||||
Bit64u eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
||||
|
||||
Bit32u val32 = read_virtual_dword_64(i->seg(), eaddr);
|
||||
|
||||
BX_WRITE_32BIT_REGZ(i->nnn(), val32);
|
||||
|
||||
BX_NEXT_INSTR(i);
|
||||
@ -70,16 +70,34 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_EqGqM(bxInstruction_c *i)
|
||||
BX_NEXT_INSTR(i);
|
||||
}
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GqEqM(bxInstruction_c *i)
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV64S_EqGqM(bxInstruction_c *i)
|
||||
{
|
||||
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
||||
|
||||
stack_write_qword(eaddr, BX_READ_64BIT_REG(i->nnn()));
|
||||
|
||||
BX_NEXT_INSTR(i);
|
||||
}
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GqEqM(bxInstruction_c *i)
|
||||
{
|
||||
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
||||
Bit64u val64 = read_virtual_qword_64(i->seg(), eaddr);
|
||||
|
||||
BX_WRITE_64BIT_REG(i->nnn(), val64);
|
||||
|
||||
BX_NEXT_INSTR(i);
|
||||
}
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV64S_GqEqM(bxInstruction_c *i)
|
||||
{
|
||||
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
||||
|
||||
BX_WRITE_64BIT_REG(i->nnn(), stack_read_qword(eaddr));
|
||||
|
||||
BX_NEXT_INSTR(i);
|
||||
}
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_GqEqR(bxInstruction_c *i)
|
||||
{
|
||||
BX_WRITE_64BIT_REG(i->nnn(), BX_READ_64BIT_REG(i->rm()));
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2011 The Bochs Project
|
||||
// Copyright (C) 2001-2012 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -1937,6 +1937,15 @@ modrm_done:
|
||||
if (mod_mem) {
|
||||
i->execute = BxOpcodesTable[ia_opcode].execute1;
|
||||
i->execute2 = BxOpcodesTable[ia_opcode].execute2;
|
||||
|
||||
if (ia_opcode == BX_IA_MOV32_GdEd) {
|
||||
if (seg == BX_SEG_REG_SS)
|
||||
i->execute = &BX_CPU_C::MOV32S_GdEdM;
|
||||
}
|
||||
if (ia_opcode == BX_IA_MOV32_EdGd) {
|
||||
if (seg == BX_SEG_REG_SS)
|
||||
i->execute = &BX_CPU_C::MOV32S_EdGdM;
|
||||
}
|
||||
}
|
||||
else {
|
||||
i->execute = BxOpcodesTable[ia_opcode].execute2;
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2011 The Bochs Project
|
||||
// Copyright (C) 2001-2012 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -2362,6 +2362,15 @@ modrm_done:
|
||||
if (mod_mem) {
|
||||
i->execute = BxOpcodesTable[ia_opcode].execute1;
|
||||
i->execute2 = BxOpcodesTable[ia_opcode].execute2;
|
||||
|
||||
if (ia_opcode == BX_IA_MOV_GqEq) {
|
||||
if (seg == BX_SEG_REG_SS)
|
||||
i->execute = &BX_CPU_C::MOV64S_GqEqM;
|
||||
}
|
||||
if (ia_opcode == BX_IA_MOV32_EdGd) {
|
||||
if (seg == BX_SEG_REG_SS)
|
||||
i->execute = &BX_CPU_C::MOV64S_EqGqM;
|
||||
}
|
||||
}
|
||||
else {
|
||||
i->execute = BxOpcodesTable[ia_opcode].execute2;
|
||||
|
@ -1060,11 +1060,16 @@ void BX_CPU_C::reset(unsigned source)
|
||||
|
||||
TLB_flush();
|
||||
|
||||
// invalidate the prefetch queue
|
||||
// invalidate the code prefetch queue
|
||||
BX_CPU_THIS_PTR eipPageBias = 0;
|
||||
BX_CPU_THIS_PTR eipPageWindowSize = 0;
|
||||
BX_CPU_THIS_PTR eipFetchPtr = NULL;
|
||||
|
||||
// invalidate current stack page
|
||||
BX_CPU_THIS_PTR espPageBias = 0;
|
||||
BX_CPU_THIS_PTR espPageWindowSize = 0;
|
||||
BX_CPU_THIS_PTR espHostPtr = NULL;
|
||||
|
||||
handleCpuModeChange();
|
||||
|
||||
#if BX_DEBUGGER
|
||||
|
@ -124,9 +124,9 @@ BX_CPU_C::iret_protected(bxInstruction_c *i)
|
||||
temp_ESP = SP;
|
||||
|
||||
if (i->os32L()) {
|
||||
new_eflags = read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP + 8);
|
||||
raw_cs_selector = (Bit16u) read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP + 4);
|
||||
new_eip = read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP + 0);
|
||||
new_eflags = stack_read_dword(temp_ESP + 8);
|
||||
raw_cs_selector = (Bit16u) stack_read_dword(temp_ESP + 4);
|
||||
new_eip = stack_read_dword(temp_ESP + 0);
|
||||
|
||||
// if VM=1 in flags image on stack then STACK_RETURN_TO_V86
|
||||
if (new_eflags & EFlagsVMMask) {
|
||||
@ -138,9 +138,9 @@ BX_CPU_C::iret_protected(bxInstruction_c *i)
|
||||
}
|
||||
}
|
||||
else {
|
||||
new_flags = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 4);
|
||||
raw_cs_selector = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 2);
|
||||
new_ip = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 0);
|
||||
new_flags = stack_read_word(temp_ESP + 4);
|
||||
raw_cs_selector = stack_read_word(temp_ESP + 2);
|
||||
new_ip = stack_read_word(temp_ESP + 0);
|
||||
}
|
||||
|
||||
parse_selector(raw_cs_selector, &cs_selector);
|
||||
@ -216,10 +216,10 @@ BX_CPU_C::iret_protected(bxInstruction_c *i)
|
||||
|
||||
/* examine return SS selector and associated descriptor */
|
||||
if (i->os32L()) {
|
||||
raw_ss_selector = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 16);
|
||||
raw_ss_selector = stack_read_word(temp_ESP + 16);
|
||||
}
|
||||
else {
|
||||
raw_ss_selector = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 8);
|
||||
raw_ss_selector = stack_read_word(temp_ESP + 8);
|
||||
}
|
||||
|
||||
/* selector must be non-null, else #GP(0) */
|
||||
@ -267,14 +267,14 @@ BX_CPU_C::iret_protected(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
if (i->os32L()) {
|
||||
new_esp = read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP + 12);
|
||||
new_eflags = read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP + 8);
|
||||
new_eip = read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP + 0);
|
||||
new_esp = stack_read_dword(temp_ESP + 12);
|
||||
new_eflags = stack_read_dword(temp_ESP + 8);
|
||||
new_eip = stack_read_dword(temp_ESP + 0);
|
||||
}
|
||||
else {
|
||||
new_esp = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 6);
|
||||
new_eflags = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 4);
|
||||
new_eip = read_virtual_word_32(BX_SEG_REG_SS, temp_ESP + 0);
|
||||
new_esp = stack_read_word(temp_ESP + 6);
|
||||
new_eflags = stack_read_word(temp_ESP + 4);
|
||||
new_eip = stack_read_word(temp_ESP + 0);
|
||||
}
|
||||
|
||||
// ID,VIP,VIF,AC,VM,RF,x,NT,IOPL,OF,DF,IF,TF,SF,ZF,x,AF,x,PF,x,CF
|
||||
@ -351,23 +351,23 @@ BX_CPU_C::long_iret(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->os64L()) {
|
||||
new_eflags = (Bit32u) read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP + 16);
|
||||
raw_cs_selector = (Bit16u) read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP + 8);
|
||||
new_rip = read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP + 0);
|
||||
new_eflags = (Bit32u) stack_read_qword(temp_RSP + 16);
|
||||
raw_cs_selector = (Bit16u) stack_read_qword(temp_RSP + 8);
|
||||
new_rip = stack_read_qword(temp_RSP + 0);
|
||||
top_nbytes_same = 24;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (i->os32L()) {
|
||||
new_eflags = read_virtual_dword(BX_SEG_REG_SS, temp_RSP + 8);
|
||||
raw_cs_selector = (Bit16u) read_virtual_dword(BX_SEG_REG_SS, temp_RSP + 4);
|
||||
new_rip = (Bit64u) read_virtual_dword(BX_SEG_REG_SS, temp_RSP + 0);
|
||||
new_eflags = stack_read_dword(temp_RSP + 8);
|
||||
raw_cs_selector = (Bit16u) stack_read_dword(temp_RSP + 4);
|
||||
new_rip = (Bit64u) stack_read_dword(temp_RSP + 0);
|
||||
top_nbytes_same = 12;
|
||||
}
|
||||
else {
|
||||
new_eflags = read_virtual_word(BX_SEG_REG_SS, temp_RSP + 4);
|
||||
raw_cs_selector = read_virtual_word(BX_SEG_REG_SS, temp_RSP + 2);
|
||||
new_rip = (Bit64u) read_virtual_word(BX_SEG_REG_SS, temp_RSP + 0);
|
||||
new_eflags = stack_read_word(temp_RSP + 4);
|
||||
raw_cs_selector = stack_read_word(temp_RSP + 2);
|
||||
new_rip = (Bit64u) stack_read_word(temp_RSP + 0);
|
||||
top_nbytes_same = 6;
|
||||
}
|
||||
|
||||
@ -446,19 +446,19 @@ BX_CPU_C::long_iret(bxInstruction_c *i)
|
||||
/* examine return SS selector and associated descriptor */
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->os64L()) {
|
||||
raw_ss_selector = (Bit16u) read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP + 32);
|
||||
new_rsp = read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP + 24);
|
||||
raw_ss_selector = (Bit16u) stack_read_qword(temp_RSP + 32);
|
||||
new_rsp = stack_read_qword(temp_RSP + 24);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (i->os32L()) {
|
||||
raw_ss_selector = (Bit16u) read_virtual_dword(BX_SEG_REG_SS, temp_RSP + 16);
|
||||
new_rsp = (Bit64u) read_virtual_dword(BX_SEG_REG_SS, temp_RSP + 12);
|
||||
raw_ss_selector = (Bit16u) stack_read_dword(temp_RSP + 16);
|
||||
new_rsp = (Bit64u) stack_read_dword(temp_RSP + 12);
|
||||
}
|
||||
else {
|
||||
raw_ss_selector = read_virtual_word(BX_SEG_REG_SS, temp_RSP + 8);
|
||||
new_rsp = (Bit64u) read_virtual_word(BX_SEG_REG_SS, temp_RSP + 6);
|
||||
raw_ss_selector = stack_read_word(temp_RSP + 8);
|
||||
new_rsp = (Bit64u) stack_read_word(temp_RSP + 6);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,6 +374,8 @@ void BX_CPU_C::TLB_flush(void)
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
invalidate_stack_cache();
|
||||
|
||||
for (unsigned n=0; n<BX_TLB_SIZE; n++) {
|
||||
BX_CPU_THIS_PTR TLB.entry[n].lpf = BX_INVALID_TLB_ENTRY;
|
||||
BX_CPU_THIS_PTR TLB.entry[n].accessBits = 0;
|
||||
@ -399,6 +401,8 @@ void BX_CPU_C::TLB_flushNonGlobal(void)
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
invalidate_stack_cache();
|
||||
|
||||
BX_CPU_THIS_PTR TLB.split_large = 0;
|
||||
Bit32u lpf_mask = 0;
|
||||
|
||||
@ -428,6 +432,8 @@ void BX_CPU_C::TLB_invlpg(bx_address laddr)
|
||||
{
|
||||
invalidate_prefetch_q();
|
||||
|
||||
invalidate_stack_cache();
|
||||
|
||||
BX_DEBUG(("TLB_invlpg(0x"FMT_ADDRX"): invalidate TLB entry", laddr));
|
||||
|
||||
#if BX_CPU_LEVEL >= 5
|
||||
|
@ -442,6 +442,26 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::BxNoAVX(bxInstruction_c *i)
|
||||
|
||||
#endif
|
||||
|
||||
void BX_CPU_C::handleCpuContextChange(void)
|
||||
{
|
||||
TLB_flush();
|
||||
|
||||
#if BX_SUPPORT_MONITOR_MWAIT
|
||||
BX_CPU_THIS_PTR monitor.reset_monitor();
|
||||
#endif
|
||||
|
||||
invalidate_prefetch_q();
|
||||
invalidate_stack_cache();
|
||||
#if BX_SUPPORT_ALIGNMENT_CHECK
|
||||
handleAlignmentCheck();
|
||||
#endif
|
||||
handleCpuModeChange();
|
||||
handleSseModeChange();
|
||||
#if BX_SUPPORT_AVX
|
||||
handleAvxModeChange();
|
||||
#endif
|
||||
}
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RDPMC(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_CPU_LEVEL >= 5
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2005-2009 Stanislav Shwartsman
|
||||
// Copyright (c) 2005-2012 Stanislav Shwartsman
|
||||
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
@ -56,20 +56,20 @@ BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes)
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->os64L()) {
|
||||
raw_cs_selector = (Bit16u) read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP + 8);
|
||||
return_RIP = read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP);
|
||||
raw_cs_selector = (Bit16u) stack_read_qword(temp_RSP + 8);
|
||||
return_RIP = stack_read_qword(temp_RSP);
|
||||
stack_param_offset = 16;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (i->os32L()) {
|
||||
raw_cs_selector = (Bit16u) read_virtual_dword(BX_SEG_REG_SS, temp_RSP + 4);
|
||||
return_RIP = read_virtual_dword(BX_SEG_REG_SS, temp_RSP);
|
||||
raw_cs_selector = (Bit16u) stack_read_dword(temp_RSP + 4);
|
||||
return_RIP = stack_read_dword(temp_RSP);
|
||||
stack_param_offset = 8;
|
||||
}
|
||||
else {
|
||||
raw_cs_selector = read_virtual_word(BX_SEG_REG_SS, temp_RSP + 2);
|
||||
return_RIP = read_virtual_word(BX_SEG_REG_SS, temp_RSP);
|
||||
raw_cs_selector = stack_read_word(temp_RSP + 2);
|
||||
return_RIP = stack_read_word(temp_RSP);
|
||||
stack_param_offset = 4;
|
||||
}
|
||||
|
||||
@ -132,18 +132,18 @@ BX_CPU_C::return_protected(bxInstruction_c *i, Bit16u pop_bytes)
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (i->os64L()) {
|
||||
raw_ss_selector = read_virtual_word_64(BX_SEG_REG_SS, temp_RSP + 24 + pop_bytes);
|
||||
return_RSP = read_virtual_qword_64(BX_SEG_REG_SS, temp_RSP + 16 + pop_bytes);
|
||||
raw_ss_selector = stack_read_word(temp_RSP + 24 + pop_bytes);
|
||||
return_RSP = stack_read_qword(temp_RSP + 16 + pop_bytes);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (i->os32L()) {
|
||||
raw_ss_selector = read_virtual_word(BX_SEG_REG_SS, temp_RSP + 12 + pop_bytes);
|
||||
return_RSP = read_virtual_dword(BX_SEG_REG_SS, temp_RSP + 8 + pop_bytes);
|
||||
raw_ss_selector = stack_read_word(temp_RSP + 12 + pop_bytes);
|
||||
return_RSP = stack_read_dword(temp_RSP + 8 + pop_bytes);
|
||||
}
|
||||
else {
|
||||
raw_ss_selector = read_virtual_word(BX_SEG_REG_SS, temp_RSP + 6 + pop_bytes);
|
||||
return_RSP = read_virtual_word(BX_SEG_REG_SS, temp_RSP + 4 + pop_bytes);
|
||||
raw_ss_selector = stack_read_word(temp_RSP + 6 + pop_bytes);
|
||||
return_RSP = stack_read_word(temp_RSP + 4 + pop_bytes);
|
||||
}
|
||||
|
||||
/* selector index must be within its descriptor table limits,
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2009 The Bochs Project
|
||||
// Copyright (C) 2001-2012 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -91,6 +91,8 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache = descriptor;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1;
|
||||
|
||||
invalidate_stack_cache();
|
||||
|
||||
return;
|
||||
}
|
||||
else if ((seg==&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS]) ||
|
||||
@ -201,6 +203,9 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
handleAlignmentCheck(/* CPL change */);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (seg == &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS])
|
||||
invalidate_stack_cache();
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(2)
|
||||
@ -227,6 +232,8 @@ BX_CPU_C::load_null_selector(bx_segment_reg_t *seg, unsigned value)
|
||||
#if BX_SUPPORT_X86_64
|
||||
seg->cache.u.segment.l = 0;
|
||||
#endif
|
||||
|
||||
invalidate_stack_cache();
|
||||
}
|
||||
|
||||
BX_CPP_INLINE void BX_CPU_C::validate_seg_reg(unsigned seg)
|
||||
@ -526,6 +533,8 @@ BX_CPU_C::load_ss(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache = *descriptor;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = cpl;
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1;
|
||||
|
||||
invalidate_stack_cache();
|
||||
}
|
||||
|
||||
void BX_CPU_C::fetch_raw_descriptor(const bx_selector_t *selector,
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2006-2011 Stanislav Shwartsman
|
||||
// Copyright (c) 2006-2012 Stanislav Shwartsman
|
||||
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
@ -81,8 +81,6 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RSM(bxInstruction_c *i)
|
||||
}
|
||||
#endif
|
||||
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INFO(("RSM: Resuming from System Management Mode"));
|
||||
|
||||
BX_CPU_THIS_PTR disable_NMI = 0;
|
||||
@ -113,8 +111,6 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RSM(bxInstruction_c *i)
|
||||
|
||||
void BX_CPU_C::enter_system_management_mode(void)
|
||||
{
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INFO(("Enter to System Management Mode"));
|
||||
|
||||
// debug(BX_CPU_THIS_PTR prev_rip);
|
||||
@ -180,9 +176,6 @@ void BX_CPU_C::enter_system_management_mode(void)
|
||||
BX_CPU_THIS_PTR cr4.set32(0);
|
||||
#endif
|
||||
|
||||
// paging mode was changed - flush TLB
|
||||
TLB_flush(); // Flush Global entries also
|
||||
|
||||
#if BX_CPU_LEVEL >= 5
|
||||
BX_CPU_THIS_PTR efer.set32(0);
|
||||
#endif
|
||||
@ -205,19 +198,6 @@ void BX_CPU_C::enter_system_management_mode(void)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.l = 0; /* 16bit default size */
|
||||
#endif
|
||||
|
||||
handleCpuModeChange();
|
||||
|
||||
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
|
||||
handleAlignmentCheck();
|
||||
#endif
|
||||
|
||||
#if BX_CPU_LEVEL >= 6
|
||||
handleSseModeChange();
|
||||
#if BX_SUPPORT_AVX
|
||||
handleAvxModeChange();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* DS (Data Segment) and descriptor cache */
|
||||
parse_selector(0x0000,
|
||||
&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector);
|
||||
@ -243,6 +223,8 @@ void BX_CPU_C::enter_system_management_mode(void)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS] = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS];
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS] = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS];
|
||||
|
||||
handleCpuContextChange();
|
||||
|
||||
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_CONTEXT_SWITCH, 0);
|
||||
}
|
||||
|
||||
@ -656,13 +638,6 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
}
|
||||
}
|
||||
|
||||
handleCpuModeChange();
|
||||
|
||||
handleSseModeChange();
|
||||
#if BX_SUPPORT_AVX
|
||||
handleAvxModeChange();
|
||||
#endif
|
||||
|
||||
Bit16u ar_data = SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR ldtr,
|
||||
(ar_data >> 8) & 1,
|
||||
@ -696,6 +671,8 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
|
||||
BX_CPU_THIS_PTR smbase = SMRAM_FIELD(saved_state, SMRAM_FIELD_SMBASE_OFFSET);
|
||||
|
||||
handleCpuContextChange();
|
||||
|
||||
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_CONTEXT_SWITCH, 0);
|
||||
|
||||
return 1;
|
||||
|
332
bochs/cpu/stack.cc
Executable file
332
bochs/cpu/stack.cc
Executable file
@ -0,0 +1,332 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2012 Stanislav Shwartsman
|
||||
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define NEED_CPU_REG_SHORTCUTS 1
|
||||
#include "bochs.h"
|
||||
#include "cpu.h"
|
||||
#define LOG_THIS BX_CPU_THIS_PTR
|
||||
|
||||
void BX_CPP_AttrRegparmN(2) BX_CPU_C::stackPrefetch(bx_address offset, unsigned len)
|
||||
{
|
||||
bx_address laddr;
|
||||
|
||||
BX_CPU_THIS_PTR espHostPtr = 0; // initialize with NULL pointer
|
||||
BX_CPU_THIS_PTR espPageWindowSize = 0;
|
||||
|
||||
len--;
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (long64_mode()) {
|
||||
laddr = offset;
|
||||
unsigned pageOffset = PAGE_OFFSET(offset);
|
||||
|
||||
// canonical violations will miss the TLB below
|
||||
|
||||
if (pageOffset + len >= 4096) // don't care for page split accesses
|
||||
return;
|
||||
|
||||
BX_CPU_THIS_PTR espPageBias = pageOffset - offset;
|
||||
BX_CPU_THIS_PTR espPageWindowSize = 4096;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
laddr = (Bit32u) (offset + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base);
|
||||
unsigned pageOffset = PAGE_OFFSET(laddr);
|
||||
if (pageOffset + len >= 4096) // don't care for page split accesses
|
||||
return;
|
||||
|
||||
BX_CPU_THIS_PTR espPageBias = (bx_address) pageOffset - offset;
|
||||
|
||||
Bit32u limit = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled;
|
||||
Bit32u pageStart = offset - pageOffset;
|
||||
|
||||
BX_ASSERT(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid);
|
||||
BX_ASSERT(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p);
|
||||
|
||||
// check that the begining of the page is within stack segment limits
|
||||
// problem can happen with EXPAND DOWN segments
|
||||
if (IS_DATA_SEGMENT_EXPAND_DOWN(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.type)) {
|
||||
Bit32u upper_limit;
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
|
||||
upper_limit = 0xffffffff;
|
||||
else
|
||||
upper_limit = 0x0000ffff;
|
||||
if (offset <= limit || offset > upper_limit || (upper_limit - offset) < len) {
|
||||
BX_ERROR(("stackPrefetch(%d): access [0x%08x] > SS.limit [0x%08x] ED", len+1, (Bit32u) offset, limit));
|
||||
exception(BX_SS_EXCEPTION, 0);
|
||||
}
|
||||
|
||||
// check that the begining of the page is within stack segment limits
|
||||
// handle correctly the wrap corner case for EXPAND DOWN
|
||||
Bit32u pageEnd = pageStart + 0xfff;
|
||||
if (pageStart > limit && pageStart < pageEnd) {
|
||||
BX_CPU_THIS_PTR espPageWindowSize = 4096;
|
||||
if ((upper_limit - offset) < (4096 - pageOffset))
|
||||
BX_CPU_THIS_PTR espPageWindowSize = (Bit32u)(upper_limit - offset + 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (offset > (limit - len) || len > limit) {
|
||||
BX_ERROR(("stackPrefetch(%d): access [0x%08x] > SS.limit [0x%08x]", len+1, (Bit32u) offset, limit));
|
||||
exception(BX_SS_EXCEPTION, 0);
|
||||
}
|
||||
|
||||
if (pageStart <= limit) {
|
||||
BX_CPU_THIS_PTR espPageWindowSize = 4096;
|
||||
if ((limit - offset) < (4096 - pageOffset))
|
||||
BX_CPU_THIS_PTR espPageWindowSize = (Bit32u)(limit - offset + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned tlbIndex = BX_TLB_INDEX_OF(laddr, 0);
|
||||
Bit64u lpf = LPFOf(laddr);
|
||||
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[tlbIndex];
|
||||
if (tlbEntry->lpf == lpf) {
|
||||
// See if the TLB entry privilege level allows us write access from this CPL
|
||||
// Assuming that we always can read if write access is OK
|
||||
if (! (tlbEntry->accessBits & (0x2 | USER_PL))) {
|
||||
BX_CPU_THIS_PTR pAddrStackPage = tlbEntry->ppf;
|
||||
BX_CPU_THIS_PTR espHostPtr = (Bit8u*) tlbEntry->hostPageAddr;
|
||||
}
|
||||
}
|
||||
|
||||
if (! BX_CPU_THIS_PTR espHostPtr || BX_CPU_THIS_PTR espPageWindowSize < 7)
|
||||
BX_CPU_THIS_PTR espPageWindowSize = 0;
|
||||
else
|
||||
BX_CPU_THIS_PTR espPageWindowSize -= 7;
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(2) BX_CPU_C::stack_write_byte(bx_address offset, Bit8u data)
|
||||
{
|
||||
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
|
||||
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
|
||||
stackPrefetch(offset, 1);
|
||||
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR espHostPtr) {
|
||||
Bit8u *hostPageAddr = (Bit8u*)(BX_CPU_THIS_PTR espHostPtr + espBiased);
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrStackPage + espBiased;
|
||||
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset), pAddr, 1, CPL, BX_WRITE, (Bit8u*) &data);
|
||||
pageWriteStampTable.decWriteStamp(pAddr, 1);
|
||||
*hostPageAddr = data;
|
||||
}
|
||||
else {
|
||||
write_virtual_byte(BX_SEG_REG_SS, offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(2) BX_CPU_C::stack_write_word(bx_address offset, Bit16u data)
|
||||
{
|
||||
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
|
||||
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
|
||||
stackPrefetch(offset, 2);
|
||||
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR espHostPtr) {
|
||||
Bit16u *hostPageAddr = (Bit16u*)(BX_CPU_THIS_PTR espHostPtr + espBiased);
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrStackPage + espBiased;
|
||||
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
|
||||
if (BX_CPU_THIS_PTR alignment_check() && (pAddr & 1) != 0) {
|
||||
BX_ERROR(("stack_write_word(): #AC misaligned access"));
|
||||
exception(BX_AC_EXCEPTION, 0);
|
||||
}
|
||||
#endif
|
||||
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset), pAddr, 2, CPL, BX_WRITE, (Bit8u*) &data);
|
||||
pageWriteStampTable.decWriteStamp(pAddr, 2);
|
||||
WriteHostWordToLittleEndian(hostPageAddr, data);
|
||||
}
|
||||
else {
|
||||
write_virtual_word(BX_SEG_REG_SS, offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(2) BX_CPU_C::stack_write_dword(bx_address offset, Bit32u data)
|
||||
{
|
||||
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
|
||||
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
|
||||
stackPrefetch(offset, 4);
|
||||
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR espHostPtr) {
|
||||
Bit32u *hostPageAddr = (Bit32u*)(BX_CPU_THIS_PTR espHostPtr + espBiased);
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrStackPage + espBiased;
|
||||
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
|
||||
if (BX_CPU_THIS_PTR alignment_check() && (pAddr & 3) != 0) {
|
||||
BX_ERROR(("stack_write_dword(): #AC misaligned access"));
|
||||
exception(BX_AC_EXCEPTION, 0);
|
||||
}
|
||||
#endif
|
||||
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset), pAddr, 4, CPL, BX_WRITE, (Bit8u*) &data);
|
||||
pageWriteStampTable.decWriteStamp(pAddr, 4);
|
||||
WriteHostDWordToLittleEndian(hostPageAddr, data);
|
||||
}
|
||||
else {
|
||||
write_virtual_dword(BX_SEG_REG_SS, offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(2) BX_CPU_C::stack_write_qword(bx_address offset, Bit64u data)
|
||||
{
|
||||
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
|
||||
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
|
||||
stackPrefetch(offset, 8);
|
||||
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR espHostPtr) {
|
||||
Bit64u *hostPageAddr = (Bit64u*)(BX_CPU_THIS_PTR espHostPtr + espBiased);
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrStackPage + espBiased;
|
||||
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
|
||||
if (BX_CPU_THIS_PTR alignment_check() && (pAddr & 7) != 0) {
|
||||
BX_ERROR(("stack_write_qword(): #AC misaligned access"));
|
||||
exception(BX_AC_EXCEPTION, 0);
|
||||
}
|
||||
#endif
|
||||
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset), pAddr, 8, CPL, BX_WRITE, (Bit8u*) &data);
|
||||
pageWriteStampTable.decWriteStamp(pAddr, 8);
|
||||
WriteHostQWordToLittleEndian(hostPageAddr, data);
|
||||
}
|
||||
else {
|
||||
write_virtual_qword(BX_SEG_REG_SS, offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
Bit8u BX_CPP_AttrRegparmN(1) BX_CPU_C::stack_read_byte(bx_address offset)
|
||||
{
|
||||
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
|
||||
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
|
||||
stackPrefetch(offset, 1);
|
||||
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR espHostPtr) {
|
||||
Bit8u *hostPageAddr = (Bit8u*)(BX_CPU_THIS_PTR espHostPtr + espBiased), data;
|
||||
data = *hostPageAddr;
|
||||
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset),
|
||||
(BX_CPU_THIS_PTR pAddrStackPage + espBiased), 1, CPL, BX_READ, (Bit8u*) &data);
|
||||
return data;
|
||||
}
|
||||
else {
|
||||
return read_virtual_byte(BX_SEG_REG_SS, offset);
|
||||
}
|
||||
}
|
||||
|
||||
Bit16u BX_CPP_AttrRegparmN(1) BX_CPU_C::stack_read_word(bx_address offset)
|
||||
{
|
||||
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
|
||||
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
|
||||
stackPrefetch(offset, 2);
|
||||
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR espHostPtr) {
|
||||
Bit16u *hostPageAddr = (Bit16u*)(BX_CPU_THIS_PTR espHostPtr + espBiased), data;
|
||||
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
|
||||
if (BX_CPU_THIS_PTR alignment_check()) {
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrStackPage + espBiased;
|
||||
if (pAddr & 1) {
|
||||
BX_ERROR(("stack_read_word(): #AC misaligned access"));
|
||||
exception(BX_AC_EXCEPTION, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ReadHostWordFromLittleEndian(hostPageAddr, data);
|
||||
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset),
|
||||
(BX_CPU_THIS_PTR pAddrStackPage + espBiased), 2, CPL, BX_READ, (Bit8u*) &data);
|
||||
return data;
|
||||
}
|
||||
else {
|
||||
return read_virtual_word(BX_SEG_REG_SS, offset);
|
||||
}
|
||||
}
|
||||
|
||||
Bit32u BX_CPP_AttrRegparmN(1) BX_CPU_C::stack_read_dword(bx_address offset)
|
||||
{
|
||||
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
|
||||
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
|
||||
stackPrefetch(offset, 4);
|
||||
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR espHostPtr) {
|
||||
Bit32u *hostPageAddr = (Bit32u*)(BX_CPU_THIS_PTR espHostPtr + espBiased), data;
|
||||
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
|
||||
if (BX_CPU_THIS_PTR alignment_check()) {
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrStackPage + espBiased;
|
||||
if (pAddr & 3) {
|
||||
BX_ERROR(("stack_read_dword(): #AC misaligned access"));
|
||||
exception(BX_AC_EXCEPTION, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ReadHostDWordFromLittleEndian(hostPageAddr, data);
|
||||
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset),
|
||||
(BX_CPU_THIS_PTR pAddrStackPage + espBiased), 4, CPL, BX_READ, (Bit8u*) &data);
|
||||
return data;
|
||||
}
|
||||
else {
|
||||
return read_virtual_dword(BX_SEG_REG_SS, offset);
|
||||
}
|
||||
}
|
||||
|
||||
Bit64u BX_CPP_AttrRegparmN(1) BX_CPU_C::stack_read_qword(bx_address offset)
|
||||
{
|
||||
bx_address espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
|
||||
if (espBiased >= BX_CPU_THIS_PTR espPageWindowSize) {
|
||||
stackPrefetch(offset, 8);
|
||||
espBiased = offset + BX_CPU_THIS_PTR espPageBias;
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR espHostPtr) {
|
||||
Bit64u *hostPageAddr = (Bit64u*)(BX_CPU_THIS_PTR espHostPtr + espBiased), data;
|
||||
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
|
||||
if (BX_CPU_THIS_PTR alignment_check()) {
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR pAddrStackPage + espBiased;
|
||||
if (pAddr & 7) {
|
||||
BX_ERROR(("stack_read_qword(): #AC misaligned access"));
|
||||
exception(BX_AC_EXCEPTION, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ReadHostQWordFromLittleEndian(hostPageAddr, data);
|
||||
BX_NOTIFY_LIN_MEMORY_ACCESS(get_laddr(BX_SEG_REG_SS, offset),
|
||||
(BX_CPU_THIS_PTR pAddrStackPage + espBiased), 8, CPL, BX_READ, (Bit8u*) &data);
|
||||
return data;
|
||||
}
|
||||
else {
|
||||
return read_virtual_qword(BX_SEG_REG_SS, offset);
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2007-2009 Stanislav Shwartsman
|
||||
// Copyright (c) 2007-2012 Stanislav Shwartsman
|
||||
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
@ -29,18 +29,18 @@ BX_CPU_C::push_16(Bit16u value16)
|
||||
{
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (long64_mode()) { /* StackAddrSize = 64 */
|
||||
write_virtual_word_64(BX_SEG_REG_SS, RSP-2, value16);
|
||||
stack_write_word(RSP-2, value16);
|
||||
RSP -= 2;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u) (ESP-2), value16);
|
||||
stack_write_word((Bit32u) (ESP-2), value16);
|
||||
ESP -= 2;
|
||||
}
|
||||
else /* StackAddrSize = 16 */
|
||||
{
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u) (SP-2), value16);
|
||||
stack_write_word((Bit16u) (SP-2), value16);
|
||||
SP -= 2;
|
||||
}
|
||||
}
|
||||
@ -50,18 +50,18 @@ BX_CPU_C::push_32(Bit32u value32)
|
||||
{
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (long64_mode()) { /* StackAddrSize = 64 */
|
||||
write_virtual_dword_64(BX_SEG_REG_SS, RSP-4, value32);
|
||||
stack_write_dword(RSP-4, value32);
|
||||
RSP -= 4;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (ESP-4), value32);
|
||||
stack_write_dword((Bit32u) (ESP-4), value32);
|
||||
ESP -= 4;
|
||||
}
|
||||
else /* StackAddrSize = 16 */
|
||||
{
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (SP-4), value32);
|
||||
stack_write_dword((Bit16u) (SP-4), value32);
|
||||
SP -= 4;
|
||||
}
|
||||
}
|
||||
@ -72,7 +72,7 @@ BX_CPU_C::push_32(Bit32u value32)
|
||||
BX_CPU_C::push_64(Bit64u value64)
|
||||
{
|
||||
/* StackAddrSize = 64 */
|
||||
write_virtual_qword_64(BX_SEG_REG_SS, RSP-8, value64);
|
||||
stack_write_qword(RSP-8, value64);
|
||||
RSP -= 8;
|
||||
}
|
||||
#endif
|
||||
@ -84,17 +84,17 @@ BX_CPP_INLINE Bit16u BX_CPU_C::pop_16(void)
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (long64_mode()) { /* StackAddrSize = 64 */
|
||||
value16 = read_virtual_word_64(BX_SEG_REG_SS, RSP);
|
||||
value16 = stack_read_word(RSP);
|
||||
RSP += 2;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
|
||||
value16 = read_virtual_word_32(BX_SEG_REG_SS, ESP);
|
||||
value16 = stack_read_word(ESP);
|
||||
ESP += 2;
|
||||
}
|
||||
else { /* StackAddrSize = 16 */
|
||||
value16 = read_virtual_word_32(BX_SEG_REG_SS, SP);
|
||||
value16 = stack_read_word(SP);
|
||||
SP += 2;
|
||||
}
|
||||
|
||||
@ -108,17 +108,17 @@ BX_CPP_INLINE Bit32u BX_CPU_C::pop_32(void)
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
if (long64_mode()) { /* StackAddrSize = 64 */
|
||||
value32 = read_virtual_dword_64(BX_SEG_REG_SS, RSP);
|
||||
value32 = stack_read_dword(RSP);
|
||||
RSP += 4;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
|
||||
value32 = read_virtual_dword_32(BX_SEG_REG_SS, ESP);
|
||||
value32 = stack_read_dword(ESP);
|
||||
ESP += 4;
|
||||
}
|
||||
else { /* StackAddrSize = 16 */
|
||||
value32 = read_virtual_dword_32(BX_SEG_REG_SS, SP);
|
||||
value32 = stack_read_dword(SP);
|
||||
SP += 4;
|
||||
}
|
||||
|
||||
@ -130,7 +130,7 @@ BX_CPP_INLINE Bit32u BX_CPU_C::pop_32(void)
|
||||
BX_CPP_INLINE Bit64u BX_CPU_C::pop_64(void)
|
||||
{
|
||||
/* StackAddrSize = 64 */
|
||||
Bit64u value64 = read_virtual_qword_64(BX_SEG_REG_SS, RSP);
|
||||
Bit64u value64 = stack_read_qword(RSP);
|
||||
RSP += 8;
|
||||
|
||||
return value64;
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2011 The Bochs Project
|
||||
// Copyright (C) 2001-2012 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -108,26 +108,26 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSHAD16(bxInstruction_c *i)
|
||||
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
|
||||
{
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 2), AX);
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 4), CX);
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 6), DX);
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 8), BX);
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 10), temp_SP);
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 12), BP);
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 14), SI);
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP - 16), DI);
|
||||
stack_write_word((Bit32u)(temp_ESP - 2), AX);
|
||||
stack_write_word((Bit32u)(temp_ESP - 4), CX);
|
||||
stack_write_word((Bit32u)(temp_ESP - 6), DX);
|
||||
stack_write_word((Bit32u)(temp_ESP - 8), BX);
|
||||
stack_write_word((Bit32u)(temp_ESP - 10), temp_SP);
|
||||
stack_write_word((Bit32u)(temp_ESP - 12), BP);
|
||||
stack_write_word((Bit32u)(temp_ESP - 14), SI);
|
||||
stack_write_word((Bit32u)(temp_ESP - 16), DI);
|
||||
ESP -= 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 2), AX);
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 4), CX);
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 6), DX);
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 8), BX);
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 10), temp_SP);
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 12), BP);
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 14), SI);
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP - 16), DI);
|
||||
stack_write_word((Bit16u)(temp_SP - 2), AX);
|
||||
stack_write_word((Bit16u)(temp_SP - 4), CX);
|
||||
stack_write_word((Bit16u)(temp_SP - 6), DX);
|
||||
stack_write_word((Bit16u)(temp_SP - 8), BX);
|
||||
stack_write_word((Bit16u)(temp_SP - 10), temp_SP);
|
||||
stack_write_word((Bit16u)(temp_SP - 12), BP);
|
||||
stack_write_word((Bit16u)(temp_SP - 14), SI);
|
||||
stack_write_word((Bit16u)(temp_SP - 16), DI);
|
||||
SP -= 16;
|
||||
}
|
||||
|
||||
@ -141,27 +141,27 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POPAD16(bxInstruction_c *i)
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
|
||||
{
|
||||
Bit32u temp_ESP = ESP;
|
||||
di = read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 0));
|
||||
si = read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 2));
|
||||
bp = read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 4));
|
||||
read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 6));
|
||||
bx = read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 8));
|
||||
dx = read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 10));
|
||||
cx = read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 12));
|
||||
ax = read_virtual_word_32(BX_SEG_REG_SS, (Bit32u)(temp_ESP + 14));
|
||||
di = stack_read_word((Bit32u)(temp_ESP + 0));
|
||||
si = stack_read_word((Bit32u)(temp_ESP + 2));
|
||||
bp = stack_read_word((Bit32u)(temp_ESP + 4));
|
||||
stack_read_word((Bit32u)(temp_ESP + 6));
|
||||
bx = stack_read_word((Bit32u)(temp_ESP + 8));
|
||||
dx = stack_read_word((Bit32u)(temp_ESP + 10));
|
||||
cx = stack_read_word((Bit32u)(temp_ESP + 12));
|
||||
ax = stack_read_word((Bit32u)(temp_ESP + 14));
|
||||
ESP += 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
Bit16u temp_SP = SP;
|
||||
di = read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 0));
|
||||
si = read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 2));
|
||||
bp = read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 4));
|
||||
read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 6));
|
||||
bx = read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 8));
|
||||
dx = read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 10));
|
||||
cx = read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 12));
|
||||
ax = read_virtual_word_32(BX_SEG_REG_SS, (Bit16u)(temp_SP + 14));
|
||||
di = stack_read_word((Bit16u)(temp_SP + 0));
|
||||
si = stack_read_word((Bit16u)(temp_SP + 2));
|
||||
bp = stack_read_word((Bit16u)(temp_SP + 4));
|
||||
stack_read_word((Bit16u)(temp_SP + 6));
|
||||
bx = stack_read_word((Bit16u)(temp_SP + 8));
|
||||
dx = stack_read_word((Bit16u)(temp_SP + 10));
|
||||
cx = stack_read_word((Bit16u)(temp_SP + 12));
|
||||
ax = stack_read_word((Bit16u)(temp_SP + 14));
|
||||
SP += 16;
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER16_IwIb(bxInstruction_c *i)
|
||||
/* do level-1 times */
|
||||
while (--level) {
|
||||
ebp -= 2;
|
||||
Bit16u temp16 = read_virtual_word_32(BX_SEG_REG_SS, ebp);
|
||||
Bit16u temp16 = stack_read_word(ebp);
|
||||
push_16(temp16);
|
||||
}
|
||||
|
||||
@ -218,7 +218,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER16_IwIb(bxInstruction_c *i)
|
||||
/* do level-1 times */
|
||||
while (--level) {
|
||||
bp -= 2;
|
||||
Bit16u temp16 = read_virtual_word_32(BX_SEG_REG_SS, bp);
|
||||
Bit16u temp16 = stack_read_word(bp);
|
||||
push_16(temp16);
|
||||
}
|
||||
|
||||
@ -248,11 +248,11 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LEAVE16(bxInstruction_c *i)
|
||||
Bit16u value16;
|
||||
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
|
||||
value16 = read_virtual_word_32(BX_SEG_REG_SS, EBP);
|
||||
value16 = stack_read_word(EBP);
|
||||
ESP = EBP + 2;
|
||||
}
|
||||
else {
|
||||
value16 = read_virtual_word_32(BX_SEG_REG_SS, BP);
|
||||
value16 = stack_read_word(BP);
|
||||
SP = BP + 2;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2011 The Bochs Project
|
||||
// Copyright (C) 2001-2012 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -61,12 +61,12 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSH32_Sw(bxInstruction_c *i)
|
||||
Bit16u val_16 = BX_CPU_THIS_PTR sregs[i->nnn()].selector.value;
|
||||
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit32u) (ESP-4), val_16);
|
||||
stack_write_word((Bit32u) (ESP-4), val_16);
|
||||
ESP -= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_virtual_word_32(BX_SEG_REG_SS, (Bit16u) (SP-4), val_16);
|
||||
stack_write_word((Bit16u) (SP-4), val_16);
|
||||
SP -= 4;
|
||||
}
|
||||
|
||||
@ -78,12 +78,12 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POP32_Sw(bxInstruction_c *i)
|
||||
Bit16u selector;
|
||||
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
|
||||
selector = read_virtual_word_32(BX_SEG_REG_SS, ESP);
|
||||
selector = stack_read_word(ESP);
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[i->nnn()], selector);
|
||||
ESP += 4;
|
||||
}
|
||||
else {
|
||||
selector = read_virtual_word_32(BX_SEG_REG_SS, SP);
|
||||
selector = stack_read_word(SP);
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[i->nnn()], selector);
|
||||
SP += 4;
|
||||
}
|
||||
@ -124,26 +124,26 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSHAD32(bxInstruction_c *i)
|
||||
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
|
||||
{
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 4), EAX);
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 8), ECX);
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 12), EDX);
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 16), EBX);
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 20), temp_ESP);
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 24), EBP);
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 28), ESI);
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP - 32), EDI);
|
||||
stack_write_dword((Bit32u) (temp_ESP - 4), EAX);
|
||||
stack_write_dword((Bit32u) (temp_ESP - 8), ECX);
|
||||
stack_write_dword((Bit32u) (temp_ESP - 12), EDX);
|
||||
stack_write_dword((Bit32u) (temp_ESP - 16), EBX);
|
||||
stack_write_dword((Bit32u) (temp_ESP - 20), temp_ESP);
|
||||
stack_write_dword((Bit32u) (temp_ESP - 24), EBP);
|
||||
stack_write_dword((Bit32u) (temp_ESP - 28), ESI);
|
||||
stack_write_dword((Bit32u) (temp_ESP - 32), EDI);
|
||||
ESP -= 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 4), EAX);
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 8), ECX);
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 12), EDX);
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 16), EBX);
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 20), temp_ESP);
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 24), EBP);
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 28), ESI);
|
||||
write_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP - 32), EDI);
|
||||
stack_write_dword((Bit16u) (temp_SP - 4), EAX);
|
||||
stack_write_dword((Bit16u) (temp_SP - 8), ECX);
|
||||
stack_write_dword((Bit16u) (temp_SP - 12), EDX);
|
||||
stack_write_dword((Bit16u) (temp_SP - 16), EBX);
|
||||
stack_write_dword((Bit16u) (temp_SP - 20), temp_ESP);
|
||||
stack_write_dword((Bit16u) (temp_SP - 24), EBP);
|
||||
stack_write_dword((Bit16u) (temp_SP - 28), ESI);
|
||||
stack_write_dword((Bit16u) (temp_SP - 32), EDI);
|
||||
SP -= 32;
|
||||
}
|
||||
|
||||
@ -157,27 +157,27 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POPAD32(bxInstruction_c *i)
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
|
||||
{
|
||||
Bit32u temp_ESP = ESP;
|
||||
edi = read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 0));
|
||||
esi = read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 4));
|
||||
ebp = read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 8));
|
||||
read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 12));
|
||||
ebx = read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 16));
|
||||
edx = read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 20));
|
||||
ecx = read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 24));
|
||||
eax = read_virtual_dword_32(BX_SEG_REG_SS, (Bit32u) (temp_ESP + 28));
|
||||
edi = stack_read_dword((Bit32u) (temp_ESP + 0));
|
||||
esi = stack_read_dword((Bit32u) (temp_ESP + 4));
|
||||
ebp = stack_read_dword((Bit32u) (temp_ESP + 8));
|
||||
stack_read_dword((Bit32u) (temp_ESP + 12));
|
||||
ebx = stack_read_dword((Bit32u) (temp_ESP + 16));
|
||||
edx = stack_read_dword((Bit32u) (temp_ESP + 20));
|
||||
ecx = stack_read_dword((Bit32u) (temp_ESP + 24));
|
||||
eax = stack_read_dword((Bit32u) (temp_ESP + 28));
|
||||
ESP += 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
Bit16u temp_SP = SP;
|
||||
edi = read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 0));
|
||||
esi = read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 4));
|
||||
ebp = read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 8));
|
||||
read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 12));
|
||||
ebx = read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 16));
|
||||
edx = read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 20));
|
||||
ecx = read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 24));
|
||||
eax = read_virtual_dword_32(BX_SEG_REG_SS, (Bit16u) (temp_SP + 28));
|
||||
edi = stack_read_dword((Bit16u) (temp_SP + 0));
|
||||
esi = stack_read_dword((Bit16u) (temp_SP + 4));
|
||||
ebp = stack_read_dword((Bit16u) (temp_SP + 8));
|
||||
stack_read_dword((Bit16u) (temp_SP + 12));
|
||||
ebx = stack_read_dword((Bit16u) (temp_SP + 16));
|
||||
edx = stack_read_dword((Bit16u) (temp_SP + 20));
|
||||
ecx = stack_read_dword((Bit16u) (temp_SP + 24));
|
||||
eax = stack_read_dword((Bit16u) (temp_SP + 28));
|
||||
SP += 32;
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER32_IwIb(bxInstruction_c *i)
|
||||
/* do level-1 times */
|
||||
while (--level) {
|
||||
ebp -= 4;
|
||||
Bit32u temp32 = read_virtual_dword_32(BX_SEG_REG_SS, ebp);
|
||||
Bit32u temp32 = stack_read_dword(ebp);
|
||||
push_32(temp32);
|
||||
}
|
||||
|
||||
@ -232,7 +232,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER32_IwIb(bxInstruction_c *i)
|
||||
/* do level-1 times */
|
||||
while (--level) {
|
||||
bp -= 4;
|
||||
Bit32u temp32 = read_virtual_dword_32(BX_SEG_REG_SS, bp);
|
||||
Bit32u temp32 = stack_read_dword(bp);
|
||||
push_32(temp32);
|
||||
}
|
||||
|
||||
@ -262,11 +262,11 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LEAVE32(bxInstruction_c *i)
|
||||
Bit32u value32;
|
||||
|
||||
if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
|
||||
value32 = read_virtual_dword_32(BX_SEG_REG_SS, EBP);
|
||||
value32 = stack_read_dword(EBP);
|
||||
ESP = EBP + 4;
|
||||
}
|
||||
else {
|
||||
value32 = read_virtual_dword_32(BX_SEG_REG_SS, BP);
|
||||
value32 = stack_read_dword(BP);
|
||||
SP = BP + 4;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2011 The Bochs Project
|
||||
// Copyright (C) 2001-2012 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -67,7 +67,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSH64_Sw(bxInstruction_c *i)
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POP64_Sw(bxInstruction_c *i)
|
||||
{
|
||||
Bit16u selector = read_virtual_word_64(BX_SEG_REG_SS, RSP);
|
||||
Bit16u selector = stack_read_word(RSP);
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[i->nnn()], selector);
|
||||
RSP += 8;
|
||||
|
||||
@ -101,7 +101,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER64_IwIb(bxInstruction_c *i)
|
||||
Bit64u temp_RSP = RSP, temp_RBP = RBP;
|
||||
|
||||
temp_RSP -= 8;
|
||||
write_virtual_qword_64(BX_SEG_REG_SS, temp_RSP, temp_RBP);
|
||||
stack_write_qword(temp_RSP, temp_RBP);
|
||||
|
||||
Bit64u frame_ptr64 = temp_RSP;
|
||||
|
||||
@ -109,14 +109,14 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER64_IwIb(bxInstruction_c *i)
|
||||
/* do level-1 times */
|
||||
while (--level) {
|
||||
temp_RBP -= 8;
|
||||
Bit64u temp64 = read_virtual_qword_64(BX_SEG_REG_SS, temp_RBP);
|
||||
Bit64u temp64 = stack_read_qword(temp_RBP);
|
||||
temp_RSP -= 8;
|
||||
write_virtual_qword_64(BX_SEG_REG_SS, temp_RSP, temp64);
|
||||
stack_write_qword(temp_RSP, temp64);
|
||||
} /* while (--level) */
|
||||
|
||||
/* push(frame pointer) */
|
||||
temp_RSP -= 8;
|
||||
write_virtual_qword_64(BX_SEG_REG_SS, temp_RSP, frame_ptr64);
|
||||
stack_write_qword(temp_RSP, frame_ptr64);
|
||||
} /* if (level > 0) ... */
|
||||
|
||||
temp_RSP -= i->Iw();
|
||||
@ -135,7 +135,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::ENTER64_IwIb(bxInstruction_c *i)
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LEAVE64(bxInstruction_c *i)
|
||||
{
|
||||
// restore frame pointer
|
||||
Bit64u temp64 = read_virtual_qword_64(BX_SEG_REG_SS, RBP);
|
||||
Bit64u temp64 = stack_read_qword(RBP);
|
||||
RSP = RBP + 8;
|
||||
RBP = temp64;
|
||||
|
||||
|
@ -255,21 +255,7 @@ void BX_CPU_C::SvmExitLoadHostState(SVM_HOST_STATE *host)
|
||||
|
||||
CPL = 0;
|
||||
|
||||
TLB_flush(); // CR0/CR4 updated
|
||||
|
||||
#if BX_SUPPORT_MONITOR_MWAIT
|
||||
BX_CPU_THIS_PTR monitor.reset_monitor();
|
||||
#endif
|
||||
|
||||
invalidate_prefetch_q();
|
||||
#if BX_SUPPORT_ALIGNMENT_CHECK
|
||||
handleAlignmentCheck();
|
||||
#endif
|
||||
handleCpuModeChange();
|
||||
handleSseModeChange();
|
||||
#if BX_SUPPORT_AVX
|
||||
handleAvxModeChange();
|
||||
#endif
|
||||
handleCpuContextChange();
|
||||
|
||||
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_CONTEXT_SWITCH, 0);
|
||||
}
|
||||
@ -567,19 +553,7 @@ bx_bool BX_CPU_C::SvmEnterLoadCheckGuestState(void)
|
||||
if (SVM_V_IRQ)
|
||||
BX_CPU_THIS_PTR async_event = 1;
|
||||
|
||||
#if BX_SUPPORT_MONITOR_MWAIT
|
||||
BX_CPU_THIS_PTR monitor.reset_monitor();
|
||||
#endif
|
||||
|
||||
invalidate_prefetch_q();
|
||||
#if BX_SUPPORT_ALIGNMENT_CHECK
|
||||
handleAlignmentCheck();
|
||||
#endif
|
||||
handleCpuModeChange();
|
||||
handleSseModeChange();
|
||||
#if BX_SUPPORT_AVX
|
||||
handleAvxModeChange();
|
||||
#endif
|
||||
handleCpuContextChange();
|
||||
|
||||
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_CONTEXT_SWITCH, 0);
|
||||
|
||||
|
@ -591,6 +591,8 @@ void BX_CPU_C::task_switch(bxInstruction_c *i, bx_selector_t *tss_selector,
|
||||
|
||||
// All checks pass, fill in shadow cache
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache = ss_descriptor;
|
||||
|
||||
invalidate_stack_cache();
|
||||
}
|
||||
else {
|
||||
// SS selector is valid, else #TS(new stack segment)
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2009 The Bochs Project
|
||||
// Copyright (C) 2001-2012 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -67,14 +67,14 @@ void BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector, Bit32
|
||||
temp_ESP = SP;
|
||||
|
||||
// load SS:ESP from stack
|
||||
new_esp = read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP+12);
|
||||
raw_ss_selector = (Bit16u) read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP+16);
|
||||
new_esp = stack_read_dword(temp_ESP+12);
|
||||
raw_ss_selector = (Bit16u) stack_read_dword(temp_ESP+16);
|
||||
|
||||
// load ES,DS,FS,GS from stack
|
||||
raw_es_selector = (Bit16u) read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP+20);
|
||||
raw_ds_selector = (Bit16u) read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP+24);
|
||||
raw_fs_selector = (Bit16u) read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP+28);
|
||||
raw_gs_selector = (Bit16u) read_virtual_dword_32(BX_SEG_REG_SS, temp_ESP+32);
|
||||
raw_es_selector = (Bit16u) stack_read_dword(temp_ESP+20);
|
||||
raw_ds_selector = (Bit16u) stack_read_dword(temp_ESP+24);
|
||||
raw_fs_selector = (Bit16u) stack_read_dword(temp_ESP+28);
|
||||
raw_gs_selector = (Bit16u) stack_read_dword(temp_ESP+32);
|
||||
|
||||
writeEFlags(flags32, EFlagsValidMask);
|
||||
|
||||
@ -258,6 +258,8 @@ void BX_CPU_C::init_v8086_mode(void)
|
||||
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
|
||||
handleAlignmentCheck(/* CPL change */);
|
||||
#endif
|
||||
|
||||
invalidate_stack_cache();
|
||||
}
|
||||
|
||||
#endif /* BX_CPU_LEVEL >= 3 */
|
||||
|
@ -1631,19 +1631,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
|
||||
BX_CPU_THIS_PTR vmx_interrupt_window = 1; // set up interrupt window exiting
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_MONITOR_MWAIT
|
||||
BX_CPU_THIS_PTR monitor.reset_monitor();
|
||||
#endif
|
||||
|
||||
invalidate_prefetch_q();
|
||||
#if BX_SUPPORT_ALIGNMENT_CHECK
|
||||
handleAlignmentCheck();
|
||||
#endif
|
||||
handleCpuModeChange();
|
||||
handleSseModeChange();
|
||||
#if BX_SUPPORT_AVX
|
||||
handleAvxModeChange();
|
||||
#endif
|
||||
handleCpuContextChange();
|
||||
|
||||
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_CONTEXT_SWITCH, 0);
|
||||
|
||||
@ -2070,19 +2058,7 @@ void BX_CPU_C::VMexitLoadHostState(void)
|
||||
// Update lazy flags state
|
||||
setEFlagsOSZAPC(0);
|
||||
|
||||
#if BX_SUPPORT_MONITOR_MWAIT
|
||||
BX_CPU_THIS_PTR monitor.reset_monitor();
|
||||
#endif
|
||||
|
||||
invalidate_prefetch_q();
|
||||
#if BX_SUPPORT_ALIGNMENT_CHECK
|
||||
handleAlignmentCheck();
|
||||
#endif
|
||||
handleCpuModeChange();
|
||||
handleSseModeChange();
|
||||
#if BX_SUPPORT_AVX
|
||||
handleAvxModeChange();
|
||||
#endif
|
||||
handleCpuContextChange();
|
||||
|
||||
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_CONTEXT_SWITCH, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user