diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2007-01-22 22:31:48 -0800 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2007-01-22 22:31:48 -0800 |
commit | 1352e55ceb2d78a9a36451636b672cd6daf8550e (patch) | |
tree | d7c797f46cd00cc76628a4a65329f2f2dd966cbe /src/arch/sparc/faults.cc | |
parent | 45c3f1747c78aff3495edfe2cbe35fbb7a67f2a4 (diff) | |
parent | 60eaa03d72a13863596e64343d7407af1cab51c5 (diff) | |
download | gem5-1352e55ceb2d78a9a36451636b672cd6daf8550e.tar.xz |
Merge zizzer.eecs.umich.edu:/bk/newmem
into ewok.(none):/home/gblack/m5/newmemo3
src/sim/byteswap.hh:
Hand Merge
--HG--
extra : convert_revision : 640d33ad0c416934e8a5107768e7f1dce6709ca8
Diffstat (limited to 'src/arch/sparc/faults.cc')
-rw-r--r-- | src/arch/sparc/faults.cc | 103 |
1 files changed, 35 insertions, 68 deletions
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 92fdbfdbb..d94c05a0f 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -197,7 +197,7 @@ template<> SparcFaultBase::FaultVals template<> SparcFaultBase::FaultVals SparcFault<InterruptLevelN>::vals = - {"interrupt_level_n", 0x041, 0, {P, P, SH}}; + {"interrupt_level_n", 0x040, 0, {P, P, SH}}; template<> SparcFaultBase::FaultVals SparcFault<HstickMatch>::vals = @@ -240,7 +240,7 @@ template<> SparcFaultBase::FaultVals {"dev_mondo", 0x07D, 1611, {P, P, SH}}; template<> SparcFaultBase::FaultVals - SparcFault<ResumeableError>::vals = + SparcFault<ResumableError>::vals = {"resume_error", 0x07E, 3330, {P, P, SH}}; template<> SparcFaultBase::FaultVals @@ -342,22 +342,8 @@ void doREDFault(ThreadContext *tc, TrapType tt) //Update GL tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL)); - //set PSTATE.mm to 00 - //set PSTATE.pef to 1 - PSTATE |= (1 << 4); - //set PSTATE.am to 0 - PSTATE &= ~(1 << 3); -/* //set PSTATE.priv to 0 - PSTATE &= ~(1 << 2);*/ - //set PSTATE.ie to 0 - //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 - //XXX Where is the tct bit? - //set PSTATE.tct to 0 + PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit + PSTATE |= (1 << 4); //set PSTATE.pef to 1 tc->setMiscReg(MISCREG_PSTATE, PSTATE); //set HPSTATE.red to 1 @@ -440,64 +426,45 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) tc->setMiscReg(MISCREG_TT, tt); //Update the global register level - if(!gotoHpriv) + if (!gotoHpriv) tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxPGL)); else tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL)); //PSTATE.mm is unchanged - //PSTATE.pef = whether or not an fpu is present - //XXX We'll say there's one present, even though there aren't - //implementations for a decent number of the instructions - PSTATE |= (1 << 4); - //PSTATE.am = 0 - PSTATE &= ~(1 << 3); - if(!gotoHpriv) - { - //PSTATE.priv = 1 - PSTATE |= (1 << 2); - //PSTATE.cle = PSTATE.tle - replaceBits(PSTATE, 9, 9, PSTATE >> 8); - } - else - { - //PSTATE.priv = 0 - //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); - } - //PSTATE.ie = 0 - PSTATE &= ~(1 << 1); + PSTATE |= (1 << 4); //PSTATE.pef = whether or not an fpu is present + PSTATE &= ~(1 << 3); //PSTATE.am = 0 + PSTATE &= ~(1 << 1); //PSTATE.ie = 0 //PSTATE.tle is unchanged //PSTATE.tct = 0 - //XXX Where exactly is this field? - tc->setMiscReg(MISCREG_PSTATE, PSTATE); - if(gotoHpriv) + if (gotoHpriv) { - //HPSTATE.red = 0 - HPSTATE &= ~(1 << 5); - //HPSTATE.hpriv = 1 - HPSTATE |= (1 << 2); - //HPSTATE.ibe = 0 - HPSTATE &= ~(1 << 10); + PSTATE &= ~(1 << 9); // PSTATE.cle = 0 + //The manual says PSTATE.priv should be 0, but Legion leaves it alone + HPSTATE &= ~(1 << 5); //HPSTATE.red = 0 + HPSTATE |= (1 << 2); //HPSTATE.hpriv = 1 + HPSTATE &= ~(1 << 10); //HPSTATE.ibe = 0 //HPSTATE.tlz is unchanged tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); + } else { // we are going to priv + PSTATE |= (1 << 2); //PSTATE.priv = 1 + replaceBits(PSTATE, 9, 9, PSTATE >> 8); //PSTATE.cle = PSTATE.tle } + tc->setMiscReg(MISCREG_PSTATE, PSTATE); + bool changedCWP = true; - if(tt == 0x24) + if (tt == 0x24) CWP++; - else if(0x80 <= tt && tt <= 0xbf) + else if (0x80 <= tt && tt <= 0xbf) CWP += (CANSAVE + 2); - else if(0xc0 <= tt && tt <= 0xff) + else if (0xc0 <= tt && tt <= 0xff) CWP--; else changedCWP = false; - if(changedCWP) + if (changedCWP) { CWP = (CWP + NWindows) % NWindows; tc->setMiscRegWithEffect(MISCREG_CWP, CWP); @@ -538,45 +505,45 @@ void SparcFaultBase::invoke(ThreadContext * tc) //We can refer to this to see what the trap level -was-, but something //in the middle could change it in the regfile out from under us. - MiscReg TL = tc->readMiscReg(MISCREG_TL); - MiscReg TT = tc->readMiscReg(MISCREG_TT); - MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); - MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); + MiscReg tl = tc->readMiscReg(MISCREG_TL); + MiscReg tt = tc->readMiscReg(MISCREG_TT); + MiscReg pstate = tc->readMiscReg(MISCREG_PSTATE); + MiscReg hpstate = tc->readMiscReg(MISCREG_HPSTATE); Addr PC, NPC; PrivilegeLevel current; - if(HPSTATE & (1 << 2)) + if (hpstate & HPSTATE::hpriv) current = Hyperprivileged; - else if(PSTATE & (1 << 2)) + else if (pstate & PSTATE::priv) current = Privileged; else current = User; PrivilegeLevel level = getNextLevel(current); - if(HPSTATE & (1 << 5) || TL == MaxTL - 1) { + if ((hpstate & HPSTATE::red) || (tl == MaxTL - 1)) { getREDVector(5, PC, NPC); - 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) { panic("Should go to error state here.. crap\n"); //Do error_state somehow? //Probably inject a WDR fault using the interrupt mechanism. //What should the PC and NPC be set to? - } else if(TL > MaxPTL && level == Privileged) { + } else if (tl > MaxPTL && level == Privileged) { //guest_watchdog fault doNormalFault(tc, trapType(), true); getHyperVector(tc, PC, NPC, 2); - } else if(level == Hyperprivileged || + } else if (level == Hyperprivileged || level == Privileged && trapType() >= 384) { doNormalFault(tc, trapType(), true); getHyperVector(tc, PC, NPC, trapType()); } else { doNormalFault(tc, trapType(), false); - getPrivVector(tc, PC, NPC, trapType(), TL+1); + getPrivVector(tc, PC, NPC, trapType(), tl+1); } tc->setPC(PC); |