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