core/sal: add x86 control and segment registers
new register type RT_CONTROL: CR0, CR2, CR3, CR4 new register type RT_SEGMENT: CS, DS, ES, FS, GS, SS Reading/writing is mostly untested except for CR3... Change-Id: I0d0fba4a1669153ab2577e82ab64a04cf2bbfb94
This commit is contained in:
@ -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
|
||||
};
|
||||
|
||||
@ -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?
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user