Set the pstate.priv bit to 1 in hyperpriveleged mode. The description in the manual of what happens during a trap says it should be 0, and other places say it doesn't matter.
--HG-- extra : convert_revision : 9ecb6af06657e936a208cbeb8e4a18305869b949
This commit is contained in:
parent
cd2727694d
commit
a0287c1e2d
1 changed files with 26 additions and 14 deletions
|
@ -284,6 +284,11 @@ void enterREDState(ThreadContext *tc)
|
||||||
//HPSTATE.hpriv = 1
|
//HPSTATE.hpriv = 1
|
||||||
HPSTATE |= (1 << 2);
|
HPSTATE |= (1 << 2);
|
||||||
tc->setMiscRegWithEffect(MISCREG_HPSTATE, HPSTATE);
|
tc->setMiscRegWithEffect(MISCREG_HPSTATE, HPSTATE);
|
||||||
|
//PSTATE.priv is set to 1 here. The manual says it should be 0, but
|
||||||
|
//Legion sets it to 1.
|
||||||
|
MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
|
||||||
|
PSTATE |= (1 << 2);
|
||||||
|
tc->setMiscRegWithEffect(MISCREG_PSTATE, PSTATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -340,10 +345,12 @@ void doREDFault(ThreadContext *tc, TrapType tt)
|
||||||
PSTATE |= (1 << 4);
|
PSTATE |= (1 << 4);
|
||||||
//set PSTATE.am to 0
|
//set PSTATE.am to 0
|
||||||
PSTATE &= ~(1 << 3);
|
PSTATE &= ~(1 << 3);
|
||||||
//set PSTATE.priv to 0
|
/* //set PSTATE.priv to 0
|
||||||
PSTATE &= ~(1 << 2);
|
PSTATE &= ~(1 << 2);*/
|
||||||
//set PSTATE.ie to 0
|
//set PSTATE.ie to 0
|
||||||
PSTATE &= ~(1 << 1);
|
//PSTATE.priv is set to 1 here. The manual says it should be 0, but
|
||||||
|
//Legion sets it to 1.
|
||||||
|
PSTATE |= (1 << 2);
|
||||||
//set PSTATE.cle to 0
|
//set PSTATE.cle to 0
|
||||||
PSTATE &= ~(1 << 9);
|
PSTATE &= ~(1 << 9);
|
||||||
//PSTATE.tle is unchanged
|
//PSTATE.tle is unchanged
|
||||||
|
@ -451,7 +458,9 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//PSTATE.priv = 0
|
//PSTATE.priv = 0
|
||||||
PSTATE &= ~(1 << 2);
|
//PSTATE.priv is set to 1 here. The manual says it should be 0, but
|
||||||
|
//Legion sets it to 1.
|
||||||
|
PSTATE |= (1 << 2);
|
||||||
//PSTATE.cle = 0
|
//PSTATE.cle = 0
|
||||||
PSTATE &= ~(1 << 9);
|
PSTATE &= ~(1 << 9);
|
||||||
}
|
}
|
||||||
|
@ -533,20 +542,22 @@ void SparcFaultBase::invoke(ThreadContext * tc)
|
||||||
Addr PC, NPC;
|
Addr PC, NPC;
|
||||||
|
|
||||||
PrivilegeLevel current;
|
PrivilegeLevel current;
|
||||||
if(!(PSTATE & (1 << 2)))
|
if(HPSTATE & (1 << 2))
|
||||||
current = User;
|
current = Hyperprivileged;
|
||||||
else if(!(HPSTATE & (1 << 2)))
|
else if(PSTATE & (1 << 2))
|
||||||
current = Privileged;
|
current = Privileged;
|
||||||
else
|
else
|
||||||
current = Hyperprivileged;
|
current = User;
|
||||||
|
|
||||||
PrivilegeLevel level = getNextLevel(current);
|
PrivilegeLevel level = getNextLevel(current);
|
||||||
|
|
||||||
if(HPSTATE & (1 << 5) || TL == MaxTL - 1)
|
if(HPSTATE & (1 << 5) || TL == MaxTL - 1)
|
||||||
{
|
{
|
||||||
getREDVector(5, PC, NPC);
|
getREDVector(5, PC, NPC);
|
||||||
enterREDState(tc);
|
|
||||||
doREDFault(tc, TT);
|
doREDFault(tc, TT);
|
||||||
|
//This changes the hpstate and pstate, so we need to make sure we
|
||||||
|
//save the old version on the trap stack in doREDFault.
|
||||||
|
enterREDState(tc);
|
||||||
}
|
}
|
||||||
else if(TL == MaxTL)
|
else if(TL == MaxTL)
|
||||||
{
|
{
|
||||||
|
@ -578,9 +589,6 @@ void SparcFaultBase::invoke(ThreadContext * tc)
|
||||||
|
|
||||||
void PowerOnReset::invoke(ThreadContext * tc)
|
void PowerOnReset::invoke(ThreadContext * tc)
|
||||||
{
|
{
|
||||||
//First, enter RED state.
|
|
||||||
enterREDState(tc);
|
|
||||||
|
|
||||||
//For SPARC, when a system is first started, there is a power
|
//For SPARC, when a system is first started, there is a power
|
||||||
//on reset Trap which sets the processor into the following state.
|
//on reset Trap which sets the processor into the following state.
|
||||||
//Bits that aren't set aren't defined on startup.
|
//Bits that aren't set aren't defined on startup.
|
||||||
|
@ -589,8 +597,8 @@ void PowerOnReset::invoke(ThreadContext * tc)
|
||||||
tc->setMiscReg(MISCREG_TT, trapType());
|
tc->setMiscReg(MISCREG_TT, trapType());
|
||||||
tc->setMiscRegWithEffect(MISCREG_GL, MaxGL);
|
tc->setMiscRegWithEffect(MISCREG_GL, MaxGL);
|
||||||
|
|
||||||
//Turn on pef, set everything else to 0
|
//Turn on pef and priv, set everything else to 0
|
||||||
tc->setMiscReg(MISCREG_PSTATE, 1 << 4);
|
tc->setMiscReg(MISCREG_PSTATE, (1 << 4) | (1 << 2));
|
||||||
|
|
||||||
//Turn on red and hpriv, set everything else to 0
|
//Turn on red and hpriv, set everything else to 0
|
||||||
MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
|
MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
|
||||||
|
@ -607,6 +615,10 @@ void PowerOnReset::invoke(ThreadContext * tc)
|
||||||
//The tick register is unreadable by nonprivileged software
|
//The tick register is unreadable by nonprivileged software
|
||||||
tc->setMiscReg(MISCREG_TICK, 1ULL << 63);
|
tc->setMiscReg(MISCREG_TICK, 1ULL << 63);
|
||||||
|
|
||||||
|
//Enter RED state. We do this last so that the actual state preserved in
|
||||||
|
//the trap stack is the state from before this fault.
|
||||||
|
enterREDState(tc);
|
||||||
|
|
||||||
Addr PC, NPC;
|
Addr PC, NPC;
|
||||||
getREDVector(trapType(), PC, NPC);
|
getREDVector(trapType(), PC, NPC);
|
||||||
tc->setPC(PC);
|
tc->setPC(PC);
|
||||||
|
|
Loading…
Reference in a new issue