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:
Gabe Black 2006-11-20 18:07:58 -05:00
parent cd2727694d
commit a0287c1e2d

View file

@ -284,6 +284,11 @@ void enterREDState(ThreadContext *tc)
//HPSTATE.hpriv = 1
HPSTATE |= (1 << 2);
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);
//set PSTATE.am to 0
PSTATE &= ~(1 << 3);
//set PSTATE.priv to 0
PSTATE &= ~(1 << 2);
/* //set PSTATE.priv to 0
PSTATE &= ~(1 << 2);*/
//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
PSTATE &= ~(1 << 9);
//PSTATE.tle is unchanged
@ -451,7 +458,9 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
else
{
//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 &= ~(1 << 9);
}
@ -533,20 +542,22 @@ void SparcFaultBase::invoke(ThreadContext * tc)
Addr PC, NPC;
PrivilegeLevel current;
if(!(PSTATE & (1 << 2)))
current = User;
else if(!(HPSTATE & (1 << 2)))
if(HPSTATE & (1 << 2))
current = Hyperprivileged;
else if(PSTATE & (1 << 2))
current = Privileged;
else
current = Hyperprivileged;
current = User;
PrivilegeLevel level = getNextLevel(current);
if(HPSTATE & (1 << 5) || TL == MaxTL - 1)
{
getREDVector(5, PC, NPC);
enterREDState(tc);
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)
{
@ -578,9 +589,6 @@ void SparcFaultBase::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
//on reset Trap which sets the processor into the following state.
//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->setMiscRegWithEffect(MISCREG_GL, MaxGL);
//Turn on pef, set everything else to 0
tc->setMiscReg(MISCREG_PSTATE, 1 << 4);
//Turn on pef and priv, set everything else to 0
tc->setMiscReg(MISCREG_PSTATE, (1 << 4) | (1 << 2));
//Turn on red and hpriv, set everything else to 0
MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
@ -607,6 +615,10 @@ void PowerOnReset::invoke(ThreadContext * tc)
//The tick register is unreadable by nonprivileged software
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;
getREDVector(trapType(), PC, NPC);
tc->setPC(PC);