From d4e7c7edd35d1f5e6771077eeca83369c1169a33 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:50:25 -0400 Subject: X86: Keep handy values like the operating mode in one register. --- src/arch/x86/isa/microops/regop.isa | 5 +++++ src/arch/x86/isa/operands.isa | 1 + src/arch/x86/miscregfile.cc | 30 +++++++++++++++++++++++++++++- src/arch/x86/miscregs.hh | 9 +++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 6bd26608e..35f319528 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1100,6 +1100,11 @@ let {{ DestReg = TscOp; ''' + class Rdm5reg(RdRegOp): + code = ''' + DestReg = M5Reg; + ''' + class Wrdl(RegOp): code = ''' SegDescriptor desc = SrcReg1; diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index f002b2cea..446580c1b 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -151,5 +151,6 @@ def operands {{ 'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207), 'CSAttr': ('ControlReg', 'udw', 'MISCREG_CS_ATTR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 208), 'TscOp': ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 209), + 'M5Reg': ('ControlReg', 'udw', 'MISCREG_M5_REG', (None, None, None), 210), 'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300) }}; diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index 930bf53c7..6abeb7d34 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -300,17 +300,39 @@ void MiscRegFile::setReg(int miscReg, CR0 toggled = regVal[miscReg] ^ val; CR0 newCR0 = val; Efer efer = regVal[MISCREG_EFER]; + HandyM5Reg m5reg = regVal[MISCREG_M5_REG]; if (toggled.pg && efer.lme) { if (newCR0.pg) { //Turning on long mode efer.lma = 1; + m5reg.mode = LongMode; regVal[MISCREG_EFER] = efer; } else { //Turning off long mode efer.lma = 0; + m5reg.mode = LegacyMode; regVal[MISCREG_EFER] = efer; } } + // Figure out what submode we're in. + if (m5reg.mode == LongMode) { + SegAttr csAttr = regVal[MISCREG_CS_ATTR]; + if (csAttr.longMode) + m5reg.submode = SixtyFourBitMode; + else + m5reg.submode = CompatabilityMode; + } else { + if (newCR0.pe) { + RFLAGS rflags = regVal[MISCREG_RFLAGS]; + if (rflags.vm) + m5reg.submode = Virtual8086Mode; + else + m5reg.submode = ProtectedMode; + } else { + m5reg.submode = RealMode; + } + } + regVal[MISCREG_M5_REG] = m5reg; if (toggled.pg) { tc->getITBPtr()->invalidateAll(); tc->getDTBPtr()->invalidateAll(); @@ -341,20 +363,26 @@ void MiscRegFile::setReg(int miscReg, { SegAttr toggled = regVal[miscReg] ^ val; SegAttr newCSAttr = val; + HandyM5Reg m5reg = regVal[MISCREG_M5_REG]; if (toggled.longMode) { - SegAttr newCSAttr = val; if (newCSAttr.longMode) { + if (m5reg.mode == LongMode) + m5reg.submode = SixtyFourBitMode; regVal[MISCREG_ES_EFF_BASE] = 0; regVal[MISCREG_CS_EFF_BASE] = 0; regVal[MISCREG_SS_EFF_BASE] = 0; regVal[MISCREG_DS_EFF_BASE] = 0; } else { + if (m5reg.mode == LongMode) + m5reg.submode = CompatabilityMode; regVal[MISCREG_ES_EFF_BASE] = regVal[MISCREG_ES_BASE]; regVal[MISCREG_CS_EFF_BASE] = regVal[MISCREG_CS_BASE]; regVal[MISCREG_SS_EFF_BASE] = regVal[MISCREG_SS_BASE]; regVal[MISCREG_DS_EFF_BASE] = regVal[MISCREG_DS_BASE]; } } + m5reg.cpl = newCSAttr.dpl; + regVal[MISCREG_M5_REG] = m5reg; } break; // These segments always actually use their bases, or in other words diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index 90f1d9fda..caa1e817b 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -130,6 +130,9 @@ namespace X86ISA // Flags register MISCREG_RFLAGS = MISCREG_DR_BASE + NumDRegs, + //Register to keep handy values like the CPU mode in. + MISCREG_M5_REG, + /* * Model Specific Registers */ @@ -563,6 +566,12 @@ namespace X86ISA Bitfield<0> cf; // Carry Flag EndBitUnion(RFLAGS) + BitUnion64(HandyM5Reg) + Bitfield<0> mode; + Bitfield<3, 1> submode; + Bitfield<5, 4> cpl; + EndBitUnion(HandyM5Reg) + /** * Control registers */ -- cgit v1.2.3