accessors for DR6 and DR7 fields
This commit is contained in:
parent
edd7c2d787
commit
63fe52f601
@ -660,11 +660,11 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
|
||||
#endif
|
||||
#if BX_X86_DEBUGGER
|
||||
// any debug code breakpoint is set
|
||||
|| ((BX_CPU_THIS_PTR dr7 & 0xff) &&
|
||||
(((BX_CPU_THIS_PTR dr7 >> 16) & 3) == 0 ||
|
||||
((BX_CPU_THIS_PTR dr7 >> 20) & 3) == 0 ||
|
||||
((BX_CPU_THIS_PTR dr7 >> 24) & 3) == 0 ||
|
||||
((BX_CPU_THIS_PTR dr7 >> 28) & 3) == 0))
|
||||
|| (BX_CPU_THIS_PTR dr7.bp_enabled() &&
|
||||
(BX_CPU_THIS_PTR dr7.get_R_W0() == 0 ||
|
||||
BX_CPU_THIS_PTR dr7.get_R_W1() == 0 ||
|
||||
BX_CPU_THIS_PTR dr7.get_R_W2() == 0 ||
|
||||
BX_CPU_THIS_PTR dr7.get_R_W3() == 0))
|
||||
#endif
|
||||
))
|
||||
BX_CPU_THIS_PTR async_event = 0;
|
||||
|
@ -884,18 +884,18 @@ public: // for now...
|
||||
/* debug registers DR0-DR7 */
|
||||
#if BX_CPU_LEVEL >= 3
|
||||
bx_address dr[4]; /* DR0-DR3 */
|
||||
Bit32u dr6;
|
||||
Bit32u dr7;
|
||||
bx_dr6_t dr6;
|
||||
bx_dr7_t dr7;
|
||||
#endif
|
||||
|
||||
/* TR3 - TR7 (Test Register 3-7), unimplemented */
|
||||
|
||||
/* Control registers */
|
||||
bx_cr0_t cr0;
|
||||
bx_address cr2;
|
||||
bx_address cr3;
|
||||
bx_cr0_t cr0;
|
||||
bx_address cr2;
|
||||
bx_address cr3;
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
bx_cr4_t cr4;
|
||||
bx_cr4_t cr4;
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
|
@ -43,7 +43,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_DdRd(bxInstruction_c *i)
|
||||
|
||||
// Note: processor clears GD upon entering debug exception
|
||||
// handler, to allow access to the debug registers
|
||||
if (BX_CPU_THIS_PTR dr7 & 0x2000) { // GD bit set
|
||||
if (BX_CPU_THIS_PTR dr7.get_GD()) {
|
||||
BX_ERROR(("MOV_DdRd: DR7 GD bit is set"));
|
||||
BX_CPU_THIS_PTR debug_trap |= BX_DEBUG_DR_ACCESS_BIT;
|
||||
exception(BX_DB_EXCEPTION, 0);
|
||||
@ -79,11 +79,11 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_DdRd(bxInstruction_c *i)
|
||||
case 6: // DR6
|
||||
#if BX_CPU_LEVEL <= 4
|
||||
// On 386/486 bit12 is settable
|
||||
BX_CPU_THIS_PTR dr6 = (BX_CPU_THIS_PTR dr6 & 0xffff0ff0) |
|
||||
BX_CPU_THIS_PTR dr6.val32 = (BX_CPU_THIS_PTR dr6.val32 & 0xffff0ff0) |
|
||||
(val_32 & 0x0000f00f);
|
||||
#else
|
||||
// On Pentium+, bit12 is always zero
|
||||
BX_CPU_THIS_PTR dr6 = (BX_CPU_THIS_PTR dr6 & 0xffff0ff0) |
|
||||
BX_CPU_THIS_PTR dr6.val32 = (BX_CPU_THIS_PTR dr6.val32 & 0xffff0ff0) |
|
||||
(val_32 & 0x0000e00f);
|
||||
#endif
|
||||
break;
|
||||
@ -107,20 +107,20 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_DdRd(bxInstruction_c *i)
|
||||
}
|
||||
#if BX_CPU_LEVEL <= 4
|
||||
// 386/486: you can play with all the bits except b10 is always 1
|
||||
BX_CPU_THIS_PTR dr7 = val_32 | 0x00000400;
|
||||
BX_CPU_THIS_PTR dr7.set32(val_32 | 0x00000400);
|
||||
#else
|
||||
// Pentium+: bits15,14,12 are hardwired to 0, rest are settable.
|
||||
// Even bits 11,10 are changeable though reserved.
|
||||
BX_CPU_THIS_PTR dr7 = (val_32 & 0xffff2fff) | 0x00000400;
|
||||
BX_CPU_THIS_PTR dr7.set32((val_32 & 0xffff2fff) | 0x00000400);
|
||||
#endif
|
||||
#if BX_X86_DEBUGGER
|
||||
// if we have code breakpoints enabled then we must check
|
||||
// breakpoints condition in cpu loop
|
||||
if (BX_CPU_THIS_PTR dr7 & 0xff) {
|
||||
if (((BX_CPU_THIS_PTR dr7 >> 16) & 3) == 0 ||
|
||||
((BX_CPU_THIS_PTR dr7 >> 20) & 3) == 0 ||
|
||||
((BX_CPU_THIS_PTR dr7 >> 24) & 3) == 0 ||
|
||||
((BX_CPU_THIS_PTR dr7 >> 28) & 3) == 0)
|
||||
if (BX_CPU_THIS_PTR dr7.bp_enabled()) {
|
||||
if (BX_CPU_THIS_PTR dr7.get_R_W0() == 0 ||
|
||||
BX_CPU_THIS_PTR dr7.get_R_W1() == 0 ||
|
||||
BX_CPU_THIS_PTR dr7.get_R_W2() == 0 ||
|
||||
BX_CPU_THIS_PTR dr7.get_R_W3() == 0)
|
||||
{
|
||||
BX_INFO(("MOV_DdRd(): code breakpoint is set"));
|
||||
BX_CPU_THIS_PTR async_event = 1;
|
||||
@ -154,7 +154,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RdDd(bxInstruction_c *i)
|
||||
|
||||
// Note: processor clears GD upon entering debug exception
|
||||
// handler, to allow access to the debug registers
|
||||
if (BX_CPU_THIS_PTR dr7 & 0x2000) { // GD bit set
|
||||
if (BX_CPU_THIS_PTR dr7.get_GD()) {
|
||||
BX_ERROR(("MOV_RdDd: DR7 GD bit is set"));
|
||||
BX_CPU_THIS_PTR debug_trap |= BX_DEBUG_DR_ACCESS_BIT;
|
||||
exception(BX_DB_EXCEPTION, 0);
|
||||
@ -183,14 +183,14 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RdDd(bxInstruction_c *i)
|
||||
// DR4 aliased to DR6 by default. With Debug Extensions ON,
|
||||
// access to DR4 causes #UD
|
||||
case 6: // DR6
|
||||
val_32 = BX_CPU_THIS_PTR dr6;
|
||||
val_32 = BX_CPU_THIS_PTR dr6.get32();
|
||||
break;
|
||||
|
||||
case 5: // DR5
|
||||
// DR5 aliased to DR7 by default. With Debug Extensions ON,
|
||||
// access to DR5 causes #UD
|
||||
case 7: // DR7
|
||||
val_32 = BX_CPU_THIS_PTR dr7;
|
||||
val_32 = BX_CPU_THIS_PTR dr7.get32();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -222,7 +222,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_DqRq(bxInstruction_c *i)
|
||||
|
||||
// Note: processor clears GD upon entering debug exception
|
||||
// handler, to allow access to the debug registers
|
||||
if (BX_CPU_THIS_PTR dr7 & 0x2000) { // GD bit set
|
||||
if (BX_CPU_THIS_PTR dr7.get_GD()) {
|
||||
BX_ERROR(("MOV_DqRq: DR7 GD bit is set"));
|
||||
BX_CPU_THIS_PTR debug_trap |= BX_DEBUG_DR_ACCESS_BIT;
|
||||
exception(BX_DB_EXCEPTION, 0);
|
||||
@ -262,7 +262,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_DqRq(bxInstruction_c *i)
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
// On Pentium+, bit12 is always zero
|
||||
BX_CPU_THIS_PTR dr6 = (BX_CPU_THIS_PTR dr6 & 0xffff0ff0) |
|
||||
BX_CPU_THIS_PTR dr6.val32 = (BX_CPU_THIS_PTR dr6.val32 & 0xffff0ff0) |
|
||||
(val_64 & 0x0000e00f);
|
||||
break;
|
||||
|
||||
@ -292,18 +292,18 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_DqRq(bxInstruction_c *i)
|
||||
|
||||
// Pentium+: bits15,14,12 are hardwired to 0, rest are settable.
|
||||
// Even bits 11,10 are changeable though reserved.
|
||||
BX_CPU_THIS_PTR dr7 = (val_64 & 0xffff2fff) | 0x00000400;
|
||||
BX_CPU_THIS_PTR dr7.set32((val_64 & 0xffff2fff) | 0x00000400);
|
||||
|
||||
#if BX_X86_DEBUGGER
|
||||
// if we have code breakpoints enabled then we must check
|
||||
// breakpoints condition in cpu loop
|
||||
if (BX_CPU_THIS_PTR dr7 & 0xff) {
|
||||
if (((BX_CPU_THIS_PTR dr7 >> 16) & 3) == 0 ||
|
||||
((BX_CPU_THIS_PTR dr7 >> 20) & 3) == 0 ||
|
||||
((BX_CPU_THIS_PTR dr7 >> 24) & 3) == 0 ||
|
||||
((BX_CPU_THIS_PTR dr7 >> 28) & 3) == 0)
|
||||
if (BX_CPU_THIS_PTR dr7.bp_enabled()) {
|
||||
if (BX_CPU_THIS_PTR dr7.get_R_W0() == 0 ||
|
||||
BX_CPU_THIS_PTR dr7.get_R_W1() == 0 ||
|
||||
BX_CPU_THIS_PTR dr7.get_R_W2() == 0 ||
|
||||
BX_CPU_THIS_PTR dr7.get_R_W3() == 0)
|
||||
{
|
||||
BX_INFO(("MOV_DqRq(): code breakpoint is set"));
|
||||
BX_INFO(("MOV_DdRd(): code breakpoint is set"));
|
||||
BX_CPU_THIS_PTR async_event = 1;
|
||||
}
|
||||
}
|
||||
@ -338,7 +338,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RqDq(bxInstruction_c *i)
|
||||
|
||||
// Note: processor clears GD upon entering debug exception
|
||||
// handler, to allow access to the debug registers
|
||||
if (BX_CPU_THIS_PTR dr7 & 0x2000) { // GD bit set
|
||||
if (BX_CPU_THIS_PTR dr7.get_GD()) {
|
||||
BX_ERROR(("MOV_RqDq: DR7 GD bit is set"));
|
||||
BX_CPU_THIS_PTR debug_trap |= BX_DEBUG_DR_ACCESS_BIT;
|
||||
exception(BX_DB_EXCEPTION, 0);
|
||||
@ -368,14 +368,14 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RqDq(bxInstruction_c *i)
|
||||
// DR4 aliased to DR6 by default. With Debug Extensions ON,
|
||||
// access to DR4 causes #UD
|
||||
case 6: // DR6
|
||||
val_64 = BX_CPU_THIS_PTR dr6;
|
||||
val_64 = BX_CPU_THIS_PTR dr6.get32();
|
||||
break;
|
||||
|
||||
case 5: // DR5
|
||||
// DR5 aliased to DR7 by default. With Debug Extensions ON,
|
||||
// access to DR5 causes #UD
|
||||
case 7: // DR7
|
||||
val_64 = BX_CPU_THIS_PTR dr7;
|
||||
val_64 = BX_CPU_THIS_PTR dr7.get32();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1194,7 +1194,7 @@ bx_bool BX_CPU_C::hwbreakpoint_check(bx_address laddr)
|
||||
|
||||
void BX_CPU_C::code_breakpoint_match(bx_address laddr)
|
||||
{
|
||||
if (BX_CPU_THIS_PTR dr7 & 0x000000ff) {
|
||||
if (BX_CPU_THIS_PTR dr7.bp_enabled()) {
|
||||
Bit32u dr6_bits = hwdebug_compare(laddr, 1, BX_HWDebugInstruction, BX_HWDebugInstruction);
|
||||
if (dr6_bits) {
|
||||
// Add to the list of debug events thus far.
|
||||
@ -1207,7 +1207,7 @@ void BX_CPU_C::code_breakpoint_match(bx_address laddr)
|
||||
|
||||
void BX_CPU_C::hwbreakpoint_match(bx_address laddr, unsigned len, unsigned rw)
|
||||
{
|
||||
if (BX_CPU_THIS_PTR dr7 & 0x000000ff) {
|
||||
if (BX_CPU_THIS_PTR dr7.bp_enabled()) {
|
||||
// Only compare debug registers if any breakpoints are enabled
|
||||
unsigned opa, opb, write = rw & 1;
|
||||
opa = BX_HWDebugMemRW; // Read or Write always compares vs 11b
|
||||
@ -1226,8 +1226,7 @@ void BX_CPU_C::hwbreakpoint_match(bx_address laddr, unsigned len, unsigned rw)
|
||||
Bit32u BX_CPU_C::hwdebug_compare(bx_address laddr_0, unsigned size,
|
||||
unsigned opa, unsigned opb)
|
||||
{
|
||||
// Support x86 hardware debug facilities (DR0..DR7)
|
||||
Bit32u dr7 = BX_CPU_THIS_PTR dr7;
|
||||
Bit32u dr7 = BX_CPU_THIS_PTR dr7.get32();
|
||||
|
||||
static bx_address alignment_mask[4] =
|
||||
// 00b=1 01b=2 10b=undef(8) 11b=4
|
||||
@ -1237,15 +1236,15 @@ Bit32u BX_CPU_C::hwdebug_compare(bx_address laddr_0, unsigned size,
|
||||
Bit32u dr_op[4], dr_len[4];
|
||||
bx_bool ibpoint_found_n[4], ibpoint_found = 0;
|
||||
|
||||
dr_len[0] = (dr7>>18) & 3;
|
||||
dr_len[1] = (dr7>>22) & 3;
|
||||
dr_len[2] = (dr7>>26) & 3;
|
||||
dr_len[3] = (dr7>>30) & 3;
|
||||
dr_len[0] = BX_CPU_THIS_PTR dr7.get_LEN0();
|
||||
dr_len[1] = BX_CPU_THIS_PTR dr7.get_LEN1();
|
||||
dr_len[2] = BX_CPU_THIS_PTR dr7.get_LEN2();
|
||||
dr_len[3] = BX_CPU_THIS_PTR dr7.get_LEN3();
|
||||
|
||||
dr_op[0] = (dr7>>16) & 3;
|
||||
dr_op[1] = (dr7>>20) & 3;
|
||||
dr_op[2] = (dr7>>24) & 3;
|
||||
dr_op[3] = (dr7>>28) & 3;
|
||||
dr_op[0] = BX_CPU_THIS_PTR dr7.get_R_W0();
|
||||
dr_op[1] = BX_CPU_THIS_PTR dr7.get_R_W1();
|
||||
dr_op[2] = BX_CPU_THIS_PTR dr7.get_R_W2();
|
||||
dr_op[3] = BX_CPU_THIS_PTR dr7.get_R_W3();
|
||||
|
||||
for (unsigned n=0;n<4;n++) {
|
||||
bx_address dr_start = BX_CPU_THIS_PTR dr[n] & ~alignment_mask[dr_len[n]];
|
||||
@ -1283,7 +1282,7 @@ Bit32u BX_CPU_C::hwdebug_compare(bx_address laddr_0, unsigned size,
|
||||
void BX_CPU_C::iobreakpoint_match(unsigned port, unsigned len)
|
||||
{
|
||||
// Only compare debug registers if any breakpoints are enabled
|
||||
if (BX_CPU_THIS_PTR cr4.get_DE() && (BX_CPU_THIS_PTR dr7 & 0x000000ff))
|
||||
if (BX_CPU_THIS_PTR cr4.get_DE() && BX_CPU_THIS_PTR dr7.bp_enabled())
|
||||
{
|
||||
Bit32u dr6_bits = hwdebug_compare(port, len, BX_HWDebugIO, BX_HWDebugIO);
|
||||
if (dr6_bits) {
|
||||
|
@ -29,10 +29,10 @@ struct bx_cr0_t {
|
||||
|
||||
// Accessors for all cr0 bitfields.
|
||||
#define IMPLEMENT_CRREG_ACCESSORS(name, bitnum) \
|
||||
BX_CPP_INLINE bx_bool get_##name () { \
|
||||
BX_CPP_INLINE bx_bool get_##name() const { \
|
||||
return 1 & (val32 >> bitnum); \
|
||||
} \
|
||||
BX_CPP_INLINE void set_##name (Bit8u val) { \
|
||||
BX_CPP_INLINE void set_##name(Bit8u val) { \
|
||||
val32 = (val32 & ~(1<<bitnum)) | ((!!val) << bitnum); \
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ struct bx_cr0_t {
|
||||
#endif
|
||||
IMPLEMENT_CRREG_ACCESSORS(PG, 31);
|
||||
|
||||
BX_CPP_INLINE Bit32u get32() { return val32; }
|
||||
BX_CPP_INLINE Bit32u get32() const { return val32; }
|
||||
// ET is hardwired bit in CR0
|
||||
BX_CPP_INLINE void set32(Bit32u val) { val32 = val | 0x10; }
|
||||
};
|
||||
@ -116,7 +116,7 @@ struct bx_cr4_t {
|
||||
#endif
|
||||
IMPLEMENT_CRREG_ACCESSORS(OSXSAVE, 18);
|
||||
|
||||
BX_CPP_INLINE Bit32u get32() { return val32; }
|
||||
BX_CPP_INLINE Bit32u get32() const { return val32; }
|
||||
BX_CPP_INLINE void set32(Bit32u val) { val32 = val; }
|
||||
};
|
||||
|
||||
@ -125,6 +125,66 @@ struct bx_cr4_t {
|
||||
|
||||
#endif // #if BX_CPU_LEVEL >= 4
|
||||
|
||||
struct bx_dr6_t {
|
||||
Bit32u val32; // 32bit value of register
|
||||
|
||||
IMPLEMENT_CRREG_ACCESSORS(B0, 0);
|
||||
IMPLEMENT_CRREG_ACCESSORS(B1, 1);
|
||||
IMPLEMENT_CRREG_ACCESSORS(B2, 2);
|
||||
IMPLEMENT_CRREG_ACCESSORS(B3, 3);
|
||||
|
||||
IMPLEMENT_CRREG_ACCESSORS(BD, 13);
|
||||
IMPLEMENT_CRREG_ACCESSORS(BS, 14);
|
||||
IMPLEMENT_CRREG_ACCESSORS(BT, 15);
|
||||
|
||||
BX_CPP_INLINE Bit32u get32() const { return val32; }
|
||||
BX_CPP_INLINE void set32(Bit32u val) { val32 = val; }
|
||||
};
|
||||
|
||||
struct bx_dr7_t {
|
||||
Bit32u val32; // 32bit value of register
|
||||
|
||||
IMPLEMENT_CRREG_ACCESSORS(L0, 0);
|
||||
IMPLEMENT_CRREG_ACCESSORS(G0, 1);
|
||||
IMPLEMENT_CRREG_ACCESSORS(L1, 2);
|
||||
IMPLEMENT_CRREG_ACCESSORS(G1, 3);
|
||||
IMPLEMENT_CRREG_ACCESSORS(L2, 4);
|
||||
IMPLEMENT_CRREG_ACCESSORS(G2, 5);
|
||||
IMPLEMENT_CRREG_ACCESSORS(L3, 6);
|
||||
IMPLEMENT_CRREG_ACCESSORS(G3, 7);
|
||||
IMPLEMENT_CRREG_ACCESSORS(LE, 8);
|
||||
IMPLEMENT_CRREG_ACCESSORS(GE, 9);
|
||||
IMPLEMENT_CRREG_ACCESSORS(GD, 13);
|
||||
|
||||
#define IMPLEMENT_DRREG_ACCESSORS(name, bitmask, bitnum) \
|
||||
int get_##name() const { \
|
||||
return (val32 & (bitmask)) >> (bitnum); \
|
||||
}
|
||||
|
||||
IMPLEMENT_DRREG_ACCESSORS(R_W0, 0x00030000, 16);
|
||||
IMPLEMENT_DRREG_ACCESSORS(LEN0, 0x000C0000, 18);
|
||||
IMPLEMENT_DRREG_ACCESSORS(R_W1, 0x00300000, 20);
|
||||
IMPLEMENT_DRREG_ACCESSORS(LEN1, 0x00C00000, 22);
|
||||
IMPLEMENT_DRREG_ACCESSORS(R_W2, 0x03000000, 24);
|
||||
IMPLEMENT_DRREG_ACCESSORS(LEN2, 0x0C000000, 26);
|
||||
IMPLEMENT_DRREG_ACCESSORS(R_W3, 0x30000000, 28);
|
||||
IMPLEMENT_DRREG_ACCESSORS(LEN3, 0xC0000000, 30);
|
||||
|
||||
IMPLEMENT_DRREG_ACCESSORS(bp_enabled, 0xFF, 0);
|
||||
|
||||
BX_CPP_INLINE Bit32u get32() const { return val32; }
|
||||
BX_CPP_INLINE void set32(Bit32u val) {
|
||||
#if BX_CPU_LEVEL <= 4
|
||||
// 386/486: you can play with all the bits except b10 is always 1
|
||||
val32 = val | 0x00000400;
|
||||
#else
|
||||
// Pentium+: bits15,14,12 are hardwired to 0, rest are settable.
|
||||
// Even bits 11,10 are changeable though reserved.
|
||||
val32 = (val & 0xffff2fff) | 0x00000400;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
|
||||
#define BX_EFER_SCE_MASK (1 << 0)
|
||||
@ -144,7 +204,7 @@ struct bx_efer_t {
|
||||
IMPLEMENT_CRREG_ACCESSORS(LMSLE, 13); /* AMD Long Mode Segment Limit */
|
||||
IMPLEMENT_CRREG_ACCESSORS(FFXSR, 14);
|
||||
|
||||
BX_CPP_INLINE Bit32u get32() { return val32; }
|
||||
BX_CPP_INLINE Bit32u get32() const { return val32; }
|
||||
BX_CPP_INLINE void set32(Bit32u val) { val32 = val; }
|
||||
};
|
||||
|
||||
@ -168,7 +228,7 @@ struct xcr0_t {
|
||||
IMPLEMENT_CRREG_ACCESSORS(FPU, BX_XCR0_FPU_BIT);
|
||||
IMPLEMENT_CRREG_ACCESSORS(SSE, BX_XCR0_SSE_BIT);
|
||||
|
||||
BX_CPP_INLINE Bit32u get32() { return val32; }
|
||||
BX_CPP_INLINE Bit32u get32() const { return val32; }
|
||||
BX_CPP_INLINE void set32(Bit32u val) { val32 = val; }
|
||||
};
|
||||
#endif
|
||||
@ -194,7 +254,7 @@ typedef struct msr {
|
||||
reserved(rsrv), ignored(ign) {}
|
||||
|
||||
BX_CPP_INLINE void reset() { val64 = reset_value; }
|
||||
BX_CPP_INLINE Bit64u get64() { return val64; }
|
||||
BX_CPP_INLINE Bit64u get64() const { return val64; }
|
||||
|
||||
BX_CPP_INLINE bx_bool set64(Bit64u new_val) {
|
||||
new_val = (new_val & ~ignored) | (val64 & ignored);
|
||||
|
@ -905,15 +905,15 @@ void BX_CPU_C::exception(unsigned vector, Bit16u error_code)
|
||||
// Commit debug events to DR6
|
||||
#if BX_CPU_LEVEL <= 4
|
||||
// On 386/486 bit12 is settable
|
||||
BX_CPU_THIS_PTR dr6 = (BX_CPU_THIS_PTR dr6 & 0xffff0ff0) |
|
||||
BX_CPU_THIS_PTR dr6.val32 = (BX_CPU_THIS_PTR dr6.val32 & 0xffff0ff0) |
|
||||
(BX_CPU_THIS_PTR debug_trap & 0x0000f00f);
|
||||
#else
|
||||
// On Pentium+, bit12 is always zero
|
||||
BX_CPU_THIS_PTR dr6 = (BX_CPU_THIS_PTR dr6 & 0xffff0ff0) |
|
||||
BX_CPU_THIS_PTR dr6.val32 = (BX_CPU_THIS_PTR dr6.val32 & 0xffff0ff0) |
|
||||
(BX_CPU_THIS_PTR debug_trap & 0x0000e00f);
|
||||
#endif
|
||||
// clear GD flag in the DR7 prior entering debug exception handler
|
||||
BX_CPU_THIS_PTR dr7 &= ~0x00002000;
|
||||
BX_CPU_THIS_PTR dr7.set_GD(0);
|
||||
}
|
||||
|
||||
BX_CPU_THIS_PTR EXT = 1;
|
||||
|
@ -215,8 +215,8 @@ void BX_CPU_C::register_wx_state(void)
|
||||
DEFPARAM_NORMAL(DR1, dr[1]);
|
||||
DEFPARAM_NORMAL(DR2, dr[2]);
|
||||
DEFPARAM_NORMAL(DR3, dr[3]);
|
||||
DEFPARAM_NORMAL(DR6, dr6);
|
||||
DEFPARAM_NORMAL(DR7, dr7);
|
||||
DEFPARAM_NORMAL(DR6, dr6.val32);
|
||||
DEFPARAM_NORMAL(DR7, dr7.val32);
|
||||
DEFPARAM_NORMAL(CR0, cr0.val32);
|
||||
DEFPARAM_NORMAL(CR2, cr2);
|
||||
DEFPARAM_NORMAL(CR3, cr3);
|
||||
@ -358,8 +358,8 @@ void BX_CPU_C::register_state(void)
|
||||
BXRS_HEX_PARAM_FIELD(cpu, DR1, dr[1]);
|
||||
BXRS_HEX_PARAM_FIELD(cpu, DR2, dr[2]);
|
||||
BXRS_HEX_PARAM_FIELD(cpu, DR3, dr[3]);
|
||||
BXRS_HEX_PARAM_FIELD(cpu, DR6, dr6);
|
||||
BXRS_HEX_PARAM_FIELD(cpu, DR7, dr7);
|
||||
BXRS_HEX_PARAM_FIELD(cpu, DR6, dr6.val32);
|
||||
BXRS_HEX_PARAM_FIELD(cpu, DR7, dr7.val32);
|
||||
#endif
|
||||
BXRS_HEX_PARAM_FIELD(cpu, CR0, cr0.val32);
|
||||
BXRS_HEX_PARAM_FIELD(cpu, CR2, cr2);
|
||||
@ -858,18 +858,12 @@ void BX_CPU_C::reset(unsigned source)
|
||||
BX_CPU_THIS_PTR dr[n] = 0;
|
||||
#endif
|
||||
|
||||
BX_CPU_THIS_PTR dr7 = 0x00000400;
|
||||
#if BX_CPU_LEVEL == 3
|
||||
BX_CPU_THIS_PTR dr6 = 0xFFFF1FF0;
|
||||
#elif BX_CPU_LEVEL == 4
|
||||
BX_CPU_THIS_PTR dr6 = 0xFFFF1FF0;
|
||||
#elif BX_CPU_LEVEL == 5
|
||||
BX_CPU_THIS_PTR dr6 = 0xFFFF0FF0;
|
||||
#elif BX_CPU_LEVEL == 6
|
||||
BX_CPU_THIS_PTR dr6 = 0xFFFF0FF0;
|
||||
#if BX_CPU_LEVEL >= 5
|
||||
BX_CPU_THIS_PTR dr6.val32 = 0xFFFF0FF0;
|
||||
#else
|
||||
# error "DR6: CPU > 6"
|
||||
BX_CPU_THIS_PTR dr6.val32 = 0xFFFF1FF0;
|
||||
#endif
|
||||
BX_CPU_THIS_PTR dr7.val32 = 0x00000400;
|
||||
|
||||
#if BX_X86_DEBUGGER
|
||||
BX_CPU_THIS_PTR in_repeat = 0;
|
||||
|
@ -170,7 +170,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_rip = RIP = 0x00008000;
|
||||
BX_CPU_THIS_PTR dr7 = 0x00000400;
|
||||
BX_CPU_THIS_PTR dr7.set32(0x00000400);
|
||||
|
||||
// CR0 - PE, EM, TS, and PG flags set to 0; others unmodified
|
||||
BX_CPU_THIS_PTR cr0.set_PE(0); // real mode (bit 0)
|
||||
@ -454,8 +454,8 @@ void BX_CPU_C::smram_save_state(Bit32u *saved_state)
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_EFLAGS) = read_eflags();
|
||||
|
||||
// --- Debug and Control Registers --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6) = BX_CPU_THIS_PTR dr6;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7) = BX_CPU_THIS_PTR dr7;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6) = BX_CPU_THIS_PTR dr6.get32();
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7) = BX_CPU_THIS_PTR dr7.get32();
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_CR0) = BX_CPU_THIS_PTR cr0.get32();
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_CR3_HI32) = GET32H(BX_CPU_THIS_PTR cr3);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_CR3) = GET32L(BX_CPU_THIS_PTR cr3);
|
||||
@ -629,8 +629,8 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
|
||||
RIP = SMRAM_FIELD64(saved_state, SMRAM_FIELD_RIP_HI32, SMRAM_FIELD_EIP);
|
||||
|
||||
BX_CPU_THIS_PTR dr6 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6);
|
||||
BX_CPU_THIS_PTR dr7 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7);
|
||||
BX_CPU_THIS_PTR dr6.val32 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6);
|
||||
BX_CPU_THIS_PTR dr7.val32 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7);
|
||||
|
||||
BX_CPU_THIS_PTR gdtr.base = SMRAM_FIELD64(saved_state, SMRAM_FIELD_GDTR_BASE_HI32, SMRAM_FIELD_GDTR_BASE);
|
||||
BX_CPU_THIS_PTR gdtr.limit = SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_LIMIT);
|
||||
@ -714,8 +714,8 @@ void BX_CPU_C::smram_save_state(Bit32u *saved_state)
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_CR4) = BX_CPU_THIS_PTR cr4.get32();
|
||||
#endif
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6) = BX_CPU_THIS_PTR dr6;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7) = BX_CPU_THIS_PTR dr7;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6) = BX_CPU_THIS_PTR dr6.get32();;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7) = BX_CPU_THIS_PTR dr7.get32();;
|
||||
|
||||
// --- Task Register --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR) = BX_CPU_THIS_PTR tr.selector.value;
|
||||
@ -802,8 +802,8 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
|
||||
EIP = SMRAM_FIELD(saved_state, SMRAM_FIELD_EIP);
|
||||
|
||||
BX_CPU_THIS_PTR dr6 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6);
|
||||
BX_CPU_THIS_PTR dr7 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7);
|
||||
BX_CPU_THIS_PTR dr6.val32 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6);
|
||||
BX_CPU_THIS_PTR dr7.val32 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7);
|
||||
|
||||
BX_CPU_THIS_PTR gdtr.base = SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_BASE);
|
||||
BX_CPU_THIS_PTR gdtr.limit = SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_LIMIT);
|
||||
|
@ -404,7 +404,7 @@ void BX_CPU_C::task_switch(bxInstruction_c *i, bx_selector_t *tss_selector,
|
||||
BX_CPU_THIS_PTR cr0.set_TS(1);
|
||||
|
||||
// Task switch clears LE/L3/L2/L1/L0 in DR7
|
||||
BX_CPU_THIS_PTR dr7 &= ~0x00000155;
|
||||
BX_CPU_THIS_PTR dr7.val32 &= ~0x00000155;
|
||||
|
||||
// Step 10: If call or interrupt, set the NT flag in the eflags
|
||||
// image stored in new task's TSS. If IRET or JMP,
|
||||
|
@ -1487,7 +1487,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
|
||||
|
||||
if (vmentry_ctrls & VMX_VMENTRY_CTRL1_LOAD_DBG_CTRLS) {
|
||||
// always clear bits 15:14 and set bit 10
|
||||
BX_CPU_THIS_PTR dr7 = (guest.dr7 & ~0xc000) | 0400;
|
||||
BX_CPU_THIS_PTR dr7.set32((guest.dr7 & ~0xc000) | 0x400);
|
||||
}
|
||||
|
||||
RIP = BX_CPU_THIS_PTR prev_rip = guest.rip;
|
||||
@ -1753,7 +1753,7 @@ void BX_CPU_C::VMexitSaveGuestState(void)
|
||||
#endif
|
||||
|
||||
if (vm->vmexit_ctrls & VMX_VMEXIT_CTRL1_SAVE_DBG_CTRLS)
|
||||
VMwrite64(VMCS_GUEST_DR7, BX_CPU_THIS_PTR dr7);
|
||||
VMwrite64(VMCS_GUEST_DR7, BX_CPU_THIS_PTR dr7.get32());
|
||||
|
||||
VMwrite64(VMCS_GUEST_RIP, RIP);
|
||||
VMwrite64(VMCS_GUEST_RSP, RSP);
|
||||
@ -1897,7 +1897,7 @@ void BX_CPU_C::VMexitLoadHostState(void)
|
||||
}
|
||||
}
|
||||
|
||||
BX_CPU_THIS_PTR dr7 = 0x00000400;
|
||||
BX_CPU_THIS_PTR dr7.set32(0x00000400);
|
||||
|
||||
BX_CPU_THIS_PTR msr.sysenter_cs_msr = host_state->sysenter_cs_msr;
|
||||
BX_CPU_THIS_PTR msr.sysenter_esp_msr = host_state->sysenter_esp_msr;
|
||||
|
Loading…
x
Reference in New Issue
Block a user