SPARC: Move tlb state into the tlb.
Each "strand" may need to have a private copy of this state, but I couldn't find anywhere in the spec that said that after looking briefly. This prevents writes to the thread context in o3 which was causing the pipeline to be flushed and stopping any forward progress. The other ASI accessible state will probably need to be accessed differently if/when we get O3 full system up and running. --HG-- extra : convert_revision : fa7fba812d7f76564ef4a23818e60f536710d557
This commit is contained in:
parent
26853e11c0
commit
e99c56f971
5 changed files with 175 additions and 352 deletions
|
@ -54,11 +54,7 @@ string SparcISA::getMiscRegName(RegIndex index)
|
|||
"wstate",*/ "gl",
|
||||
"hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
|
||||
"hstick_cmpr",
|
||||
"fsr", "prictx", "secctx", "partId", "lsuCtrlReg", "itbTsbC0Ps0",
|
||||
"itbTsbC0Ps1", "iTlbC0Cnfg", "itbTsbCXPs0", "itbTsbCXPs1",
|
||||
"iTlbCXCnfg","iTlbSfsr", "iTlbTagAcs", "dtbTsbC0Ps0",
|
||||
"dtbTsbC0Ps1", "dTlbC0Cnfg", "dtbTsbCXPs0", "dtbTsbCXPs1",
|
||||
"dTlbCXCnfg","dTlbSfsr", "dTlbSfar", "dTlbTagAcs",
|
||||
"fsr", "prictx", "secctx", "partId", "lsuCtrlReg",
|
||||
"scratch0", "scratch1", "scratch2", "scratch3", "scratch4",
|
||||
"scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail",
|
||||
"devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail",
|
||||
|
@ -113,25 +109,6 @@ void MiscRegFile::clear()
|
|||
partId = 0;
|
||||
lsuCtrlReg = 0;
|
||||
|
||||
iTlbC0TsbPs0 = 0;
|
||||
iTlbC0TsbPs1 = 0;
|
||||
iTlbC0Config = 0;
|
||||
iTlbCXTsbPs0 = 0;
|
||||
iTlbCXTsbPs1 = 0;
|
||||
iTlbCXConfig = 0;
|
||||
iTlbSfsr = 0;
|
||||
iTlbTagAccess = 0;
|
||||
|
||||
dTlbC0TsbPs0 = 0;
|
||||
dTlbC0TsbPs1 = 0;
|
||||
dTlbC0Config = 0;
|
||||
dTlbCXTsbPs0 = 0;
|
||||
dTlbCXTsbPs1 = 0;
|
||||
dTlbCXConfig = 0;
|
||||
dTlbSfsr = 0;
|
||||
dTlbSfar = 0;
|
||||
dTlbTagAccess = 0;
|
||||
|
||||
memset(scratchPad, 0, sizeof(scratchPad));
|
||||
#if FULL_SYSTEM
|
||||
tickCompare = NULL;
|
||||
|
@ -262,42 +239,6 @@ MiscReg MiscRegFile::readRegNoEffect(int miscReg)
|
|||
case MISCREG_MMU_LSU_CTRL:
|
||||
return lsuCtrlReg;
|
||||
|
||||
case MISCREG_MMU_ITLB_C0_TSB_PS0:
|
||||
return iTlbC0TsbPs0;
|
||||
case MISCREG_MMU_ITLB_C0_TSB_PS1:
|
||||
return iTlbC0TsbPs1;
|
||||
case MISCREG_MMU_ITLB_C0_CONFIG:
|
||||
return iTlbC0Config;
|
||||
case MISCREG_MMU_ITLB_CX_TSB_PS0:
|
||||
return iTlbCXTsbPs0;
|
||||
case MISCREG_MMU_ITLB_CX_TSB_PS1:
|
||||
return iTlbCXTsbPs1;
|
||||
case MISCREG_MMU_ITLB_CX_CONFIG:
|
||||
return iTlbCXConfig;
|
||||
case MISCREG_MMU_ITLB_SFSR:
|
||||
return iTlbSfsr;
|
||||
case MISCREG_MMU_ITLB_TAG_ACCESS:
|
||||
return iTlbTagAccess;
|
||||
|
||||
case MISCREG_MMU_DTLB_C0_TSB_PS0:
|
||||
return dTlbC0TsbPs0;
|
||||
case MISCREG_MMU_DTLB_C0_TSB_PS1:
|
||||
return dTlbC0TsbPs1;
|
||||
case MISCREG_MMU_DTLB_C0_CONFIG:
|
||||
return dTlbC0Config;
|
||||
case MISCREG_MMU_DTLB_CX_TSB_PS0:
|
||||
return dTlbCXTsbPs0;
|
||||
case MISCREG_MMU_DTLB_CX_TSB_PS1:
|
||||
return dTlbCXTsbPs1;
|
||||
case MISCREG_MMU_DTLB_CX_CONFIG:
|
||||
return dTlbCXConfig;
|
||||
case MISCREG_MMU_DTLB_SFSR:
|
||||
return dTlbSfsr;
|
||||
case MISCREG_MMU_DTLB_SFAR:
|
||||
return dTlbSfar;
|
||||
case MISCREG_MMU_DTLB_TAG_ACCESS:
|
||||
return dTlbTagAccess;
|
||||
|
||||
case MISCREG_SCRATCHPAD_R0:
|
||||
return scratchPad[0];
|
||||
case MISCREG_SCRATCHPAD_R1:
|
||||
|
@ -519,59 +460,6 @@ void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val)
|
|||
lsuCtrlReg = val;
|
||||
break;
|
||||
|
||||
case MISCREG_MMU_ITLB_C0_TSB_PS0:
|
||||
iTlbC0TsbPs0 = val;
|
||||
break;
|
||||
case MISCREG_MMU_ITLB_C0_TSB_PS1:
|
||||
iTlbC0TsbPs1 = val;
|
||||
break;
|
||||
case MISCREG_MMU_ITLB_C0_CONFIG:
|
||||
iTlbC0Config = val;
|
||||
break;
|
||||
case MISCREG_MMU_ITLB_CX_TSB_PS0:
|
||||
iTlbCXTsbPs0 = val;
|
||||
break;
|
||||
case MISCREG_MMU_ITLB_CX_TSB_PS1:
|
||||
iTlbCXTsbPs1 = val;
|
||||
break;
|
||||
case MISCREG_MMU_ITLB_CX_CONFIG:
|
||||
iTlbCXConfig = val;
|
||||
break;
|
||||
case MISCREG_MMU_ITLB_SFSR:
|
||||
iTlbSfsr = val;
|
||||
break;
|
||||
case MISCREG_MMU_ITLB_TAG_ACCESS:
|
||||
iTlbTagAccess = val;
|
||||
break;
|
||||
|
||||
case MISCREG_MMU_DTLB_C0_TSB_PS0:
|
||||
dTlbC0TsbPs0 = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_C0_TSB_PS1:
|
||||
dTlbC0TsbPs1 = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_C0_CONFIG:
|
||||
dTlbC0Config = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_CX_TSB_PS0:
|
||||
dTlbCXTsbPs0 = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_CX_TSB_PS1:
|
||||
dTlbCXTsbPs1 = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_CX_CONFIG:
|
||||
dTlbCXConfig = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_SFSR:
|
||||
dTlbSfsr = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_SFAR:
|
||||
dTlbSfar = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_TAG_ACCESS:
|
||||
dTlbTagAccess = val;
|
||||
break;
|
||||
|
||||
case MISCREG_SCRATCHPAD_R0:
|
||||
scratchPad[0] = val;
|
||||
break;
|
||||
|
@ -733,23 +621,6 @@ void MiscRegFile::serialize(std::ostream & os)
|
|||
SERIALIZE_SCALAR(secContext);
|
||||
SERIALIZE_SCALAR(partId);
|
||||
SERIALIZE_SCALAR(lsuCtrlReg);
|
||||
SERIALIZE_SCALAR(iTlbC0TsbPs0);
|
||||
SERIALIZE_SCALAR(iTlbC0TsbPs1);
|
||||
SERIALIZE_SCALAR(iTlbC0Config);
|
||||
SERIALIZE_SCALAR(iTlbCXTsbPs0);
|
||||
SERIALIZE_SCALAR(iTlbCXTsbPs1);
|
||||
SERIALIZE_SCALAR(iTlbCXConfig);
|
||||
SERIALIZE_SCALAR(iTlbSfsr);
|
||||
SERIALIZE_SCALAR(iTlbTagAccess);
|
||||
SERIALIZE_SCALAR(dTlbC0TsbPs0);
|
||||
SERIALIZE_SCALAR(dTlbC0TsbPs1);
|
||||
SERIALIZE_SCALAR(dTlbC0Config);
|
||||
SERIALIZE_SCALAR(dTlbCXTsbPs0);
|
||||
SERIALIZE_SCALAR(dTlbCXTsbPs1);
|
||||
SERIALIZE_SCALAR(dTlbCXConfig);
|
||||
SERIALIZE_SCALAR(dTlbSfsr);
|
||||
SERIALIZE_SCALAR(dTlbSfar);
|
||||
SERIALIZE_SCALAR(dTlbTagAccess);
|
||||
SERIALIZE_ARRAY(scratchPad,8);
|
||||
SERIALIZE_SCALAR(cpu_mondo_head);
|
||||
SERIALIZE_SCALAR(cpu_mondo_tail);
|
||||
|
@ -827,23 +698,6 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
|
|||
UNSERIALIZE_SCALAR(secContext);
|
||||
UNSERIALIZE_SCALAR(partId);
|
||||
UNSERIALIZE_SCALAR(lsuCtrlReg);
|
||||
UNSERIALIZE_SCALAR(iTlbC0TsbPs0);
|
||||
UNSERIALIZE_SCALAR(iTlbC0TsbPs1);
|
||||
UNSERIALIZE_SCALAR(iTlbC0Config);
|
||||
UNSERIALIZE_SCALAR(iTlbCXTsbPs0);
|
||||
UNSERIALIZE_SCALAR(iTlbCXTsbPs1);
|
||||
UNSERIALIZE_SCALAR(iTlbCXConfig);
|
||||
UNSERIALIZE_SCALAR(iTlbSfsr);
|
||||
UNSERIALIZE_SCALAR(iTlbTagAccess);
|
||||
UNSERIALIZE_SCALAR(dTlbC0TsbPs0);
|
||||
UNSERIALIZE_SCALAR(dTlbC0TsbPs1);
|
||||
UNSERIALIZE_SCALAR(dTlbC0Config);
|
||||
UNSERIALIZE_SCALAR(dTlbCXTsbPs0);
|
||||
UNSERIALIZE_SCALAR(dTlbCXTsbPs1);
|
||||
UNSERIALIZE_SCALAR(dTlbCXConfig);
|
||||
UNSERIALIZE_SCALAR(dTlbSfsr);
|
||||
UNSERIALIZE_SCALAR(dTlbSfar);
|
||||
UNSERIALIZE_SCALAR(dTlbTagAccess);
|
||||
UNSERIALIZE_ARRAY(scratchPad,8);
|
||||
UNSERIALIZE_SCALAR(cpu_mondo_head);
|
||||
UNSERIALIZE_SCALAR(cpu_mondo_tail);
|
||||
|
|
|
@ -100,25 +100,6 @@ namespace SparcISA
|
|||
MISCREG_MMU_PART_ID,
|
||||
MISCREG_MMU_LSU_CTRL,
|
||||
|
||||
MISCREG_MMU_ITLB_C0_TSB_PS0,
|
||||
MISCREG_MMU_ITLB_C0_TSB_PS1,
|
||||
MISCREG_MMU_ITLB_C0_CONFIG,
|
||||
MISCREG_MMU_ITLB_CX_TSB_PS0,
|
||||
MISCREG_MMU_ITLB_CX_TSB_PS1,
|
||||
MISCREG_MMU_ITLB_CX_CONFIG,
|
||||
MISCREG_MMU_ITLB_SFSR,
|
||||
MISCREG_MMU_ITLB_TAG_ACCESS, /* 50 */
|
||||
|
||||
MISCREG_MMU_DTLB_C0_TSB_PS0,
|
||||
MISCREG_MMU_DTLB_C0_TSB_PS1,
|
||||
MISCREG_MMU_DTLB_C0_CONFIG,
|
||||
MISCREG_MMU_DTLB_CX_TSB_PS0,
|
||||
MISCREG_MMU_DTLB_CX_TSB_PS1,
|
||||
MISCREG_MMU_DTLB_CX_CONFIG,
|
||||
MISCREG_MMU_DTLB_SFSR,
|
||||
MISCREG_MMU_DTLB_SFAR,
|
||||
MISCREG_MMU_DTLB_TAG_ACCESS,
|
||||
|
||||
/** Scratchpad regiscers **/
|
||||
MISCREG_SCRATCHPAD_R0, /* 60 */
|
||||
MISCREG_SCRATCHPAD_R1,
|
||||
|
@ -241,25 +222,6 @@ namespace SparcISA
|
|||
uint16_t partId;
|
||||
uint64_t lsuCtrlReg;
|
||||
|
||||
uint64_t iTlbC0TsbPs0;
|
||||
uint64_t iTlbC0TsbPs1;
|
||||
uint64_t iTlbC0Config;
|
||||
uint64_t iTlbCXTsbPs0;
|
||||
uint64_t iTlbCXTsbPs1;
|
||||
uint64_t iTlbCXConfig;
|
||||
uint64_t iTlbSfsr;
|
||||
uint64_t iTlbTagAccess;
|
||||
|
||||
uint64_t dTlbC0TsbPs0;
|
||||
uint64_t dTlbC0TsbPs1;
|
||||
uint64_t dTlbC0Config;
|
||||
uint64_t dTlbCXTsbPs0;
|
||||
uint64_t dTlbCXTsbPs1;
|
||||
uint64_t dTlbCXConfig;
|
||||
uint64_t dTlbSfsr;
|
||||
uint64_t dTlbSfar;
|
||||
uint64_t dTlbTagAccess;
|
||||
|
||||
uint64_t scratchPad[8];
|
||||
|
||||
uint64_t cpu_mondo_head;
|
||||
|
|
|
@ -326,42 +326,6 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
|
|||
dest->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_LSU_CTRL));
|
||||
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS0,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS0));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS1,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_ITLB_C0_TSB_PS1));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_C0_CONFIG,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_ITLB_C0_CONFIG));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS0,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS0));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS1,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_ITLB_CX_TSB_PS1));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_CX_CONFIG,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_ITLB_CX_CONFIG));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_SFSR,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_ITLB_SFSR));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_ITLB_TAG_ACCESS,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_ITLB_TAG_ACCESS));
|
||||
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS0,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS0));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS1,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_DTLB_C0_TSB_PS1));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_C0_CONFIG,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_DTLB_C0_CONFIG));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS0,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS0));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS1,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_DTLB_CX_TSB_PS1));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_CX_CONFIG,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_DTLB_CX_CONFIG));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_SFSR,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_DTLB_SFSR));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_SFAR,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_DTLB_SFAR));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_DTLB_TAG_ACCESS,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_DTLB_TAG_ACCESS));
|
||||
|
||||
// Scratchpad Registers
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R0,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R0));
|
||||
|
|
|
@ -60,6 +60,15 @@ TLB::TLB(const std::string &name, int s)
|
|||
|
||||
for (int x = 0; x < size; x++)
|
||||
freeList.push_back(&tlb[x]);
|
||||
|
||||
c0_tsb_ps0 = 0;
|
||||
c0_tsb_ps1 = 0;
|
||||
c0_config = 0;
|
||||
cx_tsb_ps0 = 0;
|
||||
cx_tsb_ps1 = 0;
|
||||
cx_config = 0;
|
||||
sfsr = 0;
|
||||
tag_access = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -393,12 +402,8 @@ TLB::validVirtualAddress(Addr va, bool am)
|
|||
}
|
||||
|
||||
void
|
||||
TLB::writeSfsr(ThreadContext *tc, int reg, bool write, ContextType ct,
|
||||
bool se, FaultTypes ft, int asi)
|
||||
TLB::writeSfsr(bool write, ContextType ct, bool se, FaultTypes ft, int asi)
|
||||
{
|
||||
uint64_t sfsr;
|
||||
sfsr = tc->readMiscRegNoEffect(reg);
|
||||
|
||||
if (sfsr & 0x1)
|
||||
sfsr = 0x3;
|
||||
else
|
||||
|
@ -411,51 +416,35 @@ TLB::writeSfsr(ThreadContext *tc, int reg, bool write, ContextType ct,
|
|||
sfsr |= 1 << 6;
|
||||
sfsr |= ft << 7;
|
||||
sfsr |= asi << 16;
|
||||
tc->setMiscReg(reg, sfsr);
|
||||
}
|
||||
|
||||
void
|
||||
TLB::writeTagAccess(ThreadContext *tc, int reg, Addr va, int context)
|
||||
TLB::writeTagAccess(Addr va, int context)
|
||||
{
|
||||
DPRINTF(TLB, "TLB: Writing Tag Access: va: %#X ctx: %#X value: %#X\n",
|
||||
va, context, mbits(va, 63,13) | mbits(context,12,0));
|
||||
|
||||
tc->setMiscReg(reg, mbits(va, 63,13) | mbits(context,12,0));
|
||||
tag_access = mbits(va, 63,13) | mbits(context,12,0);
|
||||
}
|
||||
|
||||
void
|
||||
ITB::writeSfsr(ThreadContext *tc, bool write, ContextType ct,
|
||||
bool se, FaultTypes ft, int asi)
|
||||
ITB::writeSfsr(bool write, ContextType ct, bool se, FaultTypes ft, int asi)
|
||||
{
|
||||
DPRINTF(TLB, "TLB: ITB Fault: w=%d ct=%d ft=%d asi=%d\n",
|
||||
(int)write, ct, ft, asi);
|
||||
TLB::writeSfsr(tc, MISCREG_MMU_ITLB_SFSR, write, ct, se, ft, asi);
|
||||
TLB::writeSfsr(write, ct, se, ft, asi);
|
||||
}
|
||||
|
||||
void
|
||||
ITB::writeTagAccess(ThreadContext *tc, Addr va, int context)
|
||||
{
|
||||
TLB::writeTagAccess(tc, MISCREG_MMU_ITLB_TAG_ACCESS, va, context);
|
||||
}
|
||||
|
||||
void
|
||||
DTB::writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct,
|
||||
DTB::writeSfsr(Addr a, bool write, ContextType ct,
|
||||
bool se, FaultTypes ft, int asi)
|
||||
{
|
||||
DPRINTF(TLB, "TLB: DTB Fault: A=%#x w=%d ct=%d ft=%d asi=%d\n",
|
||||
a, (int)write, ct, ft, asi);
|
||||
TLB::writeSfsr(tc, MISCREG_MMU_DTLB_SFSR, write, ct, se, ft, asi);
|
||||
tc->setMiscReg(MISCREG_MMU_DTLB_SFAR, a);
|
||||
TLB::writeSfsr(write, ct, se, ft, asi);
|
||||
sfar = a;
|
||||
}
|
||||
|
||||
void
|
||||
DTB::writeTagAccess(ThreadContext *tc, Addr va, int context)
|
||||
{
|
||||
TLB::writeTagAccess(tc, MISCREG_MMU_DTLB_TAG_ACCESS, va, context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Fault
|
||||
ITB::translate(RequestPtr &req, ThreadContext *tc)
|
||||
{
|
||||
|
@ -521,7 +510,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
|
|||
|
||||
// If the access is unaligned trap
|
||||
if (vaddr & 0x3) {
|
||||
writeSfsr(tc, false, ct, false, OtherFault, asi);
|
||||
writeSfsr(false, ct, false, OtherFault, asi);
|
||||
return new MemAddressNotAligned;
|
||||
}
|
||||
|
||||
|
@ -529,7 +518,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
|
|||
vaddr = vaddr & VAddrAMask;
|
||||
|
||||
if (!validVirtualAddress(vaddr, addr_mask)) {
|
||||
writeSfsr(tc, false, ct, false, VaOutOfRange, asi);
|
||||
writeSfsr(false, ct, false, VaOutOfRange, asi);
|
||||
return new InstructionAccessException;
|
||||
}
|
||||
|
||||
|
@ -542,7 +531,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
|
|||
}
|
||||
|
||||
if (e == NULL || !e->valid) {
|
||||
writeTagAccess(tc, vaddr, context);
|
||||
writeTagAccess(vaddr, context);
|
||||
if (real)
|
||||
return new InstructionRealTranslationMiss;
|
||||
else
|
||||
|
@ -551,8 +540,8 @@ ITB::translate(RequestPtr &req, ThreadContext *tc)
|
|||
|
||||
// were not priviledged accesing priv page
|
||||
if (!priv && e->pte.priv()) {
|
||||
writeTagAccess(tc, vaddr, context);
|
||||
writeSfsr(tc, false, ct, false, PrivViolation, asi);
|
||||
writeTagAccess(vaddr, context);
|
||||
writeSfsr(false, ct, false, PrivViolation, asi);
|
||||
return new InstructionAccessException;
|
||||
}
|
||||
|
||||
|
@ -661,12 +650,12 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
// We need to check for priv level/asi priv
|
||||
if (!priv && !hpriv && !AsiIsUnPriv(asi)) {
|
||||
// It appears that context should be Nucleus in these cases?
|
||||
writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi);
|
||||
writeSfsr(vaddr, write, Nucleus, false, IllegalAsi, asi);
|
||||
return new PrivilegedAction;
|
||||
}
|
||||
|
||||
if (!hpriv && AsiIsHPriv(asi)) {
|
||||
writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi);
|
||||
writeSfsr(vaddr, write, Nucleus, false, IllegalAsi, asi);
|
||||
return new DataAccessException;
|
||||
}
|
||||
|
||||
|
@ -719,7 +708,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
|
||||
// If the asi is unaligned trap
|
||||
if (vaddr & size-1) {
|
||||
writeSfr(tc, vaddr, false, ct, false, OtherFault, asi);
|
||||
writeSfsr(vaddr, false, ct, false, OtherFault, asi);
|
||||
return new MemAddressNotAligned;
|
||||
}
|
||||
|
||||
|
@ -727,7 +716,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
vaddr = vaddr & VAddrAMask;
|
||||
|
||||
if (!validVirtualAddress(vaddr, addr_mask)) {
|
||||
writeSfr(tc, vaddr, false, ct, true, VaOutOfRange, asi);
|
||||
writeSfsr(vaddr, false, ct, true, VaOutOfRange, asi);
|
||||
return new DataAccessException;
|
||||
}
|
||||
|
||||
|
@ -745,7 +734,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
e = lookup(vaddr, part_id, real, context);
|
||||
|
||||
if (e == NULL || !e->valid) {
|
||||
writeTagAccess(tc, vaddr, context);
|
||||
writeTagAccess(vaddr, context);
|
||||
DPRINTF(TLB, "TLB: DTB Failed to find matching TLB entry\n");
|
||||
if (real)
|
||||
return new DataRealTranslationMiss;
|
||||
|
@ -755,26 +744,26 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
}
|
||||
|
||||
if (!priv && e->pte.priv()) {
|
||||
writeTagAccess(tc, vaddr, context);
|
||||
writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), PrivViolation, asi);
|
||||
writeTagAccess(vaddr, context);
|
||||
writeSfsr(vaddr, write, ct, e->pte.sideffect(), PrivViolation, asi);
|
||||
return new DataAccessException;
|
||||
}
|
||||
|
||||
if (write && !e->pte.writable()) {
|
||||
writeTagAccess(tc, vaddr, context);
|
||||
writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), OtherFault, asi);
|
||||
writeTagAccess(vaddr, context);
|
||||
writeSfsr(vaddr, write, ct, e->pte.sideffect(), OtherFault, asi);
|
||||
return new FastDataAccessProtection;
|
||||
}
|
||||
|
||||
if (e->pte.nofault() && !AsiIsNoFault(asi)) {
|
||||
writeTagAccess(tc, vaddr, context);
|
||||
writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), LoadFromNfo, asi);
|
||||
writeTagAccess(vaddr, context);
|
||||
writeSfsr(vaddr, write, ct, e->pte.sideffect(), LoadFromNfo, asi);
|
||||
return new DataAccessException;
|
||||
}
|
||||
|
||||
if (e->pte.sideffect() && AsiIsNoFault(asi)) {
|
||||
writeTagAccess(tc, vaddr, context);
|
||||
writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), SideEffect, asi);
|
||||
writeTagAccess(vaddr, context);
|
||||
writeSfsr(vaddr, write, ct, e->pte.sideffect(), SideEffect, asi);
|
||||
return new DataAccessException;
|
||||
}
|
||||
|
||||
|
@ -806,7 +795,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
/** Normal flow ends here. */
|
||||
handleIntRegAccess:
|
||||
if (!hpriv) {
|
||||
writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
|
||||
writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
|
||||
if (priv)
|
||||
return new DataAccessException;
|
||||
else
|
||||
|
@ -815,7 +804,7 @@ handleIntRegAccess:
|
|||
|
||||
if (asi == ASI_SWVR_UDB_INTR_W && !write ||
|
||||
asi == ASI_SWVR_UDB_INTR_R && write) {
|
||||
writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
|
||||
writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
|
||||
return new DataAccessException;
|
||||
}
|
||||
|
||||
|
@ -824,25 +813,25 @@ handleIntRegAccess:
|
|||
|
||||
handleScratchRegAccess:
|
||||
if (vaddr > 0x38 || (vaddr >= 0x20 && vaddr < 0x30 && !hpriv)) {
|
||||
writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
|
||||
writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
|
||||
return new DataAccessException;
|
||||
}
|
||||
goto regAccessOk;
|
||||
|
||||
handleQueueRegAccess:
|
||||
if (!priv && !hpriv) {
|
||||
writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
|
||||
writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
|
||||
return new PrivilegedAction;
|
||||
}
|
||||
if (!hpriv && vaddr & 0xF || vaddr > 0x3f8 || vaddr < 0x3c0) {
|
||||
writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
|
||||
writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
|
||||
return new DataAccessException;
|
||||
}
|
||||
goto regAccessOk;
|
||||
|
||||
handleSparcErrorRegAccess:
|
||||
if (!hpriv) {
|
||||
writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
|
||||
writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
|
||||
if (priv)
|
||||
return new DataAccessException;
|
||||
else
|
||||
|
@ -869,6 +858,8 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
|
|||
DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n",
|
||||
(uint32_t)pkt->req->getAsi(), pkt->getAddr());
|
||||
|
||||
ITB * itb = tc->getITBPtr();
|
||||
|
||||
switch (asi) {
|
||||
case ASI_LSU_CONTROL_REG:
|
||||
assert(va == 0);
|
||||
|
@ -892,51 +883,51 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
|
|||
break;
|
||||
case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0:
|
||||
assert(va == 0);
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0));
|
||||
pkt->set(c0_tsb_ps0);
|
||||
break;
|
||||
case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1:
|
||||
assert(va == 0);
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1));
|
||||
pkt->set(c0_tsb_ps1);
|
||||
break;
|
||||
case ASI_DMMU_CTXT_ZERO_CONFIG:
|
||||
assert(va == 0);
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG));
|
||||
pkt->set(c0_config);
|
||||
break;
|
||||
case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0:
|
||||
assert(va == 0);
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0));
|
||||
pkt->set(itb->c0_tsb_ps0);
|
||||
break;
|
||||
case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1:
|
||||
assert(va == 0);
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1));
|
||||
pkt->set(itb->c0_tsb_ps1);
|
||||
break;
|
||||
case ASI_IMMU_CTXT_ZERO_CONFIG:
|
||||
assert(va == 0);
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG));
|
||||
pkt->set(itb->c0_config);
|
||||
break;
|
||||
case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0:
|
||||
assert(va == 0);
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0));
|
||||
pkt->set(cx_tsb_ps0);
|
||||
break;
|
||||
case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1:
|
||||
assert(va == 0);
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1));
|
||||
pkt->set(cx_tsb_ps1);
|
||||
break;
|
||||
case ASI_DMMU_CTXT_NONZERO_CONFIG:
|
||||
assert(va == 0);
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG));
|
||||
pkt->set(cx_config);
|
||||
break;
|
||||
case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0:
|
||||
assert(va == 0);
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0));
|
||||
pkt->set(itb->cx_tsb_ps0);
|
||||
break;
|
||||
case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1:
|
||||
assert(va == 0);
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1));
|
||||
pkt->set(itb->cx_tsb_ps1);
|
||||
break;
|
||||
case ASI_IMMU_CTXT_NONZERO_CONFIG:
|
||||
assert(va == 0);
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG));
|
||||
pkt->set(itb->cx_config);
|
||||
break;
|
||||
case ASI_SPARC_ERROR_STATUS_REG:
|
||||
pkt->set((uint64_t)0);
|
||||
|
@ -948,14 +939,14 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
|
|||
case ASI_IMMU:
|
||||
switch (va) {
|
||||
case 0x0:
|
||||
temp = tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS);
|
||||
temp = itb->tag_access;
|
||||
pkt->set(bits(temp,63,22) | bits(temp,12,0) << 48);
|
||||
break;
|
||||
case 0x18:
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_SFSR));
|
||||
pkt->set(itb->sfsr);
|
||||
break;
|
||||
case 0x30:
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS));
|
||||
pkt->set(itb->tag_access);
|
||||
break;
|
||||
default:
|
||||
goto doMmuReadError;
|
||||
|
@ -964,17 +955,17 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
|
|||
case ASI_DMMU:
|
||||
switch (va) {
|
||||
case 0x0:
|
||||
temp = tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS);
|
||||
temp = tag_access;
|
||||
pkt->set(bits(temp,63,22) | bits(temp,12,0) << 48);
|
||||
break;
|
||||
case 0x18:
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_SFSR));
|
||||
pkt->set(sfsr);
|
||||
break;
|
||||
case 0x20:
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_SFAR));
|
||||
pkt->set(sfar);
|
||||
break;
|
||||
case 0x30:
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS));
|
||||
pkt->set(tag_access);
|
||||
break;
|
||||
case 0x80:
|
||||
pkt->set(tc->readMiscReg(MISCREG_MMU_PART_ID));
|
||||
|
@ -985,35 +976,35 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
|
|||
break;
|
||||
case ASI_DMMU_TSB_PS0_PTR_REG:
|
||||
pkt->set(MakeTsbPtr(Ps0,
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS),
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0),
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG),
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0),
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG)));
|
||||
tag_access,
|
||||
c0_tsb_ps0,
|
||||
c0_config,
|
||||
cx_tsb_ps0,
|
||||
cx_config));
|
||||
break;
|
||||
case ASI_DMMU_TSB_PS1_PTR_REG:
|
||||
pkt->set(MakeTsbPtr(Ps1,
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS),
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1),
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG),
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1),
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG)));
|
||||
tag_access,
|
||||
c0_tsb_ps1,
|
||||
c0_config,
|
||||
cx_tsb_ps1,
|
||||
cx_config));
|
||||
break;
|
||||
case ASI_IMMU_TSB_PS0_PTR_REG:
|
||||
pkt->set(MakeTsbPtr(Ps0,
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS),
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0),
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG),
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0),
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG)));
|
||||
itb->tag_access,
|
||||
itb->c0_tsb_ps0,
|
||||
itb->c0_config,
|
||||
itb->cx_tsb_ps0,
|
||||
itb->cx_config));
|
||||
break;
|
||||
case ASI_IMMU_TSB_PS1_PTR_REG:
|
||||
pkt->set(MakeTsbPtr(Ps1,
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS),
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1),
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG),
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1),
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG)));
|
||||
itb->tag_access,
|
||||
itb->c0_tsb_ps1,
|
||||
itb->c0_config,
|
||||
itb->cx_tsb_ps1,
|
||||
itb->cx_config));
|
||||
break;
|
||||
case ASI_SWVR_INTR_RECEIVE:
|
||||
pkt->set(tc->getCpuPtr()->get_interrupts(IT_INT_VEC));
|
||||
|
@ -1053,6 +1044,8 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
|
|||
DPRINTF(IPR, "Memory Mapped IPR Write: asi=%#X a=%#x d=%#X\n",
|
||||
(uint32_t)asi, va, data);
|
||||
|
||||
ITB * itb = tc->getITBPtr();
|
||||
|
||||
switch (asi) {
|
||||
case ASI_LSU_CONTROL_REG:
|
||||
assert(va == 0);
|
||||
|
@ -1077,51 +1070,51 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
|
|||
break;
|
||||
case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0:
|
||||
assert(va == 0);
|
||||
tc->setMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0, data);
|
||||
c0_tsb_ps0 = data;
|
||||
break;
|
||||
case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1:
|
||||
assert(va == 0);
|
||||
tc->setMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1, data);
|
||||
c0_tsb_ps1 = data;
|
||||
break;
|
||||
case ASI_DMMU_CTXT_ZERO_CONFIG:
|
||||
assert(va == 0);
|
||||
tc->setMiscReg(MISCREG_MMU_DTLB_C0_CONFIG, data);
|
||||
c0_config = data;
|
||||
break;
|
||||
case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0:
|
||||
assert(va == 0);
|
||||
tc->setMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0, data);
|
||||
itb->c0_tsb_ps0 = data;
|
||||
break;
|
||||
case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1:
|
||||
assert(va == 0);
|
||||
tc->setMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1, data);
|
||||
itb->c0_tsb_ps1 = data;
|
||||
break;
|
||||
case ASI_IMMU_CTXT_ZERO_CONFIG:
|
||||
assert(va == 0);
|
||||
tc->setMiscReg(MISCREG_MMU_ITLB_C0_CONFIG, data);
|
||||
itb->c0_config = data;
|
||||
break;
|
||||
case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0:
|
||||
assert(va == 0);
|
||||
tc->setMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0, data);
|
||||
cx_tsb_ps0 = data;
|
||||
break;
|
||||
case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1:
|
||||
assert(va == 0);
|
||||
tc->setMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1, data);
|
||||
cx_tsb_ps1 = data;
|
||||
break;
|
||||
case ASI_DMMU_CTXT_NONZERO_CONFIG:
|
||||
assert(va == 0);
|
||||
tc->setMiscReg(MISCREG_MMU_DTLB_CX_CONFIG, data);
|
||||
cx_config = data;
|
||||
break;
|
||||
case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0:
|
||||
assert(va == 0);
|
||||
tc->setMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0, data);
|
||||
itb->cx_tsb_ps0 = data;
|
||||
break;
|
||||
case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1:
|
||||
assert(va == 0);
|
||||
tc->setMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1, data);
|
||||
itb->cx_tsb_ps1 = data;
|
||||
break;
|
||||
case ASI_IMMU_CTXT_NONZERO_CONFIG:
|
||||
assert(va == 0);
|
||||
tc->setMiscReg(MISCREG_MMU_ITLB_CX_CONFIG, data);
|
||||
itb->cx_config = data;
|
||||
break;
|
||||
case ASI_SPARC_ERROR_EN_REG:
|
||||
case ASI_SPARC_ERROR_STATUS_REG:
|
||||
|
@ -1134,11 +1127,11 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
|
|||
case ASI_IMMU:
|
||||
switch (va) {
|
||||
case 0x18:
|
||||
tc->setMiscReg(MISCREG_MMU_ITLB_SFSR, data);
|
||||
itb->sfsr = data;
|
||||
break;
|
||||
case 0x30:
|
||||
sext<59>(bits(data, 59,0));
|
||||
tc->setMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS, data);
|
||||
itb->tag_access = data;
|
||||
break;
|
||||
default:
|
||||
goto doMmuWriteError;
|
||||
|
@ -1148,7 +1141,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
|
|||
entry_insert = bits(va, 8,3);
|
||||
case ASI_ITLB_DATA_IN_REG:
|
||||
assert(entry_insert != -1 || mbits(va,10,9) == va);
|
||||
ta_insert = tc->readMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS);
|
||||
ta_insert = itb->tag_access;
|
||||
va_insert = mbits(ta_insert, 63,13);
|
||||
ct_insert = mbits(ta_insert, 12,0);
|
||||
part_insert = tc->readMiscReg(MISCREG_MMU_PART_ID);
|
||||
|
@ -1162,7 +1155,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
|
|||
entry_insert = bits(va, 8,3);
|
||||
case ASI_DTLB_DATA_IN_REG:
|
||||
assert(entry_insert != -1 || mbits(va,10,9) == va);
|
||||
ta_insert = tc->readMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS);
|
||||
ta_insert = tag_access;
|
||||
va_insert = mbits(ta_insert, 63,13);
|
||||
ct_insert = mbits(ta_insert, 12,0);
|
||||
part_insert = tc->readMiscReg(MISCREG_MMU_PART_ID);
|
||||
|
@ -1209,11 +1202,11 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
|
|||
case ASI_DMMU:
|
||||
switch (va) {
|
||||
case 0x18:
|
||||
tc->setMiscReg(MISCREG_MMU_DTLB_SFSR, data);
|
||||
sfsr = data;
|
||||
break;
|
||||
case 0x30:
|
||||
sext<59>(bits(data, 59,0));
|
||||
tc->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS, data);
|
||||
tag_access = data;
|
||||
break;
|
||||
case 0x80:
|
||||
tc->setMiscReg(MISCREG_MMU_PART_ID, data);
|
||||
|
@ -1281,26 +1274,27 @@ void
|
|||
DTB::GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs)
|
||||
{
|
||||
uint64_t tag_access = mbits(addr,63,13) | mbits(ctx,12,0);
|
||||
ITB * itb = tc->getITBPtr();
|
||||
ptrs[0] = MakeTsbPtr(Ps0, tag_access,
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS0),
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG),
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS0),
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG));
|
||||
c0_tsb_ps0,
|
||||
c0_config,
|
||||
cx_tsb_ps0,
|
||||
cx_config);
|
||||
ptrs[1] = MakeTsbPtr(Ps1, tag_access,
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_C0_TSB_PS1),
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_C0_CONFIG),
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_CX_TSB_PS1),
|
||||
tc->readMiscReg(MISCREG_MMU_DTLB_CX_CONFIG));
|
||||
c0_tsb_ps1,
|
||||
c0_config,
|
||||
cx_tsb_ps1,
|
||||
cx_config);
|
||||
ptrs[2] = MakeTsbPtr(Ps0, tag_access,
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS0),
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG),
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS0),
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG));
|
||||
itb->c0_tsb_ps0,
|
||||
itb->c0_config,
|
||||
itb->cx_tsb_ps0,
|
||||
itb->cx_config);
|
||||
ptrs[3] = MakeTsbPtr(Ps1, tag_access,
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_C0_TSB_PS1),
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_C0_CONFIG),
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_CX_TSB_PS1),
|
||||
tc->readMiscReg(MISCREG_MMU_ITLB_CX_CONFIG));
|
||||
itb->c0_tsb_ps1,
|
||||
itb->c0_config,
|
||||
itb->cx_tsb_ps1,
|
||||
itb->cx_config);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1358,6 +1352,15 @@ TLB::serialize(std::ostream &os)
|
|||
nameOut(os, csprintf("%s.PTE%d", name(), x));
|
||||
tlb[x].serialize(os);
|
||||
}
|
||||
|
||||
SERIALIZE_SCALAR(c0_tsb_ps0);
|
||||
SERIALIZE_SCALAR(c0_tsb_ps1);
|
||||
SERIALIZE_SCALAR(c0_config);
|
||||
SERIALIZE_SCALAR(cx_tsb_ps0);
|
||||
SERIALIZE_SCALAR(cx_tsb_ps1);
|
||||
SERIALIZE_SCALAR(cx_config);
|
||||
SERIALIZE_SCALAR(sfsr);
|
||||
SERIALIZE_SCALAR(tag_access);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1387,6 +1390,29 @@ TLB::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
lookupTable.insert(tlb[x].range, &tlb[x]);
|
||||
|
||||
}
|
||||
|
||||
UNSERIALIZE_SCALAR(c0_tsb_ps0);
|
||||
UNSERIALIZE_SCALAR(c0_tsb_ps1);
|
||||
UNSERIALIZE_SCALAR(c0_config);
|
||||
UNSERIALIZE_SCALAR(cx_tsb_ps0);
|
||||
UNSERIALIZE_SCALAR(cx_tsb_ps1);
|
||||
UNSERIALIZE_SCALAR(cx_config);
|
||||
UNSERIALIZE_SCALAR(sfsr);
|
||||
UNSERIALIZE_SCALAR(tag_access);
|
||||
}
|
||||
|
||||
void
|
||||
DTB::serialize(std::ostream &os)
|
||||
{
|
||||
TLB::serialize(os);
|
||||
SERIALIZE_SCALAR(sfar);
|
||||
}
|
||||
|
||||
void
|
||||
DTB::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
TLB::unserialize(cp, section);
|
||||
UNSERIALIZE_SCALAR(sfar);
|
||||
}
|
||||
|
||||
/* end namespace SparcISA */ }
|
||||
|
|
|
@ -46,6 +46,17 @@ namespace SparcISA
|
|||
|
||||
class TLB : public SimObject
|
||||
{
|
||||
//TLB state
|
||||
protected:
|
||||
uint64_t c0_tsb_ps0;
|
||||
uint64_t c0_tsb_ps1;
|
||||
uint64_t c0_config;
|
||||
uint64_t cx_tsb_ps0;
|
||||
uint64_t cx_tsb_ps1;
|
||||
uint64_t cx_config;
|
||||
uint64_t sfsr;
|
||||
uint64_t tag_access;
|
||||
|
||||
protected:
|
||||
TlbMap lookupTable;;
|
||||
typedef TlbMap::iterator MapIter;
|
||||
|
@ -120,13 +131,13 @@ class TLB : public SimObject
|
|||
/** Checks if the virtual address provided is a valid one. */
|
||||
bool validVirtualAddress(Addr va, bool am);
|
||||
|
||||
void writeSfsr(ThreadContext *tc, int reg, bool write, ContextType ct,
|
||||
void writeSfsr(bool write, ContextType ct,
|
||||
bool se, FaultTypes ft, int asi);
|
||||
|
||||
void clearUsedBits();
|
||||
|
||||
|
||||
void writeTagAccess(ThreadContext *tc, int reg, Addr va, int context);
|
||||
void writeTagAccess(Addr va, int context);
|
||||
|
||||
public:
|
||||
TLB(const std::string &name, int size);
|
||||
|
@ -152,18 +163,21 @@ class ITB : public TLB
|
|||
|
||||
Fault translate(RequestPtr &req, ThreadContext *tc);
|
||||
private:
|
||||
void writeSfsr(ThreadContext *tc, bool write, ContextType ct,
|
||||
void writeSfsr(bool write, ContextType ct,
|
||||
bool se, FaultTypes ft, int asi);
|
||||
void writeTagAccess(ThreadContext *tc, Addr va, int context);
|
||||
TlbEntry *cacheEntry;
|
||||
friend class DTB;
|
||||
};
|
||||
|
||||
class DTB : public TLB
|
||||
{
|
||||
//DTLB specific state
|
||||
protected:
|
||||
uint64_t sfar;
|
||||
public:
|
||||
DTB(const std::string &name, int size) : TLB(name, size)
|
||||
{
|
||||
sfar = 0;
|
||||
cacheEntry[0] = NULL;
|
||||
cacheEntry[1] = NULL;
|
||||
}
|
||||
|
@ -173,10 +187,13 @@ class DTB : public TLB
|
|||
Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt);
|
||||
void GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs);
|
||||
|
||||
// Checkpointing
|
||||
virtual void serialize(std::ostream &os);
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
private:
|
||||
void writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct,
|
||||
void writeSfsr(Addr a, bool write, ContextType ct,
|
||||
bool se, FaultTypes ft, int asi);
|
||||
void writeTagAccess(ThreadContext *tc, Addr va, int context);
|
||||
|
||||
uint64_t MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb,
|
||||
uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config);
|
||||
|
|
Loading…
Reference in a new issue