diff options
Diffstat (limited to 'src/arch/x86/miscregfile.cc')
-rw-r--r-- | src/arch/x86/miscregfile.cc | 30 |
1 files changed, 29 insertions, 1 deletions
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 |