diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2012-02-11 14:16:38 -0800 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2012-02-11 14:16:38 -0800 |
commit | 5b557a314f4dbde6f029b3f75c211332ac360f3a (patch) | |
tree | 8be804d79afc881903830e5281fc86b7f7d5d5dc /src/arch/sparc | |
parent | aa513a4a99cb8dfc6b605797acbbb64a5601ab6e (diff) | |
download | gem5-5b557a314f4dbde6f029b3f75c211332ac360f3a.tar.xz |
SPARC: Make PSTATE and HPSTATE a BitUnion.
This gets rid of cryptic bits of code with lots of bit manipulation, and makes
some comments redundant.
Diffstat (limited to 'src/arch/sparc')
-rw-r--r-- | src/arch/sparc/faults.cc | 120 | ||||
-rw-r--r-- | src/arch/sparc/interrupts.hh | 13 | ||||
-rw-r--r-- | src/arch/sparc/isa.cc | 66 | ||||
-rw-r--r-- | src/arch/sparc/isa.hh | 8 | ||||
-rw-r--r-- | src/arch/sparc/isa/base.isa | 4 | ||||
-rw-r--r-- | src/arch/sparc/isa/decoder.isa | 16 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/util.isa | 8 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/priv.isa | 4 | ||||
-rw-r--r-- | src/arch/sparc/isa/operands.isa | 9 | ||||
-rw-r--r-- | src/arch/sparc/miscregs.hh | 40 | ||||
-rw-r--r-- | src/arch/sparc/process.cc | 20 | ||||
-rw-r--r-- | src/arch/sparc/remote_gdb.cc | 8 | ||||
-rw-r--r-- | src/arch/sparc/ua2005.cc | 19 | ||||
-rw-r--r-- | src/arch/sparc/utility.hh | 5 |
14 files changed, 183 insertions, 157 deletions
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index e67b8c50e..c0f2701bd 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -276,17 +276,15 @@ enterREDState(ThreadContext *tc) { //@todo Disable the mmu? //@todo Disable watchpoints? - MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); - // HPSTATE.red = 1 - HPSTATE |= (1 << 5); - // HPSTATE.hpriv = 1 - HPSTATE |= (1 << 2); - tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); + HPSTATE hpstate= tc->readMiscRegNoEffect(MISCREG_HPSTATE); + hpstate.red = 1; + hpstate.hpriv = 1; + tc->setMiscReg(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->readMiscRegNoEffect(MISCREG_PSTATE); - PSTATE |= (1 << 2); - tc->setMiscReg(MISCREG_PSTATE, PSTATE); + PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); + pstate.priv = 1; + tc->setMiscReg(MISCREG_PSTATE, pstate); } /** @@ -299,8 +297,8 @@ doREDFault(ThreadContext *tc, TrapType tt) { MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL); MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); - MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE); - MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); + PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); + HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI); MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP); @@ -310,7 +308,7 @@ doREDFault(ThreadContext *tc, TrapType tt) TL++; - Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64); + Addr pcMask = pstate.am ? mask(32) : mask(64); // set TSTATE.gl to gl replaceBits(TSTATE, 42, 40, GL); @@ -319,7 +317,7 @@ doREDFault(ThreadContext *tc, TrapType tt) // set TSTATE.asi to asi replaceBits(TSTATE, 31, 24, ASI); // set TSTATE.pstate to pstate - replaceBits(TSTATE, 20, 8, PSTATE); + replaceBits(TSTATE, 20, 8, pstate); // set TSTATE.cwp to cwp replaceBits(TSTATE, 4, 0, CWP); @@ -332,7 +330,7 @@ doREDFault(ThreadContext *tc, TrapType tt) tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask); // set HTSTATE.hpstate to hpstate - tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE); + tc->setMiscRegNoEffect(MISCREG_HTSTATE, hpstate); // TT = trap type; tc->setMiscRegNoEffect(MISCREG_TT, tt); @@ -340,19 +338,17 @@ doREDFault(ThreadContext *tc, TrapType tt) // Update GL tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL)); - PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit - PSTATE |= (1 << 4); // set PSTATE.pef to 1 - tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE); + bool priv = pstate.priv; // just save the priv bit + pstate = 0; + pstate.priv = priv; + pstate.pef = 1; + tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate); - // set HPSTATE.red to 1 - HPSTATE |= (1 << 5); - // set HPSTATE.hpriv to 1 - HPSTATE |= (1 << 2); - // set HPSTATE.ibe to 0 - HPSTATE &= ~(1 << 10); - // set HPSTATE.tlz to 0 - HPSTATE &= ~(1 << 0); - tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); + hpstate.red = 1; + hpstate.hpriv = 1; + hpstate.ibe = 0; + hpstate.tlz = 0; + tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate); bool changedCWP = true; if (tt == 0x24) @@ -380,8 +376,8 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) { MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL); MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE); - MiscReg PSTATE = tc->readMiscRegNoEffect(MISCREG_PSTATE); - MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); + PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); + HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2); MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI); MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP); @@ -393,7 +389,7 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) TL++; tc->setMiscRegNoEffect(MISCREG_TL, TL); - Addr pcMask = bits(PSTATE, 3) ? mask(32) : mask(64); + Addr pcMask = pstate.am ? mask(32) : mask(64); // Save off state @@ -404,7 +400,7 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) // set TSTATE.asi to asi replaceBits(TSTATE, 31, 24, ASI); // set TSTATE.pstate to pstate - replaceBits(TSTATE, 20, 8, PSTATE); + replaceBits(TSTATE, 20, 8, pstate); // set TSTATE.cwp to cwp replaceBits(TSTATE, 4, 0, CWP); @@ -417,7 +413,7 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask); // set HTSTATE.hpstate to hpstate - tc->setMiscRegNoEffect(MISCREG_HTSTATE, HPSTATE); + tc->setMiscRegNoEffect(MISCREG_HTSTATE, hpstate); // TT = trap type; tc->setMiscRegNoEffect(MISCREG_TT, tt); @@ -428,26 +424,26 @@ doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) else tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxGL)); - // PSTATE.mm is unchanged - 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 + // pstate.mm is unchanged + pstate.pef = 1; // PSTATE.pef = whether or not an fpu is present + pstate.am = 0; + pstate.ie = 0; + // pstate.tle is unchanged + // pstate.tct = 0 if (gotoHpriv) { - PSTATE &= ~(1 << 9); // PSTATE.cle = 0 + 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->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); + hpstate.red = 0; + hpstate.hpriv = 1; + hpstate.ibe = 0; + // hpstate.tlz is unchanged + tc->setMiscRegNoEffect(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 + pstate.priv = 1; + pstate.cle = pstate.tle; } - tc->setMiscRegNoEffect(MISCREG_PSTATE, PSTATE); + tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate); bool changedCWP = true; @@ -506,22 +502,22 @@ SparcFaultBase::invoke(ThreadContext * tc, StaticInstPtr inst) // in the middle could change it in the regfile out from under us. MiscReg tl = tc->readMiscRegNoEffect(MISCREG_TL); MiscReg tt = tc->readMiscRegNoEffect(MISCREG_TT); - MiscReg pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); - MiscReg hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); + PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); + HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); Addr PC, NPC; PrivilegeLevel current; - if (hpstate & HPSTATE::hpriv) + if (hpstate.hpriv) current = Hyperprivileged; - else if (pstate & PSTATE::priv) + else if (pstate.priv) current = Privileged; else current = User; PrivilegeLevel level = getNextLevel(current); - if ((hpstate & HPSTATE::red) || (tl == MaxTL - 1)) { + if (hpstate.red || (tl == MaxTL - 1)) { getREDVector(5, PC, NPC); doREDFault(tc, tt); // This changes the hpstate and pstate, so we need to make sure we @@ -565,20 +561,18 @@ PowerOnReset::invoke(ThreadContext *tc, StaticInstPtr inst) tc->setMiscRegNoEffect(MISCREG_TT, trapType()); tc->setMiscReg(MISCREG_GL, MaxGL); - // Turn on pef and priv, set everything else to 0 - tc->setMiscRegNoEffect(MISCREG_PSTATE, (1 << 4) | (1 << 2)); + PSTATE pstate = 0; + pstate.pef = 1; + pstate.priv = 1; + tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate); // Turn on red and hpriv, set everything else to 0 - MiscReg HPSTATE = tc->readMiscRegNoEffect(MISCREG_HPSTATE); - // HPSTATE.red = 1 - HPSTATE |= (1 << 5); - // HPSTATE.hpriv = 1 - HPSTATE |= (1 << 2); - // HPSTATE.ibe = 0 - HPSTATE &= ~(1 << 10); - // HPSTATE.tlz = 0 - HPSTATE &= ~(1 << 0); - tc->setMiscRegNoEffect(MISCREG_HPSTATE, HPSTATE); + HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); + hpstate.red = 1; + hpstate.hpriv = 1; + hpstate.ibe = 0; + hpstate.tlz = 0; + tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate); // The tick register is unreadable by nonprivileged software tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63); diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index b728e7188..6d5f30962 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -127,17 +127,16 @@ class Interrupts : public SimObject Fault getInterrupt(ThreadContext *tc) { - int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); - int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); - bool ie = pstate & PSTATE::ie; + HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); + PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); // THESE ARE IN ORDER OF PRIORITY // since there are early returns, and the highest // priority interrupts should get serviced, // it is v. important that new interrupts are inserted // in the right order of processing - if (hpstate & HPSTATE::hpriv) { - if (ie) { + if (hpstate.hpriv) { + if (pstate.ie) { if (interrupts[IT_HINTP]) { // This will be cleaned by a HINTP write return new HstickMatch; @@ -160,7 +159,7 @@ class Interrupts : public SimObject // this will be cleared by an ASI read (or write) return new InterruptVector; } - if (ie) { + if (pstate.ie) { if (interrupts[IT_CPU_MONDO]) { return new CpuMondo; } @@ -175,7 +174,7 @@ class Interrupts : public SimObject if (interrupts[IT_RES_ERROR]) { return new ResumableError; } - } // !hpriv && ie + } // !hpriv && pstate.ie } // !hpriv return NoFault; } diff --git a/src/arch/sparc/isa.cc b/src/arch/sparc/isa.cc index 13f252e82..291e25cec 100644 --- a/src/arch/sparc/isa.cc +++ b/src/arch/sparc/isa.cc @@ -40,10 +40,22 @@ namespace SparcISA { -enum RegMask +static PSTATE +buildPstateMask() { - PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12) -}; + PSTATE mask = 0; + mask.ie = 1; + mask.priv = 1; + mask.am = 1; + mask.pef = 1; + mask.mm = 3; + mask.tle = 1; + mask.cle = 1; + mask.pid1 = 1; + return mask; +} + +static const PSTATE PstateMask = buildPstateMask(); void ISA::reloadRegMap() @@ -110,7 +122,8 @@ ISA::clear() // otherwin = 0; // wstate = 0; // In a T1, bit 11 is apparently always 1 - hpstate = (1 << 11); + hpstate = 0; + hpstate.id = 1; memset(htstate, 0, sizeof(htstate)); hintp = 0; htba = 0; @@ -163,9 +176,10 @@ ISA::readMiscRegNoEffect(int miscReg) * |^lsuim * ^lsudm */ - return bits((uint64_t)hpstate,2,2) | - bits((uint64_t)hpstate,5,5) << 1 | - bits((uint64_t)pstate,3,2) << 2 | + return (uint64_t)hpstate.hpriv | + (uint64_t)hpstate.red << 1 | + (uint64_t)pstate.priv << 2 | + (uint64_t)pstate.am << 3 | bits((uint64_t)lsuCtrlReg,3,2) << 4 | bits((uint64_t)partId,7,0) << 8 | bits((uint64_t)tl,2,0) << 16 | @@ -215,7 +229,7 @@ ISA::readMiscRegNoEffect(int miscReg) case MISCREG_TBA: return tba; case MISCREG_PSTATE: - return pstate; + return (MiscReg)pstate; case MISCREG_TL: return tl; case MISCREG_PIL: @@ -238,7 +252,7 @@ ISA::readMiscRegNoEffect(int miscReg) /** Hyper privileged registers */ case MISCREG_HPSTATE: - return hpstate; + return (MiscReg)hpstate; case MISCREG_HTSTATE: return htstate[tl-1]; case MISCREG_HINTP: @@ -408,7 +422,7 @@ ISA::setMiscRegNoEffect(int miscReg, MiscReg val) tba = val & ULL(~0x7FFF); break; case MISCREG_PSTATE: - pstate = (val & PSTATE_MASK); + pstate = (val & PstateMask); break; case MISCREG_TL: tl = val; @@ -550,15 +564,17 @@ ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc) // Set up performance counting based on pcr value break; case MISCREG_PSTATE: - pstate = val & PSTATE_MASK; + pstate = val & PstateMask; return; case MISCREG_TL: - tl = val; - if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv)) - tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0); - else - tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0); - return; + { + tl = val; + if (hpstate.tlz && tl == 0 && !hpstate.hpriv) + tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0); + else + tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0); + return; + } case MISCREG_CWP: new_val = val >= NWindows ? NWindows - 1 : val; if (val >= NWindows) @@ -616,12 +632,12 @@ ISA::serialize(EventManager *em, std::ostream &os) SERIALIZE_ARRAY(tstate,MaxTL); SERIALIZE_ARRAY(tt,MaxTL); SERIALIZE_SCALAR(tba); - SERIALIZE_SCALAR(pstate); + SERIALIZE_SCALAR((uint16_t)pstate); SERIALIZE_SCALAR(tl); SERIALIZE_SCALAR(pil); SERIALIZE_SCALAR(cwp); SERIALIZE_SCALAR(gl); - SERIALIZE_SCALAR(hpstate); + SERIALIZE_SCALAR((uint64_t)hpstate); SERIALIZE_ARRAY(htstate,MaxTL); SERIALIZE_SCALAR(hintp); SERIALIZE_SCALAR(htba); @@ -692,13 +708,21 @@ ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string §ion) UNSERIALIZE_ARRAY(tstate,MaxTL); UNSERIALIZE_ARRAY(tt,MaxTL); UNSERIALIZE_SCALAR(tba); - UNSERIALIZE_SCALAR(pstate); + { + uint16_t pstate; + UNSERIALIZE_SCALAR(pstate); + this->pstate = pstate; + } UNSERIALIZE_SCALAR(tl); UNSERIALIZE_SCALAR(pil); UNSERIALIZE_SCALAR(cwp); UNSERIALIZE_SCALAR(gl); reloadRegMap(); - UNSERIALIZE_SCALAR(hpstate); + { + uint64_t hpstate; + UNSERIALIZE_SCALAR(hpstate); + this->hpstate = hpstate; + } UNSERIALIZE_ARRAY(htstate,MaxTL); UNSERIALIZE_SCALAR(hintp); UNSERIALIZE_SCALAR(htba); diff --git a/src/arch/sparc/isa.hh b/src/arch/sparc/isa.hh index e5d258786..713f01fa5 100644 --- a/src/arch/sparc/isa.hh +++ b/src/arch/sparc/isa.hh @@ -71,7 +71,7 @@ class ISA // on the previous level) uint64_t tba; // Trap Base Address - uint16_t pstate; // Process State Register + PSTATE pstate; // Process State Register uint8_t tl; // Trap Level uint8_t pil; // Process Interrupt Register uint8_t cwp; // Current Window Pointer @@ -83,7 +83,7 @@ class ISA uint8_t gl; // Global level register /** Hyperprivileged Registers */ - uint64_t hpstate; // Hyperprivileged State Register + HPSTATE hpstate; // Hyperprivileged State Register uint64_t htstate[MaxTL];// Hyperprivileged Trap State Register uint64_t hintp; uint64_t htba; // Hyperprivileged Trap Base Address register @@ -172,8 +172,8 @@ class ISA protected: - bool isHyperPriv() { return (hpstate & (1 << 2)); } - bool isPriv() { return (hpstate & (1 << 2)) || (pstate & (1 << 2)); } + bool isHyperPriv() { return hpstate.hpriv; } + bool isPriv() { return hpstate.hpriv || pstate.priv; } bool isNonPriv() { return !isPriv(); } public: diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa index d38df1c25..3b3974cbf 100644 --- a/src/arch/sparc/isa/base.isa +++ b/src/arch/sparc/isa/base.isa @@ -567,8 +567,8 @@ output exec {{ checkFpEnableFault(%(CPU_exec_context)s *xc) { if (FullSystem) { - if (xc->readMiscReg(MISCREG_PSTATE) & PSTATE::pef && - xc->readMiscReg(MISCREG_FPRS) & 0x4) { + PSTATE pstate = xc->readMiscReg(MISCREG_PSTATE); + if (pstate.pef && xc->readMiscReg(MISCREG_FPRS) & 0x4) { return NoFault; } else { return new FpDisabled; diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index a05cb94f7..44d2643c6 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -139,7 +139,7 @@ decode OP default Unknown::unknown() } 0x1: BranchN::call(30, {{ IntReg midVal; - R15 = midVal = (Pstate<3:> ? (PC)<31:0> : PC); + R15 = midVal = (Pstate.am ? (PC)<31:0> : PC); NNPC = midVal + disp; }},None, None, IsIndirectControl, IsCall); 0x2: decode OP3 { @@ -327,7 +327,7 @@ decode OP default Unknown::unknown() 0x03: NoPriv::rdasi({{Rd = Asi;}}); 0x04: Priv::rdtick({{Rd = Tick;}}, {{Tick<63:>}}); 0x05: NoPriv::rdpc({{ - if (Pstate<3:>) + if (Pstate.am) Rd = (PC)<31:0>; else Rd = PC; @@ -356,7 +356,7 @@ decode OP default Unknown::unknown() 0x18: Priv::rdstick({{Rd = Stick}}, {{Stick<63:>}}); 0x19: Priv::rdstick_cmpr({{Rd = StickCmpr;}}); 0x1A: Priv::rdstrand_sts_reg({{ - if (Pstate<2:> && !Hpstate<2:>) + if (Pstate.am && !Hpstate.hpriv) Rd = StrandStsReg<0:>; else Rd = StrandStsReg; @@ -479,7 +479,7 @@ decode OP default Unknown::unknown() 0x11: Priv::wrpic({{Pic = Rs1 ^ Rs2_or_imm13;}}, {{Pcr<0:>}}); // 0x12 should cause an illegal instruction exception 0x13: NoPriv::wrgsr({{ - if (Fprs<2:> == 0 || Pstate<4:> == 0) + if (Fprs<2:> == 0 || Pstate.pef == 0) return new FpDisabled; Gsr = Rs1 ^ Rs2_or_imm13; }}); @@ -488,7 +488,7 @@ decode OP default Unknown::unknown() 0x16: Priv::wrsoftint({{Softint = Rs1 ^ Rs2_or_imm13;}}); 0x17: Priv::wrtick_cmpr({{TickCmpr = Rs1 ^ Rs2_or_imm13;}}); 0x18: NoPriv::wrstick({{ - if (!Hpstate<2:>) + if (!Hpstate.hpriv) return new IllegalInstruction; Stick = Rs1 ^ Rs2_or_imm13; }}); @@ -536,7 +536,7 @@ decode OP default Unknown::unknown() 0x05: Priv::wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}}); 0x06: Priv::wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}}); 0x07: Priv::wrprtl({{ - if (Pstate<2:> && !Hpstate<2:>) + if (Pstate.priv && !Hpstate.hpriv) Tl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxPTL); else Tl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxTL); @@ -550,7 +550,7 @@ decode OP default Unknown::unknown() 0x0E: Priv::wrprwstate({{Wstate = Rs1 ^ Rs2_or_imm13;}}); // 0x0F should cause an illegal instruction exception 0x10: Priv::wrprgl({{ - if (Pstate<2:> && !Hpstate<2:>) + if (Pstate.priv && !Hpstate.hpriv) Gl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxPGL); else Gl = std::min<uint64_t>(Rs1 ^ Rs2_or_imm13, MaxGL); @@ -997,7 +997,7 @@ decode OP default Unknown::unknown() if (target & 0x3) { fault = new MemAddressNotAligned; } else { - if (Pstate<3:>) + if (Pstate.am) Rd = (PC)<31:0>; else Rd = PC; diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index a77059181..ffce3063b 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -317,17 +317,17 @@ let {{ # are split into ones that are available in priv and hpriv, and # those that are only available in hpriv AlternateASIPrivFaultCheck = ''' - if ((!bits(Pstate,2,2) && !bits(Hpstate,2,2) && + if ((!Pstate.priv && !Hpstate.hpriv && !asiIsUnPriv((ASI)EXT_ASI)) || - (!bits(Hpstate,2,2) && asiIsHPriv((ASI)EXT_ASI))) + (!Hpstate.hpriv && asiIsHPriv((ASI)EXT_ASI))) fault = new PrivilegedAction; - else if (asiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2)) + else if (asiIsAsIfUser((ASI)EXT_ASI) && !Pstate.priv) fault = new PrivilegedAction; ''' TruncateEA = ''' if (!FullSystem) - EA = Pstate<3:> ? EA<31:0> : EA; + EA = Pstate.am ? EA<31:0> : EA; ''' }}; diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa index 56f1cdbd9..e3242aab8 100644 --- a/src/arch/sparc/isa/formats/priv.isa +++ b/src/arch/sparc/isa/formats/priv.isa @@ -264,7 +264,7 @@ let {{ }}; def format Priv(code, extraCond=true, checkTl=false, *opt_flags) {{ - checkCode = "(%s) && !(Pstate<2:> || Hpstate<2:>)" % extraCond + checkCode = "(%s) && !(Pstate.priv || Hpstate.hpriv)" % extraCond if checkTl != "false": tlCheck = "Tl == 0" else: @@ -289,7 +289,7 @@ def format NoPriv(code, checkTl=false, *opt_flags) {{ }}; def format HPriv(code, checkTl=false, *opt_flags) {{ - checkCode = "!Hpstate<2:2>" + checkCode = "!Hpstate.hpriv" if checkTl != "false": tlCheck = "Tl == 0" else: diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index 425f6c317..32a39bbee 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.isa @@ -40,7 +40,10 @@ def operand_types {{ 'tudw' : 'Twin64_t', 'tuw' : 'Twin32_t', 'sf' : 'float', - 'df' : 'double' + 'df' : 'double', + + 'pstate' : 'PSTATE', + 'hpstate' : 'HPSTATE' }}; output header {{ @@ -167,7 +170,7 @@ def operands {{ 'Tt': ('ControlReg', 'udw', 'MISCREG_TT', None, 56), 'Tick': ('ControlReg', 'udw', 'MISCREG_TICK', None, 57), 'Tba': ('ControlReg', 'udw', 'MISCREG_TBA', None, 58), - 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 59), + 'Pstate': ('ControlReg', 'pstate', 'MISCREG_PSTATE', None, 59), 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 60), 'Pil': ('ControlReg', 'udw', 'MISCREG_PIL', None, 61), 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 62), @@ -183,7 +186,7 @@ def operands {{ 'Wstate': ('IntReg', 'udw', 'NumIntArchRegs + 7', None, 67), 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 68), - 'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 69), + 'Hpstate': ('ControlReg', 'hpstate', 'MISCREG_HPSTATE', None, 69), 'Htstate': ('ControlReg', 'udw', 'MISCREG_HTSTATE', None, 70), 'Hintp': ('ControlReg', 'udw', 'MISCREG_HINTP', None, 71), 'Htba': ('ControlReg', 'udw', 'MISCREG_HTBA', None, 72), diff --git a/src/arch/sparc/miscregs.hh b/src/arch/sparc/miscregs.hh index 890013ec0..7008b6b36 100644 --- a/src/arch/sparc/miscregs.hh +++ b/src/arch/sparc/miscregs.hh @@ -32,6 +32,7 @@ #ifndef __ARCH_SPARC_MISCREGS_HH__ #define __ARCH_SPARC_MISCREGS_HH__ +#include "base/bitunion.hh" #include "base/types.hh" namespace SparcISA @@ -115,26 +116,25 @@ enum MiscRegIndex MISCREG_NUMMISCREGS }; -struct HPSTATE -{ - const static uint64_t id = 0x800; // this impl. dependent (id) field m - const static uint64_t ibe = 0x400; - const static uint64_t red = 0x20; - const static uint64_t hpriv = 0x4; - const static uint64_t tlz = 0x1; -}; - - -struct PSTATE -{ - const static int cle = 0x200; - const static int tle = 0x100; - const static int mm = 0xC0; - const static int pef = 0x10; - const static int am = 0x8; - const static int priv = 0x4; - const static int ie = 0x2; -}; +BitUnion64(HPSTATE) + Bitfield<0> tlz; + Bitfield<2> hpriv; + Bitfield<5> red; + Bitfield<10> ibe; + Bitfield<11> id; // this impl. dependent (id) field m +EndBitUnion(HPSTATE) + +BitUnion16(PSTATE) + Bitfield<1> ie; + Bitfield<2> priv; + Bitfield<3> am; + Bitfield<4> pef; + Bitfield<6, 7> mm; + Bitfield<8> tle; + Bitfield<9> cle; + Bitfield<10> pid0; + Bitfield<11> pid1; +EndBitUnion(PSTATE) struct STS { diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index cc39ecf31..769f15497 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -161,7 +161,10 @@ Sparc32LiveProcess::initState() ThreadContext *tc = system->getThreadContext(contextIds[0]); // The process runs in user mode with 32 bit addresses - tc->setMiscReg(MISCREG_PSTATE, 0x0a); + PSTATE pstate = 0; + pstate.ie = 1; + pstate.am = 1; + tc->setMiscReg(MISCREG_PSTATE, pstate); argsInit(32 / 8, VMPageSize); } @@ -173,7 +176,9 @@ Sparc64LiveProcess::initState() ThreadContext *tc = system->getThreadContext(contextIds[0]); // The process runs in user mode - tc->setMiscReg(MISCREG_PSTATE, 0x02); + PSTATE pstate = 0; + pstate.ie = 1; + tc->setMiscReg(MISCREG_PSTATE, pstate); argsInit(sizeof(IntReg), VMPageSize); } @@ -533,27 +538,22 @@ SparcLiveProcess::setSyscallReturn(ThreadContext *tc, // check for error condition. SPARC syscall convention is to // indicate success/failure in reg the carry bit of the ccr // and put the return value itself in the standard return value reg (). + PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); if (return_value.successful()) { // no error, clear XCC.C tc->setIntReg(NumIntArchRegs + 2, tc->readIntReg(NumIntArchRegs + 2) & 0xEE); - // tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE); IntReg val = return_value.value(); - if (bits(tc->readMiscRegNoEffect( - SparcISA::MISCREG_PSTATE), 3, 3)) { + if (pstate.am) val = bits(val, 31, 0); - } tc->setIntReg(ReturnValueReg, val); } else { // got an error, set XCC.C tc->setIntReg(NumIntArchRegs + 2, tc->readIntReg(NumIntArchRegs + 2) | 0x11); - // tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11); IntReg val = -return_value.value(); - if (bits(tc->readMiscRegNoEffect( - SparcISA::MISCREG_PSTATE), 3, 3)) { + if (pstate.am) val = bits(val, 31, 0); - } tc->setIntReg(ReturnValueReg, val); } } diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc index ece6ec963..1298e327e 100644 --- a/src/arch/sparc/remote_gdb.cc +++ b/src/arch/sparc/remote_gdb.cc @@ -181,9 +181,9 @@ RemoteGDB::getregs() memset(gdbregs.regs, 0, gdbregs.size); PCState pc = context->pcState(); + PSTATE pstate = context->readMiscReg(MISCREG_PSTATE); - if (context->readMiscReg(MISCREG_PSTATE) & - PSTATE::am) { + if (pstate.am) { uint32_t *regs; regs = (uint32_t*)gdbregs.regs; regs[Reg32Pc] = htobe((uint32_t)pc.pc()); @@ -192,7 +192,7 @@ RemoteGDB::getregs() regs[x] = htobe((uint32_t)context->readIntReg(x - RegG0)); regs[Reg32Y] = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 1)); - regs[Reg32Psr] = htobe((uint32_t)context->readMiscReg(MISCREG_PSTATE)); + regs[Reg32Psr] = htobe((uint32_t)pstate); regs[Reg32Fsr] = htobe((uint32_t)context->readMiscReg(MISCREG_FSR)); regs[Reg32Csr] = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 2)); } else { @@ -206,7 +206,7 @@ RemoteGDB::getregs() gdbregs.regs[RegY] = htobe(context->readIntReg(NumIntArchRegs + 1)); gdbregs.regs[RegState] = htobe( context->readMiscReg(MISCREG_CWP) | - context->readMiscReg(MISCREG_PSTATE) << 8 | + pstate << 8 | context->readMiscReg(MISCREG_ASI) << 24 | context->readIntReg(NumIntArchRegs + 2) << 32); } diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index e6ab64de9..5948e0713 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -206,13 +206,18 @@ ISA::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) break; case MISCREG_HPSTATE: - // T1000 spec says impl. dependent val must always be 1 - setMiscRegNoEffect(miscReg, val | HPSTATE::id); - if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv)) - cpu->postInterrupt(IT_TRAP_LEVEL_ZERO, 0); - else - cpu->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0); - break; + { + HPSTATE newVal = val; + newVal.id = 1; + // T1000 spec says impl. dependent val must always be 1 + setMiscRegNoEffect(miscReg, newVal); + newVal = hpstate; + if (newVal.tlz && tl == 0 && !newVal.hpriv) + cpu->postInterrupt(IT_TRAP_LEVEL_ZERO, 0); + else + cpu->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0); + break; + } case MISCREG_HTSTATE: setMiscRegNoEffect(miscReg, val); break; diff --git a/src/arch/sparc/utility.hh b/src/arch/sparc/utility.hh index ee94ef29a..b8e3b3f0e 100644 --- a/src/arch/sparc/utility.hh +++ b/src/arch/sparc/utility.hh @@ -58,8 +58,9 @@ uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp); static inline bool inUserMode(ThreadContext *tc) { - return !((tc->readMiscRegNoEffect(MISCREG_PSTATE) & (1 << 2)) || - (tc->readMiscRegNoEffect(MISCREG_HPSTATE) & (1 << 2))); + PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); + HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); + return !(pstate.priv || hpstate.hpriv); } /** |