X86: Centralize updates to the handy M5 reg.
This commit is contained in:
parent
06b3e3c303
commit
4ee34dfb4e
|
@ -271,12 +271,8 @@ namespace X86ISA
|
|||
tc->setMiscReg(MISCREG_DR6, 0x00000000ffff0ff0ULL);
|
||||
tc->setMiscReg(MISCREG_DR7, 0x0000000000000400ULL);
|
||||
|
||||
// We're now in real mode, effectively at CPL 0
|
||||
HandyM5Reg m5Reg = 0;
|
||||
m5Reg.mode = LegacyMode;
|
||||
m5Reg.submode = RealMode;
|
||||
m5Reg.cpl = 0;
|
||||
tc->setMiscReg(MISCREG_M5_REG, m5Reg);
|
||||
// Update the handy M5 Reg.
|
||||
tc->setMiscReg(MISCREG_M5_REG, 0);
|
||||
MicroPC entry = X86ISAInst::RomLabels::extern_label_initIntHalt;
|
||||
tc->setMicroPC(romMicroPC(entry));
|
||||
tc->setNextMicroPC(romMicroPC(entry) + 1);
|
||||
|
@ -289,7 +285,7 @@ namespace X86ISA
|
|||
HandyM5Reg m5Reg = tc->readMiscReg(MISCREG_M5_REG);
|
||||
if (m5Reg.mode != LegacyMode || m5Reg.submode != RealMode) {
|
||||
panic("Startup IPI recived outside of real mode. "
|
||||
"Don't know what to do.");
|
||||
"Don't know what to do. %d, %d", m5Reg.mode, m5Reg.submode);
|
||||
}
|
||||
|
||||
tc->setMiscReg(MISCREG_CS, vector << 8);
|
||||
|
|
|
@ -96,6 +96,31 @@ using namespace std;
|
|||
|
||||
class Checkpoint;
|
||||
|
||||
void MiscRegFile::updateHandyM5Reg(Efer efer, CR0 cr0,
|
||||
SegAttr csAttr, RFLAGS rflags)
|
||||
{
|
||||
HandyM5Reg m5reg;
|
||||
if (efer.lma) {
|
||||
m5reg.mode = LongMode;
|
||||
if (csAttr.longMode)
|
||||
m5reg.submode = SixtyFourBitMode;
|
||||
else
|
||||
m5reg.submode = CompatabilityMode;
|
||||
} else {
|
||||
m5reg.mode = LegacyMode;
|
||||
if (cr0.pe) {
|
||||
if (rflags.vm)
|
||||
m5reg.submode = Virtual8086Mode;
|
||||
else
|
||||
m5reg.submode = ProtectedMode;
|
||||
} else {
|
||||
m5reg.submode = RealMode;
|
||||
}
|
||||
}
|
||||
m5reg.cpl = csAttr.dpl;
|
||||
regVal[MISCREG_M5_REG] = m5reg;
|
||||
}
|
||||
|
||||
void MiscRegFile::clear()
|
||||
{
|
||||
// Blank everything. 0 might not be an appropriate value for some things,
|
||||
|
@ -151,39 +176,17 @@ void MiscRegFile::setReg(MiscRegIndex 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();
|
||||
|
@ -191,6 +194,10 @@ void MiscRegFile::setReg(MiscRegIndex miscReg,
|
|||
//This must always be 1.
|
||||
newCR0.et = 1;
|
||||
newVal = newCR0;
|
||||
updateHandyM5Reg(regVal[MISCREG_EFER],
|
||||
newCR0,
|
||||
regVal[MISCREG_CS_ATTR],
|
||||
regVal[MISCREG_RFLAGS]);
|
||||
}
|
||||
break;
|
||||
case MISCREG_CR2:
|
||||
|
@ -214,26 +221,23 @@ void MiscRegFile::setReg(MiscRegIndex miscReg,
|
|||
{
|
||||
SegAttr toggled = regVal[miscReg] ^ val;
|
||||
SegAttr newCSAttr = val;
|
||||
HandyM5Reg m5reg = regVal[MISCREG_M5_REG];
|
||||
if (toggled.longMode) {
|
||||
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;
|
||||
updateHandyM5Reg(regVal[MISCREG_EFER],
|
||||
regVal[MISCREG_CR0],
|
||||
newCSAttr,
|
||||
regVal[MISCREG_RFLAGS]);
|
||||
}
|
||||
break;
|
||||
// These segments always actually use their bases, or in other words
|
||||
|
@ -333,6 +337,15 @@ void MiscRegFile::setReg(MiscRegIndex miscReg,
|
|||
dr7.len3 = newDR7.len3;
|
||||
}
|
||||
break;
|
||||
case MISCREG_M5_REG:
|
||||
// Writing anything to the m5reg with side effects makes it update
|
||||
// based on the current values of the relevant registers. The actual
|
||||
// value written is discarded.
|
||||
updateHandyM5Reg(regVal[MISCREG_EFER],
|
||||
regVal[MISCREG_CR0],
|
||||
regVal[MISCREG_CS_ATTR],
|
||||
regVal[MISCREG_RFLAGS]);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -107,6 +107,8 @@ namespace X86ISA
|
|||
{
|
||||
protected:
|
||||
MiscReg regVal[NumMiscRegs];
|
||||
void updateHandyM5Reg(Efer efer, CR0 cr0,
|
||||
SegAttr csAttr, RFLAGS rflags);
|
||||
|
||||
public:
|
||||
void clear();
|
||||
|
|
|
@ -232,6 +232,15 @@ X86_64LiveProcess::startup()
|
|||
|
||||
tc->setMiscRegNoEffect(MISCREG_CS_ATTR, csAttr);
|
||||
|
||||
Efer efer = 0;
|
||||
efer.sce = 1; // Enable system call extensions.
|
||||
efer.lme = 1; // Enable long mode.
|
||||
efer.lma = 1; // Activate long mode.
|
||||
efer.nxe = 1; // Enable nx support.
|
||||
efer.svme = 0; // Disable svm support for now. It isn't implemented.
|
||||
efer.ffxsr = 1; // Turn on fast fxsave and fxrstor.
|
||||
tc->setMiscReg(MISCREG_EFER, efer);
|
||||
|
||||
//Set up the registers that describe the operating mode.
|
||||
CR0 cr0 = 0;
|
||||
cr0.pg = 1; // Turn on paging.
|
||||
|
@ -248,15 +257,6 @@ X86_64LiveProcess::startup()
|
|||
// setting it to one.
|
||||
cr0.pe = 1; // We're definitely in protected mode.
|
||||
tc->setMiscReg(MISCREG_CR0, cr0);
|
||||
|
||||
Efer efer = 0;
|
||||
efer.sce = 1; // Enable system call extensions.
|
||||
efer.lme = 1; // Enable long mode.
|
||||
efer.lma = 1; // Activate long mode.
|
||||
efer.nxe = 1; // Enable nx support.
|
||||
efer.svme = 0; // Disable svm support for now. It isn't implemented.
|
||||
efer.ffxsr = 1; // Turn on fast fxsave and fxrstor.
|
||||
tc->setMiscReg(MISCREG_EFER, efer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -340,6 +340,15 @@ I386LiveProcess::startup()
|
|||
// Set the LDT selector to 0 to deactivate it.
|
||||
tc->setMiscRegNoEffect(MISCREG_TSL, 0);
|
||||
|
||||
Efer efer = 0;
|
||||
efer.sce = 1; // Enable system call extensions.
|
||||
efer.lme = 1; // Enable long mode.
|
||||
efer.lma = 0; // Deactivate long mode.
|
||||
efer.nxe = 1; // Enable nx support.
|
||||
efer.svme = 0; // Disable svm support for now. It isn't implemented.
|
||||
efer.ffxsr = 1; // Turn on fast fxsave and fxrstor.
|
||||
tc->setMiscReg(MISCREG_EFER, efer);
|
||||
|
||||
//Set up the registers that describe the operating mode.
|
||||
CR0 cr0 = 0;
|
||||
cr0.pg = 1; // Turn on paging.
|
||||
|
@ -356,15 +365,6 @@ I386LiveProcess::startup()
|
|||
// setting it to one.
|
||||
cr0.pe = 1; // We're definitely in protected mode.
|
||||
tc->setMiscReg(MISCREG_CR0, cr0);
|
||||
|
||||
Efer efer = 0;
|
||||
efer.sce = 1; // Enable system call extensions.
|
||||
efer.lme = 1; // Enable long mode.
|
||||
efer.lma = 0; // Deactivate long mode.
|
||||
efer.nxe = 1; // Enable nx support.
|
||||
efer.svme = 0; // Disable svm support for now. It isn't implemented.
|
||||
efer.ffxsr = 1; // Turn on fast fxsave and fxrstor.
|
||||
tc->setMiscReg(MISCREG_EFER, efer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue