//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);
 }
 
 /**
     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
     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);
     }
     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)
     {
 
 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.
     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);
     //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);