summaryrefslogtreecommitdiff
path: root/src/arch/sparc/tlb.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc/tlb.cc')
-rw-r--r--src/arch/sparc/tlb.cc290
1 files changed, 160 insertions, 130 deletions
diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc
index 21d56b8c6..e184429ab 100644
--- a/src/arch/sparc/tlb.cc
+++ b/src/arch/sparc/tlb.cc
@@ -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);
-}
-
-void
-ITB::writeTagAccess(ThreadContext *tc, Addr va, int context)
-{
- TLB::writeTagAccess(tc, MISCREG_MMU_ITLB_TAG_ACCESS, va, context);
+ TLB::writeSfsr(write, ct, se, ft, asi);
}
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;
}
@@ -600,9 +589,9 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
- if (cacheEntry[0]) {
+ if (cacheEntry[0]) {
TlbEntry *ce = cacheEntry[0];
- Addr ce_va = ce->range.va;
+ Addr ce_va = ce->range.va;
if (cacheAsi[0] == asi &&
ce_va < vaddr + size && ce_va + ce->range.size > vaddr &&
(!write || ce->pte.writable())) {
@@ -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;
}
@@ -688,8 +677,12 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
if (!implicit && asi != ASI_P && asi != ASI_S) {
if (AsiIsLittle(asi))
panic("Little Endian ASIs not supported\n");
- if (AsiIsNoFault(asi))
- panic("No Fault ASIs not supported\n");
+
+ //XXX It's unclear from looking at the documentation how a no fault
+ //load differs from a regular one, other than what happens concerning
+ //nfo and e bits in the TTE
+// if (AsiIsNoFault(asi))
+// panic("No Fault ASIs not supported\n");
if (AsiIsPartialStore(asi))
panic("Partial Store ASIs not supported\n");
@@ -709,13 +702,13 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
goto handleSparcErrorRegAccess;
if (!AsiIsReal(asi) && !AsiIsNucleus(asi) && !AsiIsAsIfUser(asi) &&
- !AsiIsTwin(asi) && !AsiIsBlock(asi))
+ !AsiIsTwin(asi) && !AsiIsBlock(asi) && !AsiIsNoFault(asi))
panic("Accessing ASI %#X. Should we?\n", asi);
}
// 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;
}
@@ -723,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;
}
@@ -741,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;
@@ -751,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;
}
@@ -802,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
@@ -811,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;
}
@@ -820,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
@@ -865,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);
@@ -888,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);
@@ -944,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;
@@ -960,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));
@@ -981,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));
@@ -1049,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);
@@ -1073,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:
@@ -1130,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;
@@ -1144,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);
@@ -1158,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);
@@ -1205,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);
@@ -1277,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);
}
@@ -1354,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
@@ -1383,6 +1390,29 @@ TLB::unserialize(Checkpoint *cp, const std::string &section)
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 &section)
+{
+ TLB::unserialize(cp, section);
+ UNSERIALIZE_SCALAR(sfar);
}
/* end namespace SparcISA */ }