clean up fault code a little bit

simplify and make complete some asi checks
implement all the twin asis and remove panic checks on their use
soft int is supported, so we don't need to print writes to it

src/arch/sparc/asi.cc:
    make AsiIsLittle() be all the little asis.
    Speed up AsiIsTwin() a bit
src/arch/sparc/faults.cc:
    clean up the do*Fault code.... Make it work like legion, in particular
    pstate.priv is left alone, not set to 0 like the spec says
src/arch/sparc/isa/decoder.isa:
    implement some more twin ASIs
src/arch/sparc/tlb.cc:
    All the twin asis are implemented, no need to say their not supported anymore
src/arch/sparc/ua2005.cc:
    softint is supported now, no more need to

--HG--
extra : convert_revision : aef2a1b93719235edff830a17a8ec52f23ec9f8b
This commit is contained in:
Ali Saidi 2007-01-22 21:55:43 -05:00
parent 3011fc6311
commit 5f662d451e
5 changed files with 39 additions and 76 deletions

View file

@ -179,26 +179,23 @@ namespace SparcISA
(asi == ASI_LDTX_PL) ||
(asi == ASI_LDTX_SL) ||
(asi == ASI_BLK_PL) ||
(asi == ASI_BLK_SL);
(asi == ASI_BLK_SL) ||
(asi == ASI_LTX_L);
}
bool AsiIsTwin(ASI asi)
{
return
(asi == ASI_QUAD_LDD) ||
(asi == ASI_LDTX_AIUP) ||
(asi == ASI_LDTX_AIUS) ||
(asi == ASI_LDTX_REAL) ||
(asi == ASI_LDTX_N) ||
(asi == ASI_LDTX_AIUP_L) ||
(asi == ASI_LDTX_AIUS_L) ||
(asi == ASI_LDTX_REAL_L) ||
(asi == ASI_LDTX_NL) ||
(asi == ASI_LDTX_P) ||
(asi == ASI_LDTX_S) ||
(asi == ASI_LDTX_PL) ||
(asi == ASI_LDTX_SL) ||
(asi == ASI_LTX_L);
(asi >= ASI_LDTX_AIUP &&
asi <= ASI_LDTX_N &&
asi != ASI_QUEUE) ||
(asi >= ASI_LDTX_AIUP_L &&
asi <= ASI_LDTX_NL &&
asi != 0x2D) ||
asi == ASI_LDTX_P ||
asi == ASI_LDTX_S ||
asi == ASI_LDTX_PL ||
asi == ASI_LDTX_SL;
}
bool AsiIsPartialStore(ASI asi)

View file

@ -340,22 +340,8 @@ void doREDFault(ThreadContext *tc, TrapType tt)
//Update GL
tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
//set PSTATE.mm to 00
//set PSTATE.pef to 1
PSTATE |= (1 << 4);
//set PSTATE.am to 0
PSTATE &= ~(1 << 3);
/* //set PSTATE.priv to 0
PSTATE &= ~(1 << 2);*/
//set PSTATE.ie to 0
//PSTATE.priv is set to 1 here. The manual says it should be 0, but
//Legion sets it to 1.
PSTATE |= (1 << 2);
//set PSTATE.cle to 0
PSTATE &= ~(1 << 9);
//PSTATE.tle is unchanged
//XXX Where is the tct bit?
//set PSTATE.tct to 0
PSTATE = mbits(PSTATE, 2, 2); // just save the priv bit
PSTATE |= (1 << 4); //set PSTATE.pef to 1
tc->setMiscReg(MISCREG_PSTATE, PSTATE);
//set HPSTATE.red to 1
@ -442,46 +428,27 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
tc->setMiscRegWithEffect(MISCREG_GL, min<int>(GL+1, MaxGL));
//PSTATE.mm is unchanged
//PSTATE.pef = whether or not an fpu is present
//XXX We'll say there's one present, even though there aren't
//implementations for a decent number of the instructions
PSTATE |= (1 << 4);
//PSTATE.am = 0
PSTATE &= ~(1 << 3);
if (!gotoHpriv)
{
//PSTATE.priv = 1
PSTATE |= (1 << 2);
//PSTATE.cle = PSTATE.tle
replaceBits(PSTATE, 9, 9, PSTATE >> 8);
}
else
{
//PSTATE.priv = 0
//PSTATE.priv is set to 1 here. The manual says it should be 0, but
//Legion sets it to 1.
PSTATE |= (1 << 2);
//PSTATE.cle = 0
PSTATE &= ~(1 << 9);
}
//PSTATE.ie = 0
PSTATE &= ~(1 << 1);
PSTATE |= (1 << 4); //PSTATE.pef = whether or not an fpu is present
PSTATE &= ~(1 << 3); //PSTATE.am = 0
PSTATE &= ~(1 << 1); //PSTATE.ie = 0
//PSTATE.tle is unchanged
//PSTATE.tct = 0
//XXX Where exactly is this field?
tc->setMiscReg(MISCREG_PSTATE, PSTATE);
if (gotoHpriv)
{
//HPSTATE.red = 0
HPSTATE &= ~(1 << 5);
//HPSTATE.hpriv = 1
HPSTATE |= (1 << 2);
//HPSTATE.ibe = 0
HPSTATE &= ~(1 << 10);
PSTATE &= ~(1 << 9); // PSTATE.cle = 0
//The manual says PSTATE.priv should be 0, but Legion leaves it alone
HPSTATE &= ~(1 << 5); //HPSTATE.red = 0
HPSTATE |= (1 << 2); //HPSTATE.hpriv = 1
HPSTATE &= ~(1 << 10); //HPSTATE.ibe = 0
//HPSTATE.tlz is unchanged
tc->setMiscReg(MISCREG_HPSTATE, HPSTATE);
} else { // we are going to priv
PSTATE |= (1 << 2); //PSTATE.priv = 1
replaceBits(PSTATE, 9, 9, PSTATE >> 8); //PSTATE.cle = PSTATE.tle
}
tc->setMiscReg(MISCREG_PSTATE, PSTATE);
bool changedCWP = true;
if (tt == 0x24)

