#include "cpu/base.hh"
#include "mem/packet_access.hh"
#include "mem/request.hh"
-#include "sim/builder.hh"
+#include "sim/system.hh"
/* @todo remove some of the magic constants. -- ali
* */
-namespace SparcISA
-{
+namespace SparcISA {
-TLB::TLB(const std::string &name, int s)
- : SimObject(name), size(s), usedEntries(0), lastReplaced(0),
+TLB::TLB(const Params *p)
+ : BaseTLB(p), size(p->size), usedEntries(0), lastReplaced(0),
cacheValid(false)
{
// To make this work you'll have to change the hypervisor and OS
if (size > 64)
- fatal("SPARC T1 TLB registers don't support more than 64 TLB entries.");
+ fatal("SPARC T1 TLB registers don't support more than 64 TLB entries");
tlb = new TlbEntry[size];
std::memset(tlb, 0, sizeof(TlbEntry) * size);
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
TLB::insert(Addr va, int partition_id, int context_id, bool real,
const PageTableEntry& PTE, int entry)
{
-
-
MapIter i;
TlbEntry *new_entry = NULL;
// TlbRange tr;
tr.real = real;
*/
- DPRINTF(TLB, "TLB: Inserting TLB Entry; va=%#x pa=%#x pid=%d cid=%d r=%d entryid=%d\n",
- va, PTE.paddr(), partition_id, context_id, (int)real, entry);
+ DPRINTF(TLB,
+ "TLB: Inserting Entry; va=%#x pa=%#x pid=%d cid=%d r=%d entryid=%d\n",
+ va, PTE.paddr(), partition_id, context_id, (int)real, entry);
// Demap any entry that conflicts
for (x = 0; x < size; x++) {
}
}
-
/*
i = lookupTable.find(tr);
if (i != lookupTable.end()) {
new_entry->valid = true;
usedEntries++;
-
-
i = lookupTable.insert(new_entry->range, new_entry);
assert(i != lookupTable.end());
- // If all entries have there used bit set, clear it on them all, but the
- // one we just inserted
+ // If all entries have their used bit set, clear it on them all,
+ // but the one we just inserted
if (usedEntries == size) {
clearUsedBits();
new_entry->used = true;
usedEntries++;
}
-
}
TlbEntry*
-TLB::lookup(Addr va, int partition_id, bool real, int context_id)
+TLB::lookup(Addr va, int partition_id, bool real, int context_id,
+ bool update_used)
{
MapIter i;
TlbRange tr;
va, partition_id, context_id, real);
// Assemble full address structure
tr.va = va;
- tr.size = MachineBytes;
+ tr.size = 1;
tr.contextId = context_id;
tr.partitionId = partition_id;
tr.real = real;
t = i->second;
DPRINTF(TLB, "TLB: Valid entry found pa: %#x size: %#x\n", t->pte.paddr(),
t->pte.size());
- if (!t->used) {
+
+ // Update the used bits only if this is a real access (not a fake
+ // one from virttophys()
+ if (!t->used && update_used) {
t->used = true;
usedEntries++;
if (usedEntries == size) {
// Assemble full address structure
tr.va = va;
- tr.size = MachineBytes;
+ tr.size = 1;
tr.contextId = context_id;
tr.partitionId = partition_id;
tr.real = real;
void
TLB::demapContext(int partition_id, int context_id)
{
- int x;
DPRINTF(IPR, "TLB: Demapping Context pid=%#d cid=%d\n",
partition_id, context_id);
cacheValid = false;
- for (x = 0; x < size; x++) {
+ for (int x = 0; x < size; x++) {
if (tlb[x].range.contextId == context_id &&
tlb[x].range.partitionId == partition_id) {
if (tlb[x].valid == true) {
void
TLB::demapAll(int partition_id)
{
- int x;
DPRINTF(TLB, "TLB: Demapping All pid=%#d\n", partition_id);
cacheValid = false;
- for (x = 0; x < size; x++) {
- if (!tlb[x].pte.locked() && tlb[x].range.partitionId == partition_id) {
- if (tlb[x].valid == true){
- freeList.push_front(&tlb[x]);
- }
+ for (int x = 0; x < size; x++) {
+ if (tlb[x].valid && !tlb[x].pte.locked() &&
+ tlb[x].range.partitionId == partition_id) {
+ freeList.push_front(&tlb[x]);
tlb[x].valid = false;
if (tlb[x].used) {
tlb[x].used = false;
void
TLB::invalidateAll()
{
- int x;
cacheValid = false;
-
- freeList.clear();
lookupTable.clear();
- for (x = 0; x < size; x++) {
+
+ for (int x = 0; x < size; x++) {
if (tlb[x].valid == true)
freeList.push_back(&tlb[x]);
tlb[x].valid = false;
}
uint64_t
-TLB::TteRead(int entry) {
+TLB::TteRead(int entry)
+{
if (entry >= size)
panic("entry: %d\n", entry);
}
uint64_t
-TLB::TagRead(int entry) {
+TLB::TagRead(int entry)
+{
assert(entry < size);
uint64_t tag;
if (!tlb[entry].valid)
}
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->readMiscReg(reg);
-
if (sfsr & 0x1)
sfsr = 0x3;
else
sfsr |= 1 << 6;
sfsr |= ft << 7;
sfsr |= asi << 16;
- tc->setMiscRegWithEffect(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->setMiscRegWithEffect(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->setMiscRegWithEffect(MISCREG_MMU_DTLB_SFAR, a);
-}
-
-void
-DTB::writeTagAccess(ThreadContext *tc, Addr va, int context)
-{
- TLB::writeTagAccess(tc, MISCREG_MMU_DTLB_TAG_ACCESS, va, context);
+ TLB::writeSfsr(write, ct, se, ft, asi);
+ sfar = a;
}
-
-
Fault
ITB::translate(RequestPtr &req, ThreadContext *tc)
{
- uint64_t tlbdata = tc->readMiscReg(MISCREG_TLB_DATA);
+ uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
Addr vaddr = req->getVaddr();
TlbEntry *e;
if (cacheEntry) {
if (cacheEntry->range.va < vaddr + sizeof(MachInst) &&
cacheEntry->range.va + cacheEntry->range.size >= vaddr) {
- req->setPaddr(cacheEntry->pte.paddr() & ~(cacheEntry->pte.size()-1) |
- vaddr & cacheEntry->pte.size()-1 );
- return NoFault;
+ req->setPaddr(cacheEntry->pte.translate(vaddr));
+ return NoFault;
}
} else {
req->setPaddr(vaddr & PAddrImplMask);
// 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;
}
vaddr = vaddr & VAddrAMask;
if (!validVirtualAddress(vaddr, addr_mask)) {
- writeSfsr(tc, false, ct, false, VaOutOfRange, asi);
+ writeSfsr(false, ct, false, VaOutOfRange, asi);
return new InstructionAccessException;
}
}
if (e == NULL || !e->valid) {
- writeTagAccess(tc, vaddr, context);
+ writeTagAccess(vaddr, context);
if (real)
return new InstructionRealTranslationMiss;
else
+#if FULL_SYSTEM
return new FastInstructionAccessMMUMiss;
+#else
+ return new FastInstructionAccessMMUMiss(req->getVaddr());
+#endif
}
// 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;
}
cacheState = tlbdata;
cacheEntry = e;
- req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) |
- vaddr & e->pte.size()-1 );
+ req->setPaddr(e->pte.translate(vaddr));
DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr());
return NoFault;
}
-
-
Fault
DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
{
- /* @todo this could really use some profiling and fixing to make it faster! */
- uint64_t tlbdata = tc->readMiscReg(MISCREG_TLB_DATA);
+ /*
+ * @todo this could really use some profiling and fixing to make
+ * it faster!
+ */
+ uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
Addr vaddr = req->getVaddr();
Addr size = req->getSize();
ASI asi;
asi = (ASI)req->getAsi();
bool implicit = false;
bool hpriv = bits(tlbdata,0,0);
+ bool unaligned = vaddr & (size - 1);
DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n",
vaddr, size, asi);
if (asi == ASI_IMPLICIT)
implicit = true;
- if (hpriv && implicit) {
- req->setPaddr(vaddr & PAddrImplMask);
- return NoFault;
- }
-
- // Be fast if we can!
- if (cacheValid && cacheState == tlbdata) {
- if (cacheEntry[0] && cacheAsi[0] == asi && cacheEntry[0]->range.va < vaddr + size &&
- cacheEntry[0]->range.va + cacheEntry[0]->range.size > vaddr &&
- (!write || cacheEntry[0]->pte.writable())) {
- req->setPaddr(cacheEntry[0]->pte.paddr() & ~(cacheEntry[0]->pte.size()-1) |
- vaddr & cacheEntry[0]->pte.size()-1 );
- return NoFault;
+ // Only use the fast path here if there doesn't need to be an unaligned
+ // trap later
+ if (!unaligned) {
+ if (hpriv && implicit) {
+ req->setPaddr(vaddr & PAddrImplMask);
+ return NoFault;
}
- if (cacheEntry[1] && cacheAsi[1] == asi && cacheEntry[1]->range.va < vaddr + size &&
- cacheEntry[1]->range.va + cacheEntry[1]->range.size > vaddr &&
- (!write || cacheEntry[1]->pte.writable())) {
- req->setPaddr(cacheEntry[1]->pte.paddr() & ~(cacheEntry[1]->pte.size()-1) |
- vaddr & cacheEntry[1]->pte.size()-1 );
- return NoFault;
+
+ // Be fast if we can!
+ if (cacheValid && cacheState == tlbdata) {
+
+
+
+ if (cacheEntry[0]) {
+ TlbEntry *ce = cacheEntry[0];
+ Addr ce_va = ce->range.va;
+ if (cacheAsi[0] == asi &&
+ ce_va < vaddr + size && ce_va + ce->range.size > vaddr &&
+ (!write || ce->pte.writable())) {
+ req->setPaddr(ce->pte.translate(vaddr));
+ if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1)
+ req->setFlags(Request::UNCACHEABLE);
+ DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr());
+ return NoFault;
+ } // if matched
+ } // if cache entry valid
+ if (cacheEntry[1]) {
+ TlbEntry *ce = cacheEntry[1];
+ Addr ce_va = ce->range.va;
+ if (cacheAsi[1] == asi &&
+ ce_va < vaddr + size && ce_va + ce->range.size > vaddr &&
+ (!write || ce->pte.writable())) {
+ req->setPaddr(ce->pte.translate(vaddr));
+ if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1)
+ req->setFlags(Request::UNCACHEABLE);
+ DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr());
+ return NoFault;
+ } // if matched
+ } // if cache entry valid
}
}
TlbEntry *e;
DPRINTF(TLB, "TLB: priv:%d hpriv:%d red:%d lsudm:%d part_id: %#X\n",
- priv, hpriv, red, lsu_dm, part_id);
+ priv, hpriv, red, lsu_dm, part_id);
if (implicit) {
if (tl > 0) {
// 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;
}
if (!implicit && asi != ASI_P && asi != ASI_S) {
if (AsiIsLittle(asi))
panic("Little Endian ASIs not supported\n");
- if (AsiIsBlock(asi))
- panic("Block 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");
- if (AsiIsInterrupt(asi))
- panic("Interrupt ASIs not supported\n");
+ if (AsiIsCmt(asi))
+ panic("Cmt ASI registers not implmented\n");
+
+ if (AsiIsInterrupt(asi))
+ goto handleIntRegAccess;
if (AsiIsMmu(asi))
goto handleMmuRegAccess;
if (AsiIsScratchPad(asi))
goto handleSparcErrorRegAccess;
if (!AsiIsReal(asi) && !AsiIsNucleus(asi) && !AsiIsAsIfUser(asi) &&
- !AsiIsTwin(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);
+ if (unaligned) {
+ writeSfsr(vaddr, false, ct, false, OtherFault, asi);
return new MemAddressNotAligned;
}
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;
}
-
if ((!lsu_dm && !hpriv && !red) || AsiIsReal(asi)) {
real = true;
context = 0;
- };
+ }
if (hpriv && (implicit || (!AsiIsAsIfUser(asi) && !AsiIsReal(asi)))) {
req->setPaddr(vaddr & PAddrImplMask);
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;
else
+#if FULL_SYSTEM
return new FastDataAccessMMUMiss;
+#else
+ return new FastDataAccessMMUMiss(req->getVaddr());
+#endif
}
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;
}
-
- if (e->pte.sideffect())
- req->setFlags(req->getFlags() | UNCACHEABLE);
+ if (e->pte.sideffect() || (e->pte.paddr() >> 39) & 1)
+ req->setFlags(Request::UNCACHEABLE);
// cache translation date for next translation
cacheState = tlbdata;
cacheAsi[0] = (ASI)0;
}
cacheValid = true;
- req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) |
- vaddr & e->pte.size()-1);
+ req->setPaddr(e->pte.translate(vaddr));
DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr());
return NoFault;
+
/** Normal flow ends here. */
+handleIntRegAccess:
+ if (!hpriv) {
+ writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
+ if (priv)
+ return new DataAccessException;
+ else
+ return new PrivilegedAction;
+ }
+
+ if ((asi == ASI_SWVR_UDB_INTR_W && !write) ||
+ (asi == ASI_SWVR_UDB_INTR_R && write)) {
+ writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
+ return new DataAccessException;
+ }
+
+ goto regAccessOk;
+
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);
+ if ((!hpriv && vaddr & 0xF) || vaddr > 0x3f8 || vaddr < 0x3c0) {
+ writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
return new DataAccessException;
}
goto regAccessOk;
handleSparcErrorRegAccess:
if (!hpriv) {
- if (priv) {
- writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+ writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi);
+ if (priv)
return new DataAccessException;
- } else {
- writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
+ else
return new PrivilegedAction;
- }
}
goto regAccessOk;
return NoFault;
};
+#if FULL_SYSTEM
+
Tick
DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
{
Addr va = pkt->getAddr();
ASI asi = (ASI)pkt->req->getAsi();
- uint64_t temp, data;
- uint64_t tsbtemp, cnftemp;
+ uint64_t temp;
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);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_LSU_CTRL));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_LSU_CTRL));
break;
case ASI_MMU:
switch (va) {
case 0x8:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_P_CONTEXT));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_P_CONTEXT));
break;
case 0x10:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_S_CONTEXT));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_S_CONTEXT));
break;
default:
goto doMmuReadError;
}
break;
case ASI_QUEUE:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_QUEUE_CPU_MONDO_HEAD +
+ pkt->set(tc->readMiscReg(MISCREG_QUEUE_CPU_MONDO_HEAD +
(va >> 4) - 0x3c));
break;
case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(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->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS1));
+ pkt->set(c0_tsb_ps1);
break;
case ASI_DMMU_CTXT_ZERO_CONFIG:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG));
+ pkt->set(c0_config);
break;
case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(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->readMiscRegWithEffect(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->readMiscRegWithEffect(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->readMiscRegWithEffect(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->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1));
+ pkt->set(cx_tsb_ps1);
break;
case ASI_DMMU_CTXT_NONZERO_CONFIG:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG));
+ pkt->set(cx_config);
break;
case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0:
assert(va == 0);
- pkt->set(tc->readMiscRegWithEffect(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->readMiscRegWithEffect(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->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG));
+ pkt->set(itb->cx_config);
break;
case ASI_SPARC_ERROR_STATUS_REG:
pkt->set((uint64_t)0);
break;
case ASI_HYP_SCRATCHPAD:
case ASI_SCRATCHPAD:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_SCRATCHPAD_R0 + (va >> 3)));
+ pkt->set(tc->readMiscReg(MISCREG_SCRATCHPAD_R0 + (va >> 3)));
break;
case ASI_IMMU:
switch (va) {
case 0x0:
- temp = tc->readMiscRegWithEffect(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->readMiscRegWithEffect(MISCREG_MMU_ITLB_SFSR));
+ pkt->set(itb->sfsr);
break;
case 0x30:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS));
+ pkt->set(itb->tag_access);
break;
default:
goto doMmuReadError;
case ASI_DMMU:
switch (va) {
case 0x0:
- temp = tc->readMiscRegWithEffect(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->readMiscRegWithEffect(MISCREG_MMU_DTLB_SFSR));
+ pkt->set(sfsr);
break;
case 0x20:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_SFAR));
+ pkt->set(sfar);
break;
case 0x30:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS));
+ pkt->set(tag_access);
break;
case 0x80:
- pkt->set(tc->readMiscRegWithEffect(MISCREG_MMU_PART_ID));
+ pkt->set(tc->readMiscReg(MISCREG_MMU_PART_ID));
break;
default:
goto doMmuReadError;
}
break;
case ASI_DMMU_TSB_PS0_PTR_REG:
- temp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS);
- if (bits(temp,12,0) == 0) {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS0);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG);
- } else {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS0);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG);
- }
- data = mbits(tsbtemp,63,13);
- data |= temp >> (9 + bits(cnftemp,2,0) * 3) &
- mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
- pkt->set(data);
+ pkt->set(MakeTsbPtr(Ps0,
+ tag_access,
+ c0_tsb_ps0,
+ c0_config,
+ cx_tsb_ps0,
+ cx_config));
break;
case ASI_DMMU_TSB_PS1_PTR_REG:
- temp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS);
- if (bits(temp,12,0) == 0) {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS1);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG);
- } else {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG);
- }
- data = mbits(tsbtemp,63,13);
- if (bits(tsbtemp,12,12))
- data |= ULL(1) << (13+bits(tsbtemp,3,0));
- data |= temp >> (9 + bits(cnftemp,10,8) * 3) &
- mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
- pkt->set(data);
+ pkt->set(MakeTsbPtr(Ps1,
+ tag_access,
+ c0_tsb_ps1,
+ c0_config,
+ cx_tsb_ps1,
+ cx_config));
break;
case ASI_IMMU_TSB_PS0_PTR_REG:
- temp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS);
- if (bits(temp,12,0) == 0) {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS0);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG);
- } else {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS0);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG);
- }
- data = mbits(tsbtemp,63,13);
- data |= temp >> (9 + bits(cnftemp,2,0) * 3) &
- mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
- pkt->set(data);
+ pkt->set(MakeTsbPtr(Ps0,
+ 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:
- temp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS);
- if (bits(temp,12,0) == 0) {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS1);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG);
- } else {
- tsbtemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1);
- cnftemp = tc->readMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG);
+ pkt->set(MakeTsbPtr(Ps1,
+ itb->tag_access,
+ itb->c0_tsb_ps1,
+ itb->c0_config,
+ itb->cx_tsb_ps1,
+ itb->cx_config));
+ break;
+ case ASI_SWVR_INTR_RECEIVE:
+ {
+ SparcISA::Interrupts * interrupts =
+ dynamic_cast<SparcISA::Interrupts *>(
+ tc->getCpuPtr()->getInterruptController());
+ pkt->set(interrupts->get_vec(IT_INT_VEC));
+ }
+ break;
+ case ASI_SWVR_UDB_INTR_R:
+ {
+ SparcISA::Interrupts * interrupts =
+ dynamic_cast<SparcISA::Interrupts *>(
+ tc->getCpuPtr()->getInterruptController());
+ temp = findMsbSet(interrupts->get_vec(IT_INT_VEC));
+ tc->getCpuPtr()->clearInterrupt(IT_INT_VEC, temp);
+ pkt->set(temp);
}
- data = mbits(tsbtemp,63,13);
- if (bits(tsbtemp,12,12))
- data |= ULL(1) << (13+bits(tsbtemp,3,0));
- data |= temp >> (9 + bits(cnftemp,10,8) * 3) &
- mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4);
- pkt->set(data);
break;
-
default:
doMmuReadError:
panic("need to impl DTB::doMmuRegRead() got asi=%#x, va=%#x\n",
(uint32_t)asi, va);
}
- pkt->result = Packet::Success;
- return tc->getCpuPtr()->cycles(1);
+ pkt->makeAtomicResponse();
+ return tc->getCpuPtr()->ticks(1);
}
Tick
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);
- tc->setMiscRegWithEffect(MISCREG_MMU_LSU_CTRL, data);
+ tc->setMiscReg(MISCREG_MMU_LSU_CTRL, data);
break;
case ASI_MMU:
switch (va) {
case 0x8:
- tc->setMiscRegWithEffect(MISCREG_MMU_P_CONTEXT, data);
+ tc->setMiscReg(MISCREG_MMU_P_CONTEXT, data);
break;
case 0x10:
- tc->setMiscRegWithEffect(MISCREG_MMU_S_CONTEXT, data);
+ tc->setMiscReg(MISCREG_MMU_S_CONTEXT, data);
break;
default:
goto doMmuWriteError;
break;
case ASI_QUEUE:
assert(mbits(data,13,6) == data);
- tc->setMiscRegWithEffect(MISCREG_QUEUE_CPU_MONDO_HEAD +
+ tc->setMiscReg(MISCREG_QUEUE_CPU_MONDO_HEAD +
(va >> 4) - 0x3c, data);
break;
case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS0, data);
+ c0_tsb_ps0 = data;
break;
case ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_C0_TSB_PS1, data);
+ c0_tsb_ps1 = data;
break;
case ASI_DMMU_CTXT_ZERO_CONFIG:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_C0_CONFIG, data);
+ c0_config = data;
break;
case ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0:
assert(va == 0);
- tc->setMiscRegWithEffect(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->setMiscRegWithEffect(MISCREG_MMU_ITLB_C0_TSB_PS1, data);
+ itb->c0_tsb_ps1 = data;
break;
case ASI_IMMU_CTXT_ZERO_CONFIG:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_C0_CONFIG, data);
+ itb->c0_config = data;
break;
case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS0, data);
+ cx_tsb_ps0 = data;
break;
case ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_CX_TSB_PS1, data);
+ cx_tsb_ps1 = data;
break;
case ASI_DMMU_CTXT_NONZERO_CONFIG:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_CX_CONFIG, data);
+ cx_config = data;
break;
case ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0:
assert(va == 0);
- tc->setMiscRegWithEffect(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->setMiscRegWithEffect(MISCREG_MMU_ITLB_CX_TSB_PS1, data);
+ itb->cx_tsb_ps1 = data;
break;
case ASI_IMMU_CTXT_NONZERO_CONFIG:
assert(va == 0);
- tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_CX_CONFIG, data);
+ itb->cx_config = data;
break;
case ASI_SPARC_ERROR_EN_REG:
case ASI_SPARC_ERROR_STATUS_REG:
break;
case ASI_HYP_SCRATCHPAD:
case ASI_SCRATCHPAD:
- tc->setMiscRegWithEffect(MISCREG_SCRATCHPAD_R0 + (va >> 3), data);
+ tc->setMiscReg(MISCREG_SCRATCHPAD_R0 + (va >> 3), data);
break;
case ASI_IMMU:
switch (va) {
case 0x18:
- tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_SFSR, data);
+ itb->sfsr = data;
break;
case 0x30:
sext<59>(bits(data, 59,0));
- tc->setMiscRegWithEffect(MISCREG_MMU_ITLB_TAG_ACCESS, data);
+ itb->tag_access = data;
break;
default:
goto doMmuWriteError;
entry_insert = bits(va, 8,3);
case ASI_ITLB_DATA_IN_REG:
assert(entry_insert != -1 || mbits(va,10,9) == va);
- ta_insert = tc->readMiscRegWithEffect(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->readMiscRegWithEffect(MISCREG_MMU_PART_ID);
+ part_insert = tc->readMiscReg(MISCREG_MMU_PART_ID);
real_insert = bits(va, 9,9);
pte.populate(data, bits(va,10,10) ? PageTableEntry::sun4v :
PageTableEntry::sun4u);
entry_insert = bits(va, 8,3);
case ASI_DTLB_DATA_IN_REG:
assert(entry_insert != -1 || mbits(va,10,9) == va);
- ta_insert = tc->readMiscRegWithEffect(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->readMiscRegWithEffect(MISCREG_MMU_PART_ID);
+ part_insert = tc->readMiscReg(MISCREG_MMU_PART_ID);
real_insert = bits(va, 9,9);
pte.populate(data, bits(va,10,10) ? PageTableEntry::sun4v :
PageTableEntry::sun4u);
- insert(va_insert, part_insert, ct_insert, real_insert, pte, entry_insert);
+ insert(va_insert, part_insert, ct_insert, real_insert, pte,
+ entry_insert);
break;
case ASI_IMMU_DEMAP:
ignore = false;
ctx_id = -1;
- part_id = tc->readMiscRegWithEffect(MISCREG_MMU_PART_ID);
+ part_id = tc->readMiscReg(MISCREG_MMU_PART_ID);
switch (bits(va,5,4)) {
case 0:
- ctx_id = tc->readMiscRegWithEffect(MISCREG_MMU_P_CONTEXT);
+ ctx_id = tc->readMiscReg(MISCREG_MMU_P_CONTEXT);
break;
case 1:
ignore = true;
case ASI_DMMU:
switch (va) {
case 0x18:
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_SFSR, data);
+ sfsr = data;
break;
case 0x30:
sext<59>(bits(data, 59,0));
- tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_TAG_ACCESS, data);
+ tag_access = data;
break;
case 0x80:
- tc->setMiscRegWithEffect(MISCREG_MMU_PART_ID, data);
+ tc->setMiscReg(MISCREG_MMU_PART_ID, data);
break;
default:
goto doMmuWriteError;
case ASI_DMMU_DEMAP:
ignore = false;
ctx_id = -1;
- part_id = tc->readMiscRegWithEffect(MISCREG_MMU_PART_ID);
+ part_id = tc->readMiscReg(MISCREG_MMU_PART_ID);
switch (bits(va,5,4)) {
case 0:
- ctx_id = tc->readMiscRegWithEffect(MISCREG_MMU_P_CONTEXT);
+ ctx_id = tc->readMiscReg(MISCREG_MMU_P_CONTEXT);
break;
case 1:
- ctx_id = tc->readMiscRegWithEffect(MISCREG_MMU_S_CONTEXT);
+ ctx_id = tc->readMiscReg(MISCREG_MMU_S_CONTEXT);
break;
case 3:
ctx_id = 0;
panic("Invalid type for IMMU demap\n");
}
break;
+ case ASI_SWVR_INTR_RECEIVE:
+ {
+ int msb;
+ // clear all the interrupts that aren't set in the write
+ SparcISA::Interrupts * interrupts =
+ dynamic_cast<SparcISA::Interrupts *>(
+ tc->getCpuPtr()->getInterruptController());
+ while (interrupts->get_vec(IT_INT_VEC) & data) {
+ msb = findMsbSet(interrupts->get_vec(IT_INT_VEC) & data);
+ tc->getCpuPtr()->clearInterrupt(IT_INT_VEC, msb);
+ }
+ }
+ break;
+ case ASI_SWVR_UDB_INTR_W:
+ tc->getSystemPtr()->threadContexts[bits(data,12,8)]->getCpuPtr()->
+ postInterrupt(bits(data, 5, 0), 0);
+ break;
default:
doMmuWriteError:
panic("need to impl DTB::doMmuRegWrite() got asi=%#x, va=%#x d=%#x\n",
(uint32_t)pkt->req->getAsi(), pkt->getAddr(), data);
}
- pkt->result = Packet::Success;
- return tc->getCpuPtr()->cycles(1);
+ pkt->makeAtomicResponse();
+ return tc->getCpuPtr()->ticks(1);
+}
+
+#endif
+
+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,
+ c0_tsb_ps0,
+ c0_config,
+ cx_tsb_ps0,
+ cx_config);
+ ptrs[1] = MakeTsbPtr(Ps1, tag_access,
+ c0_tsb_ps1,
+ c0_config,
+ cx_tsb_ps1,
+ cx_config);
+ ptrs[2] = MakeTsbPtr(Ps0, tag_access,
+ itb->c0_tsb_ps0,
+ itb->c0_config,
+ itb->cx_tsb_ps0,
+ itb->cx_config);
+ ptrs[3] = MakeTsbPtr(Ps1, tag_access,
+ itb->c0_tsb_ps1,
+ itb->c0_config,
+ itb->cx_tsb_ps1,
+ itb->cx_config);
+}
+
+uint64_t
+DTB::MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb,
+ uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config)
+{
+ uint64_t tsb;
+ uint64_t config;
+
+ if (bits(tag_access, 12,0) == 0) {
+ tsb = c0_tsb;
+ config = c0_config;
+ } else {
+ tsb = cX_tsb;
+ config = cX_config;
+ }
+
+ uint64_t ptr = mbits(tsb,63,13);
+ bool split = bits(tsb,12,12);
+ int tsb_size = bits(tsb,3,0);
+ int page_size = (ps == Ps0) ? bits(config, 2,0) : bits(config,10,8);
+
+ if (ps == Ps1 && split)
+ ptr |= ULL(1) << (13 + tsb_size);
+ ptr |= (tag_access >> (9 + page_size * 3)) & mask(12+tsb_size, 4);
+
+ return ptr;
}
void
SERIALIZE_SCALAR(cntr);
SERIALIZE_ARRAY(free_list, cntr);
+ 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);
+
for (int x = 0; x < size; x++) {
nameOut(os, csprintf("%s.PTE%d", name(), x));
tlb[x].serialize(os);
for (int x = 0; x < cntr; x++)
freeList.push_back(&tlb[free_list[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);
+
lookupTable.clear();
for (int x = 0; x < size; x++) {
tlb[x].unserialize(cp, csprintf("%s.PTE%d", section, x));
}
}
-
-DEFINE_SIM_OBJECT_CLASS_NAME("SparcTLB", TLB)
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITB)
-
- Param<int> size;
-
-END_DECLARE_SIM_OBJECT_PARAMS(ITB)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(ITB)
-
- INIT_PARAM_DFLT(size, "TLB size", 48)
-
-END_INIT_SIM_OBJECT_PARAMS(ITB)
-
-
-CREATE_SIM_OBJECT(ITB)
+void
+DTB::serialize(std::ostream &os)
{
- return new ITB(getInstanceName(), size);
+ TLB::serialize(os);
+ SERIALIZE_SCALAR(sfar);
}
-REGISTER_SIM_OBJECT("SparcITB", ITB)
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(DTB)
-
- Param<int> size;
-
-END_DECLARE_SIM_OBJECT_PARAMS(DTB)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(DTB)
-
- INIT_PARAM_DFLT(size, "TLB size", 64)
-
-END_INIT_SIM_OBJECT_PARAMS(DTB)
+void
+DTB::unserialize(Checkpoint *cp, const std::string §ion)
+{
+ TLB::unserialize(cp, section);
+ UNSERIALIZE_SCALAR(sfar);
+}
+/* end namespace SparcISA */ }
-CREATE_SIM_OBJECT(DTB)
+SparcISA::ITB *
+SparcITBParams::create()
{
- return new DTB(getInstanceName(), size);
+ return new SparcISA::ITB(this);
}
-REGISTER_SIM_OBJECT("SparcDTB", DTB)
+SparcISA::DTB *
+SparcDTBParams::create()
+{
+ return new SparcISA::DTB(this);
}