From 21f5f681e0bb10391334a9c291aafaad1c96d0f7 Mon Sep 17 00:00:00 2001 From: Florian Lukas Date: Wed, 26 Feb 2014 14:10:44 +0100 Subject: [PATCH] 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 --- src/core/sal/Register.hpp | 2 + src/core/sal/bochs/BochsCPU.cc | 110 +++++++++++++++++++++++++++ src/core/sal/x86/X86Architecture.cc | 42 ++++++++++ src/core/sal/x86/X86Architecture.hpp | 15 +++- 4 files changed, 168 insertions(+), 1 deletion(-) diff --git a/src/core/sal/Register.hpp b/src/core/sal/Register.hpp index 1831be0d..9935d598 100644 --- a/src/core/sal/Register.hpp +++ b/src/core/sal/Register.hpp @@ -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 }; diff --git a/src/core/sal/bochs/BochsCPU.cc b/src/core/sal/bochs/BochsCPU.cc index 4eb0a544..a1868bb7 100644 --- a/src/core/sal/bochs/BochsCPU.cc +++ b/src/core/sal/bochs/BochsCPU.cc @@ -14,6 +14,55 @@ regdata_t BochsCPU::getRegisterContent(const Register* reg) const return static_cast(BX_CPU(id)->read_eflags()); } + // untested + if (reg->getId() == RID_CR0) { // CR0 register? + return static_cast(BX_CPU(id)->read_CR0()); + } + + // untested + if (reg->getId() == RID_CR2) { // CR2 register? + return static_cast(BX_CPU(id)->cr2); + } + + if (reg->getId() == RID_CR3) { // CR3 register? + return static_cast(BX_CPU(id)->cr3); + } + + // untested + if (reg->getId() == RID_CR4) { // CR4 register? + return static_cast(BX_CPU(id)->read_CR4()); + } + + // untested + if (reg->getId() == RID_CS) { // CS register? + return static_cast(BX_CPU(id)->sregs[BX_SEG_REG_CS].selector.value); + } + + // untested + if (reg->getId() == RID_DS) { // DS register? + return static_cast(BX_CPU(id)->sregs[BX_SEG_REG_DS].selector.value); + } + + // untested + if (reg->getId() == RID_ES) { // ES register? + return static_cast(BX_CPU(id)->sregs[BX_SEG_REG_ES].selector.value); + } + + // untested + if (reg->getId() == RID_FS) { // FS register? + return static_cast(BX_CPU(id)->sregs[BX_SEG_REG_FS].selector.value); + } + + // untested + if (reg->getId() == RID_GS) { // GS register? + return static_cast(BX_CPU(id)->sregs[BX_SEG_REG_GS].selector.value); + } + + // untested + if (reg->getId() == RID_SS) { // SS register? + return static_cast(BX_CPU(id)->sregs[BX_SEG_REG_SS].selector.value); + } + #ifdef SIM_SUPPORT_64 if (reg->getId() == RID_PC) // program counter? return static_cast(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? diff --git a/src/core/sal/x86/X86Architecture.cc b/src/core/sal/x86/X86Architecture.cc index 84f751c8..312ba4e1 100644 --- a/src/core/sal/x86/X86Architecture.cc +++ b/src/core/sal/x86/X86Architecture.cc @@ -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) { diff --git a/src/core/sal/x86/X86Architecture.hpp b/src/core/sal/x86/X86Architecture.hpp index c867836a..00cae041 100644 --- a/src/core/sal/x86/X86Architecture.hpp +++ b/src/core/sal/x86/X86Architecture.hpp @@ -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