View file

@ -1061,6 +1061,12 @@ decode OP default Unknown::unknown()
0x11: lduba({{Rd = Mem.ub;}}, {{EXT_ASI}});
0x12: lduha({{Rd = Mem.uhw;}}, {{EXT_ASI}});
0x13: decode EXT_ASI {
//ASI_LDTD_AIUP
0x22: TwinLoad::ldtx_aiup(
{{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
//ASI_LDTD_AIUS
0x23: TwinLoad::ldtx_aius(
{{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
//ASI_QUAD_LDD
0x24: TwinLoad::ldtx_quad_ldd(
{{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
@ -1082,6 +1088,9 @@ decode OP default Unknown::unknown()
//ASI_LDTX_P
0xE2: TwinLoad::ldtx_p(
{{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
//ASI_LDTX_S
0xE3: TwinLoad::ldtx_s(
{{RdTwin.udw = Mem.udw}}, {{EXT_ASI}});
default: ldtwa({{
uint64_t val = Mem.udw;
RdLow = val<31:0>;

View file

@ -662,7 +662,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
}
}
if (!implicit) {
if (!implicit && asi != ASI_P && asi != ASI_S) {
if (AsiIsLittle(asi))
panic("Little Endian ASIs not supported\n");
if (AsiIsBlock(asi))
@ -670,14 +670,6 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
if (AsiIsNoFault(asi))
panic("No Fault ASIs not supported\n");
// These twin ASIs are OK
if (asi == ASI_P || asi == ASI_LDTX_P)
goto continueDtbFlow;
if (!write && (asi == ASI_QUAD_LDD || asi == ASI_LDTX_REAL))
goto continueDtbFlow;
if (AsiIsTwin(asi))
panic("Twin ASIs not supported\n");
if (AsiIsPartialStore(asi))
panic("Partial Store ASIs not supported\n");
if (AsiIsInterrupt(asi))
@ -692,11 +684,11 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
if (AsiIsSparcError(asi))
goto handleSparcErrorRegAccess;
if (!AsiIsReal(asi) && !AsiIsNucleus(asi) && !AsiIsAsIfUser(asi))
if (!AsiIsReal(asi) && !AsiIsNucleus(asi) && !AsiIsAsIfUser(asi) &&
!AsiIsTwin(asi))
panic("Accessing ASI %#X. Should we?\n", asi);
}
continueDtbFlow:
// If the asi is unaligned trap
if (vaddr & size-1) {
writeSfr(tc, vaddr, false, ct, false, OtherFault, asi);

View file

@ -43,8 +43,6 @@ MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
/* Full system only ASRs */
case MISCREG_SOFTINT:
setReg(miscReg, val);;
if (val != 0x10000 && val != 0)
warn("Writing to softint not really supported, writing: %#x\n", val);
break;
case MISCREG_SOFTINT_CLR: