Merge "core/sal: add x86 control and segment registers"

This commit is contained in:
Florian Lukas
2014-03-26 16:45:11 +01:00
committed by Gerrit Code Review
4 changed files with 168 additions and 1 deletions

View File

@ -24,6 +24,8 @@ enum RegisterType {
RT_FP, //!< floating point register
RT_IP, //!< program counter / instruction pointer
RT_ST, //!< status register
RT_CONTROL, //!< control registers
RT_SEGMENT, //!< segmentation registers
RT_TRACE //!< registers to be recorded in an extended trace
};

View File

@ -14,6 +14,55 @@ regdata_t BochsCPU::getRegisterContent(const Register* reg) const
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
if (reg->getId() == RID_PC) // program counter?
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;
}
#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;
#ifdef SIM_SUPPORT_64
if (reg->getId() == RID_PC) // program counter?

View File

@ -42,6 +42,48 @@ X86Architecture::X86Architecture()
pFlagReg->setName("EFLAGS");
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:
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) {

View File

@ -50,7 +50,20 @@ enum PCRegisterId { RID_PC = RID_LAST_GP_ID, RID_LAST_PC_ID };
* \enum FlagsRegisterId
* 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