{
//@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);
}
/**
{
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);
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);
// 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);
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);
// 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)
{
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);
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
// 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);
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);
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;
// 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
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);
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;
// 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;
}
if (interrupts[IT_RES_ERROR]) {
return new ResumableError;
}
- } // !hpriv && ie
+ } // !hpriv && pstate.ie
} // !hpriv
return NoFault;
}
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()
// 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;
* |^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 |
case MISCREG_TBA:
return tba;
case MISCREG_PSTATE:
- return pstate;
+ return (MiscReg)pstate;
case MISCREG_TL:
return tl;
case MISCREG_PIL:
/** Hyper privileged registers */
case MISCREG_HPSTATE:
- return hpstate;
+ return (MiscReg)hpstate;
case MISCREG_HTSTATE:
return htstate[tl-1];
case MISCREG_HINTP:
tba = val & ULL(~0x7FFF);
break;
case MISCREG_PSTATE:
- pstate = (val & PSTATE_MASK);
+ pstate = (val & PstateMask);
break;
case MISCREG_TL:
tl = val;
// 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)
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);
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);
// 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
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
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:
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;
}
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 {
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;
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;
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;
}});
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;
}});
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);
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);
if (target & 0x3) {
fault = new MemAddressNotAligned;
} else {
- if (Pstate<3:>)
+ if (Pstate.am)
Rd = (PC)<31:0>;
else
Rd = PC;
# 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;
'''
}};
}};
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:
}};
def format HPriv(code, checkTl=false, *opt_flags) {{
- checkCode = "!Hpstate<2:2>"
+ checkCode = "!Hpstate.hpriv"
if checkTl != "false":
tlCheck = "Tl == 0"
else:
'tudw' : 'Twin64_t',
'tuw' : 'Twin32_t',
'sf' : 'float',
- 'df' : 'double'
+ 'df' : 'double',
+
+ 'pstate' : 'PSTATE',
+ 'hpstate' : 'HPSTATE'
}};
output header {{
'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),
'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),
#ifndef __ARCH_SPARC_MISCREGS_HH__
#define __ARCH_SPARC_MISCREGS_HH__
+#include "base/bitunion.hh"
#include "base/types.hh"
namespace SparcISA
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
{
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);
}
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);
}
// 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);
}
}
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());
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 {
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);
}
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;
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);
}
/**