Merge "core/sal: add x86 control and segment registers"
This commit is contained in:
@ -24,6 +24,8 @@ enum RegisterType {
|
|||||||
RT_FP, //!< floating point register
|
RT_FP, //!< floating point register
|
||||||
RT_IP, //!< program counter / instruction pointer
|
RT_IP, //!< program counter / instruction pointer
|
||||||
RT_ST, //!< status register
|
RT_ST, //!< status register
|
||||||
|
RT_CONTROL, //!< control registers
|
||||||
|
RT_SEGMENT, //!< segmentation registers
|
||||||
|
|
||||||
RT_TRACE //!< registers to be recorded in an extended trace
|
RT_TRACE //!< registers to be recorded in an extended trace
|
||||||
};
|
};
|
||||||
|
|||||||
@ -14,6 +14,55 @@ regdata_t BochsCPU::getRegisterContent(const Register* reg) const
|
|||||||
return static_cast<regdata_t>(BX_CPU(id)->read_eflags());
|
return static_cast<regdata_t>(BX_CPU(id)->read_eflags());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_CR0) { // CR0 register?
|
||||||
|
return static_cast<regdata_t>(BX_CPU(id)->read_CR0());
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_CR2) { // CR2 register?
|
||||||
|
return static_cast<regdata_t>(BX_CPU(id)->cr2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg->getId() == RID_CR3) { // CR3 register?
|
||||||
|
return static_cast<regdata_t>(BX_CPU(id)->cr3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_CR4) { // CR4 register?
|
||||||
|
return static_cast<regdata_t>(BX_CPU(id)->read_CR4());
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_CS) { // CS register?
|
||||||
|
return static_cast<regdata_t>(BX_CPU(id)->sregs[BX_SEG_REG_CS].selector.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_DS) { // DS register?
|
||||||
|
return static_cast<regdata_t>(BX_CPU(id)->sregs[BX_SEG_REG_DS].selector.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_ES) { // ES register?
|
||||||
|
return static_cast<regdata_t>(BX_CPU(id)->sregs[BX_SEG_REG_ES].selector.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_FS) { // FS register?
|
||||||
|
return static_cast<regdata_t>(BX_CPU(id)->sregs[BX_SEG_REG_FS].selector.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_GS) { // GS register?
|
||||||
|
return static_cast<regdata_t>(BX_CPU(id)->sregs[BX_SEG_REG_GS].selector.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_SS) { // SS register?
|
||||||
|
return static_cast<regdata_t>(BX_CPU(id)->sregs[BX_SEG_REG_SS].selector.value);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SIM_SUPPORT_64
|
#ifdef SIM_SUPPORT_64
|
||||||
if (reg->getId() == RID_PC) // program counter?
|
if (reg->getId() == RID_PC) // program counter?
|
||||||
return static_cast<regdata_t>(BX_CPU(id)->gen_reg[BX_64BIT_REG_RIP].rrx);
|
return static_cast<regdata_t>(BX_CPU(id)->gen_reg[BX_64BIT_REG_RIP].rrx);
|
||||||
@ -45,6 +94,67 @@ void BochsCPU::setRegisterContent(const Register* reg, regdata_t value)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __puma
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_CR0) { // CR0 register?
|
||||||
|
BX_CPU(id)->SetCR0(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_CR2) { // CR2 register?
|
||||||
|
BX_CPU(id)->cr2 = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg->getId() == RID_CR3) { // CR3 register?
|
||||||
|
BX_CPU(id)->SetCR3(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_CR4) { // CR4 register?
|
||||||
|
BX_CPU(id)->SetCR4(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_CS) { // CS register?
|
||||||
|
BX_CPU(id)->load_seg_reg(&BX_CPU(id)->sregs[BX_SEG_REG_CS], value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_DS) { // DS register?
|
||||||
|
BX_CPU(id)->load_seg_reg(&BX_CPU(id)->sregs[BX_SEG_REG_DS], value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_ES) { // ES register?
|
||||||
|
BX_CPU(id)->load_seg_reg(&BX_CPU(id)->sregs[BX_SEG_REG_ES], value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_FS) { // FS register?
|
||||||
|
BX_CPU(id)->load_seg_reg(&BX_CPU(id)->sregs[BX_SEG_REG_FS], value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_GS) { // GS register?
|
||||||
|
BX_CPU(id)->load_seg_reg(&BX_CPU(id)->sregs[BX_SEG_REG_GS], value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// untested
|
||||||
|
if (reg->getId() == RID_SS) { // SS register?
|
||||||
|
BX_CPU(id)->load_seg_reg(&BX_CPU(id)->sregs[BX_SEG_REG_SS], value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
regdata_t* pData;
|
regdata_t* pData;
|
||||||
#ifdef SIM_SUPPORT_64
|
#ifdef SIM_SUPPORT_64
|
||||||
if (reg->getId() == RID_PC) // program counter?
|
if (reg->getId() == RID_PC) // program counter?
|
||||||
|
|||||||
@ -42,6 +42,48 @@ X86Architecture::X86Architecture()
|
|||||||
pFlagReg->setName("EFLAGS");
|
pFlagReg->setName("EFLAGS");
|
||||||
m_addRegister(pFlagReg, RT_ST);
|
m_addRegister(pFlagReg, RT_ST);
|
||||||
|
|
||||||
|
// Add the control registers
|
||||||
|
Register* pCR0Reg = new Register(RID_CR0, 32);
|
||||||
|
pCR0Reg->setName("CR0");
|
||||||
|
m_addRegister(pCR0Reg, RT_CONTROL);
|
||||||
|
|
||||||
|
Register* pCR2Reg = new Register(RID_CR2, 32);
|
||||||
|
pCR2Reg->setName("CR2");
|
||||||
|
m_addRegister(pCR2Reg, RT_CONTROL);
|
||||||
|
|
||||||
|
Register* pCR3Reg = new Register(RID_CR3, 32);
|
||||||
|
pCR3Reg->setName("CR3");
|
||||||
|
m_addRegister(pCR3Reg, RT_CONTROL);
|
||||||
|
|
||||||
|
Register* pCR4Reg = new Register(RID_CR4, 32);
|
||||||
|
pCR4Reg->setName("CR4");
|
||||||
|
m_addRegister(pCR4Reg, RT_CONTROL);
|
||||||
|
|
||||||
|
// Add the segment selector registers
|
||||||
|
Register* pCSReg = new Register(RID_CS, 16);
|
||||||
|
pCSReg->setName("CS");
|
||||||
|
m_addRegister(pCSReg, RT_SEGMENT);
|
||||||
|
|
||||||
|
Register* pDSReg = new Register(RID_DS, 16);
|
||||||
|
pDSReg->setName("DS");
|
||||||
|
m_addRegister(pDSReg, RT_SEGMENT);
|
||||||
|
|
||||||
|
Register* pESReg = new Register(RID_ES, 16);
|
||||||
|
pESReg->setName("ES");
|
||||||
|
m_addRegister(pESReg, RT_SEGMENT);
|
||||||
|
|
||||||
|
Register* pFSReg = new Register(RID_FS, 16);
|
||||||
|
pFSReg->setName("FS");
|
||||||
|
m_addRegister(pFSReg, RT_SEGMENT);
|
||||||
|
|
||||||
|
Register* pGSReg = new Register(RID_GS, 16);
|
||||||
|
pGSReg->setName("GS");
|
||||||
|
m_addRegister(pGSReg, RT_SEGMENT);
|
||||||
|
|
||||||
|
Register* pSSReg = new Register(RID_SS, 16);
|
||||||
|
pSSReg->setName("SS");
|
||||||
|
m_addRegister(pSSReg, RT_SEGMENT);
|
||||||
|
|
||||||
// Registers used for extended tracing:
|
// Registers used for extended tracing:
|
||||||
size_t ids[] = {RID_CAX, RID_CBX, RID_CCX, RID_CDX, RID_CSI, RID_CDI, RID_CSP, RID_CBP, RID_FLAGS};
|
size_t ids[] = {RID_CAX, RID_CBX, RID_CCX, RID_CDX, RID_CSI, RID_CDI, RID_CSP, RID_CBP, RID_FLAGS};
|
||||||
for (size_t i = 0; i < sizeof(ids)/sizeof(*ids); ++i) {
|
for (size_t i = 0; i < sizeof(ids)/sizeof(*ids); ++i) {
|
||||||
|
|||||||
@ -50,7 +50,20 @@ enum PCRegisterId { RID_PC = RID_LAST_GP_ID, RID_LAST_PC_ID };
|
|||||||
* \enum FlagsRegisterId
|
* \enum FlagsRegisterId
|
||||||
* Symbolic identifier to access the flags register.
|
* Symbolic identifier to access the flags register.
|
||||||
*/
|
*/
|
||||||
enum FlagsRegisterId { RID_FLAGS = RID_LAST_PC_ID };
|
enum FlagsRegisterId { RID_FLAGS = RID_LAST_PC_ID, RID_LAST_FLAGS_ID };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \enum SegmentRegisterId
|
||||||
|
* Symbolic identifier to access the segment register.
|
||||||
|
*/
|
||||||
|
enum SegmentRegisterId { RID_CS = RID_LAST_FLAGS_ID, RID_DS, RID_ES, RID_FS,
|
||||||
|
RID_GS, RID_SS, RID_LAST_SEGMENT_ID};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \enum ControlRegisterId
|
||||||
|
* Symbolic identifier to access the control register.
|
||||||
|
*/
|
||||||
|
enum ControlRegisterId { RID_CR0 = RID_LAST_SEGMENT_ID, RID_CR1, RID_CR2, RID_CR3, RID_CR4 };
|
||||||
|
|
||||||
} // end-of-namespace: fail
|
} // end-of-namespace: fail
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user