some formatting changes, and update how I do bitfields for HPSTATE and PSTATE to avoid name confusion.
src/arch/sparc/faults.cc: 1) s/Resumeable/Resumable/gc 2) s/if(/if (/gc 3) keep variables lowercase 4) change the way fields are accessed - instead of hard coding bitvectors, use masks (like HPSTATE::hpriv). src/arch/sparc/faults.hh: s/Resumeable/Resumable/ src/arch/sparc/isa_traits.hh: This is unused and unnecessary. src/arch/sparc/miscregfile.hh: add bitfield masks for some important ASRs (HPSTATE, PSTATE). --HG-- extra : convert_revision : f0ffaf48de298758685266dfb90f43aff42e0a2c
This commit is contained in:
parent
a8b2d66661
commit
b45219e7ae
4 changed files with 37 additions and 44 deletions
|
@ -240,7 +240,7 @@ template<> SparcFaultBase::FaultVals
|
||||||
{"dev_mondo", 0x07D, 1611, {P, P, SH}};
|
{"dev_mondo", 0x07D, 1611, {P, P, SH}};
|
||||||
|
|
||||||
template<> SparcFaultBase::FaultVals
|
template<> SparcFaultBase::FaultVals
|
||||||
SparcFault<ResumeableError>::vals =
|
SparcFault<ResumableError>::vals =
|
||||||
{"resume_error", 0x07E, 3330, {P, P, SH}};
|
{"resume_error", 0x07E, 3330, {P, P, SH}};
|
||||||
|
|
||||||
template<> SparcFaultBase::FaultVals
|
template<> SparcFaultBase::FaultVals
|
||||||
|
@ -436,7 +436,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
|
||||||
tc->setMiscReg(MISCREG_TT, tt);
|
tc->setMiscReg(MISCREG_TT, tt);
|
||||||
|
|
||||||
//Update the global register level
|
//Update the global register level
|
||||||
if(!gotoHpriv)
|
if (!gotoHpriv)
|
||||||
tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxPGL));
|
tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxPGL));
|
||||||
else
|
else
|
||||||
tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
|
tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
|
||||||
|
@ -448,7 +448,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
|
||||||
PSTATE |= (1 << 4);
|
PSTATE |= (1 << 4);
|
||||||
//PSTATE.am = 0
|
//PSTATE.am = 0
|
||||||
PSTATE &= ~(1 << 3);
|
PSTATE &= ~(1 << 3);
|
||||||
if(!gotoHpriv)
|
if (!gotoHpriv)
|
||||||
{
|
{
|
||||||
//PSTATE.priv = 1
|
//PSTATE.priv = 1
|
||||||
PSTATE |= (1 << 2);
|
PSTATE |= (1 << 2);
|
||||||
|
@ -471,7 +471,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
|
||||||
//XXX Where exactly is this field?
|
//XXX Where exactly is this field?
|
||||||
tc->setMiscReg(MISCREG_PSTATE, PSTATE);
|
tc->setMiscReg(MISCREG_PSTATE, PSTATE);
|
||||||
|
|
||||||
if(gotoHpriv)
|
if (gotoHpriv)
|
||||||
{
|
{
|
||||||
//HPSTATE.red = 0
|
//HPSTATE.red = 0
|
||||||
HPSTATE &= ~(1 << 5);
|
HPSTATE &= ~(1 << 5);
|
||||||
|
@ -484,16 +484,16 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool changedCWP = true;
|
bool changedCWP = true;
|
||||||
if(tt == 0x24)
|
if (tt == 0x24)
|
||||||
CWP++;
|
CWP++;
|
||||||
else if(0x80 <= tt && tt <= 0xbf)
|
else if (0x80 <= tt && tt <= 0xbf)
|
||||||
CWP += (CANSAVE + 2);
|
CWP += (CANSAVE + 2);
|
||||||
else if(0xc0 <= tt && tt <= 0xff)
|
else if (0xc0 <= tt && tt <= 0xff)
|
||||||
CWP--;
|
CWP--;
|
||||||
else
|
else
|
||||||
changedCWP = false;
|
changedCWP = false;
|
||||||
|
|
||||||
if(changedCWP)
|
if (changedCWP)
|
||||||
{
|
{
|
||||||
CWP = (CWP + NWindows) % NWindows;
|
CWP = (CWP + NWindows) % NWindows;
|
||||||
tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
|
tc->setMiscRegWithEffect(MISCREG_CWP, CWP);
|
||||||
|
@ -534,45 +534,45 @@ void SparcFaultBase::invoke(ThreadContext * tc)
|
||||||
|
|
||||||
//We can refer to this to see what the trap level -was-, but something
|
//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.
|
//in the middle could change it in the regfile out from under us.
|
||||||
MiscReg TL = tc->readMiscReg(MISCREG_TL);
|
MiscReg tl = tc->readMiscReg(MISCREG_TL);
|
||||||
MiscReg TT = tc->readMiscReg(MISCREG_TT);
|
MiscReg tt = tc->readMiscReg(MISCREG_TT);
|
||||||
MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
|
MiscReg pstate = tc->readMiscReg(MISCREG_PSTATE);
|
||||||
MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
|
MiscReg hpstate = tc->readMiscReg(MISCREG_HPSTATE);
|
||||||
|
|
||||||
Addr PC, NPC;
|
Addr PC, NPC;
|
||||||
|
|
||||||
PrivilegeLevel current;
|
PrivilegeLevel current;
|
||||||
if(HPSTATE & (1 << 2))
|
if (hpstate & HPSTATE::hpriv)
|
||||||
current = Hyperprivileged;
|
current = Hyperprivileged;
|
||||||
else if(PSTATE & (1 << 2))
|
else if (pstate & PSTATE::priv)
|
||||||
current = Privileged;
|
current = Privileged;
|
||||||
else
|
else
|
||||||
current = User;
|
current = User;
|
||||||
|
|
||||||
PrivilegeLevel level = getNextLevel(current);
|
PrivilegeLevel level = getNextLevel(current);
|
||||||
|
|
||||||
if(HPSTATE & (1 << 5) || TL == MaxTL - 1) {
|
if ((hpstate & 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
|
||||||
//save the old version on the trap stack in doREDFault.
|
//save the old version on the trap stack in doREDFault.
|
||||||
enterREDState(tc);
|
enterREDState(tc);
|
||||||
} else if(TL == MaxTL) {
|
} else if (tl == MaxTL) {
|
||||||
panic("Should go to error state here.. crap\n");
|
panic("Should go to error state here.. crap\n");
|
||||||
//Do error_state somehow?
|
//Do error_state somehow?
|
||||||
//Probably inject a WDR fault using the interrupt mechanism.
|
//Probably inject a WDR fault using the interrupt mechanism.
|
||||||
//What should the PC and NPC be set to?
|
//What should the PC and NPC be set to?
|
||||||
} else if(TL > MaxPTL && level == Privileged) {
|
} else if (tl > MaxPTL && level == Privileged) {
|
||||||
//guest_watchdog fault
|
//guest_watchdog fault
|
||||||
doNormalFault(tc, trapType(), true);
|
doNormalFault(tc, trapType(), true);
|
||||||
getHyperVector(tc, PC, NPC, 2);
|
getHyperVector(tc, PC, NPC, 2);
|
||||||
} else if(level == Hyperprivileged ||
|
} else if (level == Hyperprivileged ||
|
||||||
level == Privileged && trapType() >= 384) {
|
level == Privileged && trapType() >= 384) {
|
||||||
doNormalFault(tc, trapType(), true);
|
doNormalFault(tc, trapType(), true);
|
||||||
getHyperVector(tc, PC, NPC, trapType());
|
getHyperVector(tc, PC, NPC, trapType());
|
||||||
} else {
|
} else {
|
||||||
doNormalFault(tc, trapType(), false);
|
doNormalFault(tc, trapType(), false);
|
||||||
getPrivVector(tc, PC, NPC, trapType(), TL+1);
|
getPrivVector(tc, PC, NPC, trapType(), tl+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
tc->setPC(PC);
|
tc->setPC(PC);
|
||||||
|
|
|
@ -210,7 +210,7 @@ class CpuMondo : public SparcFault<CpuMondo> {};
|
||||||
|
|
||||||
class DevMondo : public SparcFault<DevMondo> {};
|
class DevMondo : public SparcFault<DevMondo> {};
|
||||||
|
|
||||||
class ResumeableError : public SparcFault<ResumeableError> {};
|
class ResumableError : public SparcFault<ResumableError> {};
|
||||||
|
|
||||||
class SpillNNormal : public EnumeratedFault<SpillNNormal>
|
class SpillNNormal : public EnumeratedFault<SpillNNormal>
|
||||||
{
|
{
|
||||||
|
|
|
@ -96,15 +96,6 @@ namespace SparcISA
|
||||||
StaticInstPtr decodeInst(ExtMachInst);
|
StaticInstPtr decodeInst(ExtMachInst);
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
////////// Interrupt Stuff ///////////
|
|
||||||
enum InterruptLevels
|
|
||||||
{
|
|
||||||
INTLEVEL_MIN = 1,
|
|
||||||
INTLEVEL_MAX = 15,
|
|
||||||
|
|
||||||
NumInterruptLevels = INTLEVEL_MAX - INTLEVEL_MIN
|
|
||||||
};
|
|
||||||
|
|
||||||
// I don't know what it's for, so I don't
|
// I don't know what it's for, so I don't
|
||||||
// know what SPARC's value should be
|
// know what SPARC's value should be
|
||||||
// For loading... XXX This maybe could be USegEnd?? --ali
|
// For loading... XXX This maybe could be USegEnd?? --ali
|
||||||
|
|
|
@ -142,24 +142,26 @@ namespace SparcISA
|
||||||
MISCREG_NUMMISCREGS
|
MISCREG_NUMMISCREGS
|
||||||
};
|
};
|
||||||
|
|
||||||
enum HPStateFields {
|
struct HPSTATE {
|
||||||
id = 0x800, // this impl. dependent (id) field must always be '1' for T1000
|
const static uint64_t id = 0x800; // this impl. dependent (id) field m
|
||||||
ibe = 0x400,
|
const static uint64_t ibe = 0x400;
|
||||||
red = 0x20,
|
const static uint64_t red = 0x20;
|
||||||
hpriv = 0x4,
|
const static uint64_t hpriv = 0x4;
|
||||||
tlz = 0x1
|
const static uint64_t tlz = 0x1;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PStateFields {
|
|
||||||
cle = 0x200,
|
struct PSTATE {
|
||||||
tle = 0x100,
|
const static int cle = 0x200;
|
||||||
mm = 0xC0,
|
const static int tle = 0x100;
|
||||||
pef = 0x10,
|
const static int mm = 0xC0;
|
||||||
am = 0x8,
|
const static int pef = 0x10;
|
||||||
priv = 0x4,
|
const static int am = 0x8;
|
||||||
ie = 0x2
|
const static int priv = 0x4;
|
||||||
|
const static int ie = 0x2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const int NumMiscArchRegs = MISCREG_NUMMISCREGS;
|
const int NumMiscArchRegs = MISCREG_NUMMISCREGS;
|
||||||
const int NumMiscRegs = MISCREG_NUMMISCREGS;
|
const int NumMiscRegs = MISCREG_NUMMISCREGS;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue