* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
+ * Steve Reinhardt
+ * Andrew Schultz
*/
#include <string>
#include <vector>
+#include "arch/alpha/pagetable.hh"
#include "arch/alpha/tlb.hh"
+#include "arch/alpha/faults.hh"
#include "base/inifile.hh"
#include "base/str.hh"
#include "base/trace.hh"
-#include "config/alpha_tlaser.hh"
-#include "cpu/exec_context.hh"
-#include "sim/builder.hh"
+#include "cpu/thread_context.hh"
using namespace std;
-using namespace EV5;
+
+namespace AlphaISA {
///////////////////////////////////////////////////////////////////////
//
// Alpha TLB
//
+
#ifdef DEBUG
bool uncacheBit39 = false;
bool uncacheBit40 = false;
#endif
-#define MODE2MASK(X) (1 << (X))
+#define MODE2MASK(X) (1 << (X))
-AlphaTLB::AlphaTLB(const string &name, int s)
- : SimObject(name), size(s), nlu(0)
+TLB::TLB(const Params *p)
+ : BaseTLB(p), size(p->size), nlu(0)
{
- table = new AlphaISA::PTE[size];
- memset(table, 0, sizeof(AlphaISA::PTE[size]));
+ table = new TlbEntry[size];
+ memset(table, 0, sizeof(TlbEntry[size]));
+ flushCache();
}
-AlphaTLB::~AlphaTLB()
+TLB::~TLB()
{
if (table)
delete [] table;
}
+void
+TLB::regStats()
+{
+ fetch_hits
+ .name(name() + ".fetch_hits")
+ .desc("ITB hits");
+ fetch_misses
+ .name(name() + ".fetch_misses")
+ .desc("ITB misses");
+ fetch_acv
+ .name(name() + ".fetch_acv")
+ .desc("ITB acv");
+ fetch_accesses
+ .name(name() + ".fetch_accesses")
+ .desc("ITB accesses");
+
+ fetch_accesses = fetch_hits + fetch_misses;
+
+ read_hits
+ .name(name() + ".read_hits")
+ .desc("DTB read hits")
+ ;
+
+ read_misses
+ .name(name() + ".read_misses")
+ .desc("DTB read misses")
+ ;
+
+ read_acv
+ .name(name() + ".read_acv")
+ .desc("DTB read access violations")
+ ;
+
+ read_accesses
+ .name(name() + ".read_accesses")
+ .desc("DTB read accesses")
+ ;
+
+ write_hits
+ .name(name() + ".write_hits")
+ .desc("DTB write hits")
+ ;
+
+ write_misses
+ .name(name() + ".write_misses")
+ .desc("DTB write misses")
+ ;
+
+ write_acv
+ .name(name() + ".write_acv")
+ .desc("DTB write access violations")
+ ;
+
+ write_accesses
+ .name(name() + ".write_accesses")
+ .desc("DTB write accesses")
+ ;
+
+ data_hits
+ .name(name() + ".data_hits")
+ .desc("DTB hits")
+ ;
+
+ data_misses
+ .name(name() + ".data_misses")
+ .desc("DTB misses")
+ ;
+
+ data_acv
+ .name(name() + ".data_acv")
+ .desc("DTB access violations")
+ ;
+
+ data_accesses
+ .name(name() + ".data_accesses")
+ .desc("DTB accesses")
+ ;
+
+ data_hits = read_hits + write_hits;
+ data_misses = read_misses + write_misses;
+ data_acv = read_acv + write_acv;
+ data_accesses = read_accesses + write_accesses;
+}
+
// look up an entry in the TLB
-AlphaISA::PTE *
-AlphaTLB::lookup(Addr vpn, uint8_t asn) const
+TlbEntry *
+TLB::lookup(Addr vpn, uint8_t asn)
{
// assume not found...
- AlphaISA::PTE *retval = NULL;
-
- PageTable::const_iterator i = lookupTable.find(vpn);
- if (i != lookupTable.end()) {
- while (i->first == vpn) {
- int index = i->second;
- AlphaISA::PTE *pte = &table[index];
- assert(pte->valid);
- if (vpn == pte->tag && (pte->asma || pte->asn == asn)) {
- retval = pte;
- break;
- }
+ TlbEntry *retval = NULL;
+
+ if (EntryCache[0]) {
+ if (vpn == EntryCache[0]->tag &&
+ (EntryCache[0]->asma || EntryCache[0]->asn == asn))
+ retval = EntryCache[0];
+ else if (EntryCache[1]) {
+ if (vpn == EntryCache[1]->tag &&
+ (EntryCache[1]->asma || EntryCache[1]->asn == asn))
+ retval = EntryCache[1];
+ else if (EntryCache[2] && vpn == EntryCache[2]->tag &&
+ (EntryCache[2]->asma || EntryCache[2]->asn == asn))
+ retval = EntryCache[2];
+ }
+ }
- ++i;
+ if (retval == NULL) {
+ PageTable::const_iterator i = lookupTable.find(vpn);
+ if (i != lookupTable.end()) {
+ while (i->first == vpn) {
+ int index = i->second;
+ TlbEntry *entry = &table[index];
+ assert(entry->valid);
+ if (vpn == entry->tag && (entry->asma || entry->asn == asn)) {
+ retval = updateCache(entry);
+ break;
+ }
+
+ ++i;
+ }
}
}
return retval;
}
-
Fault
-AlphaTLB::checkCacheability(RequestPtr &req)
+TLB::checkCacheability(RequestPtr &req, bool itb)
{
// in Alpha, cacheability is controlled by upper-level bits of the
// physical address
/*
- * We support having the uncacheable bit in either bit 39 or bit 40.
- * The Turbolaser platform (and EV5) support having the bit in 39, but
- * Tsunami (which Linux assumes uses an EV6) generates accesses with
- * the bit in 40. So we must check for both, but we have debug flags
- * to catch a weird case where both are used, which shouldn't happen.
+ * We support having the uncacheable bit in either bit 39 or bit
+ * 40. The Turbolaser platform (and EV5) support having the bit
+ * in 39, but Tsunami (which Linux assumes uses an EV6) generates
+ * accesses with the bit in 40. So we must check for both, but we
+ * have debug flags to catch a weird case where both are used,
+ * which shouldn't happen.
*/
-#if ALPHA_TLASER
- if (req->getPaddr() & PAddrUncachedBit39) {
-#else
if (req->getPaddr() & PAddrUncachedBit43) {
-#endif
// IPR memory space not implemented
if (PAddrIprSpace(req->getPaddr())) {
return new UnimpFault("IPR memory space not implemented!");
} else {
// mark request as uncacheable
- req->setFlags(req->getFlags() | UNCACHEABLE);
+ req->setFlags(Request::UNCACHEABLE);
-#if !ALPHA_TLASER
- // Clear bits 42:35 of the physical address (10-2 in Tsunami manual)
+ // Clear bits 42:35 of the physical address (10-2 in
+ // Tsunami manual)
req->setPaddr(req->getPaddr() & PAddrUncachedMask);
-#endif
}
+ // We shouldn't be able to read from an uncachable address in Alpha as
+ // we don't have a ROM and we don't want to try to fetch from a device
+ // register as we destroy any data that is clear-on-read.
+ if (req->isUncacheable() && itb)
+ return new UnimpFault("CPU trying to fetch from uncached I/O");
+
}
return NoFault;
}
// insert a new TLB entry
void
-AlphaTLB::insert(Addr addr, AlphaISA::PTE &pte)
+TLB::insert(Addr addr, TlbEntry &entry)
{
- AlphaISA::VAddr vaddr = addr;
+ flushCache();
+ VAddr vaddr = addr;
if (table[nlu].valid) {
Addr oldvpn = table[nlu].tag;
PageTable::iterator i = lookupTable.find(oldvpn);
lookupTable.erase(i);
}
- DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn);
+ DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), entry.ppn);
- table[nlu] = pte;
+ table[nlu] = entry;
table[nlu].tag = vaddr.vpn();
table[nlu].valid = true;
}
void
-AlphaTLB::flushAll()
+TLB::flushAll()
{
DPRINTF(TLB, "flushAll\n");
- memset(table, 0, sizeof(AlphaISA::PTE[size]));
+ memset(table, 0, sizeof(TlbEntry[size]));
+ flushCache();
lookupTable.clear();
nlu = 0;
}
void
-AlphaTLB::flushProcesses()
+TLB::flushProcesses()
{
+ flushCache();
PageTable::iterator i = lookupTable.begin();
PageTable::iterator end = lookupTable.end();
while (i != end) {
int index = i->second;
- AlphaISA::PTE *pte = &table[index];
- assert(pte->valid);
+ TlbEntry *entry = &table[index];
+ assert(entry->valid);
// we can't increment i after we erase it, so save a copy and
// increment it to get the next entry now
PageTable::iterator cur = i;
++i;
- if (!pte->asma) {
- DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn);
- pte->valid = false;
+ if (!entry->asma) {
+ DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index,
+ entry->tag, entry->ppn);
+ entry->valid = false;
lookupTable.erase(cur);
}
}
}
void
-AlphaTLB::flushAddr(Addr addr, uint8_t asn)
+TLB::flushAddr(Addr addr, uint8_t asn)
{
- AlphaISA::VAddr vaddr = addr;
+ flushCache();
+ VAddr vaddr = addr;
PageTable::iterator i = lookupTable.find(vaddr.vpn());
if (i == lookupTable.end())
return;
- while (i->first == vaddr.vpn()) {
+ while (i != lookupTable.end() && i->first == vaddr.vpn()) {
int index = i->second;
- AlphaISA::PTE *pte = &table[index];
- assert(pte->valid);
+ TlbEntry *entry = &table[index];
+ assert(entry->valid);
- if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) {
+ if (vaddr.vpn() == entry->tag && (entry->asma || entry->asn == asn)) {
DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(),
- pte->ppn);
+ entry->ppn);
// invalidate this entry
- pte->valid = false;
+ entry->valid = false;
- lookupTable.erase(i);
+ lookupTable.erase(i++);
+ } else {
+ ++i;
}
-
- ++i;
}
}
void
-AlphaTLB::serialize(ostream &os)
+TLB::serialize(ostream &os)
{
SERIALIZE_SCALAR(size);
SERIALIZE_SCALAR(nlu);
for (int i = 0; i < size; i++) {
- nameOut(os, csprintf("%s.PTE%d", name(), i));
+ nameOut(os, csprintf("%s.Entry%d", name(), i));
table[i].serialize(os);
}
}
void
-AlphaTLB::unserialize(Checkpoint *cp, const string §ion)
+TLB::unserialize(Checkpoint *cp, const string §ion)
{
UNSERIALIZE_SCALAR(size);
UNSERIALIZE_SCALAR(nlu);
for (int i = 0; i < size; i++) {
- table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
+ table[i].unserialize(cp, csprintf("%s.Entry%d", section, i));
if (table[i].valid) {
lookupTable.insert(make_pair(table[i].tag, i));
}
}
}
-
-///////////////////////////////////////////////////////////////////////
-//
-// Alpha ITB
-//
-AlphaITB::AlphaITB(const std::string &name, int size)
- : AlphaTLB(name, size)
-{}
-
-
-void
-AlphaITB::regStats()
-{
- hits
- .name(name() + ".hits")
- .desc("ITB hits");
- misses
- .name(name() + ".misses")
- .desc("ITB misses");
- acv
- .name(name() + ".acv")
- .desc("ITB acv");
- accesses
- .name(name() + ".accesses")
- .desc("ITB accesses");
-
- accesses = hits + misses;
-}
-
-
Fault
-AlphaITB::translate(RequestPtr &req, ExecContext *xc) const
+TLB::translateInst(RequestPtr req, ThreadContext *tc)
{
- if (AlphaISA::PcPAL(req->getVaddr())) {
+ //If this is a pal pc, then set PHYSICAL
+ if (FULL_SYSTEM && PcPAL(req->getPC()))
+ req->setFlags(Request::PHYSICAL);
+
+ if (PcPAL(req->getPC())) {
// strip off PAL PC marker (lsb is 1)
req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask);
- hits++;
+ fetch_hits++;
return NoFault;
}
- if (req->getFlags() & PHYSICAL) {
+ if (req->getFlags() & Request::PHYSICAL) {
req->setPaddr(req->getVaddr());
} else {
// verify that this is a good virtual address
if (!validVirtualAddress(req->getVaddr())) {
- acv++;
+ fetch_acv++;
return new ItbAcvFault(req->getVaddr());
}
// VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5
// VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6
-#if ALPHA_TLASER
- if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) &&
- VAddrSpaceEV5(req->getVaddr()) == 2) {
-#else
if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
-#endif
// only valid in kernel mode
- if (ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM)) !=
- AlphaISA::mode_kernel) {
- acv++;
+ if (ICM_CM(tc->readMiscRegNoEffect(IPR_ICM)) !=
+ mode_kernel) {
+ fetch_acv++;
return new ItbAcvFault(req->getVaddr());
}
req->setPaddr(req->getVaddr() & PAddrImplMask);
-#if !ALPHA_TLASER
// sign extend the physical address properly
if (req->getPaddr() & PAddrUncachedBit40)
req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
else
req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
-#endif
-
} else {
// not a physical address: need to look up pte
- int asn = DTB_ASN_ASN(xc->readMiscReg(AlphaISA::IPR_DTB_ASN));
- AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(),
- asn);
+ int asn = DTB_ASN_ASN(tc->readMiscRegNoEffect(IPR_DTB_ASN));
+ TlbEntry *entry = lookup(VAddr(req->getVaddr()).vpn(),
+ asn);
- if (!pte) {
- misses++;
+ if (!entry) {
+ fetch_misses++;
return new ItbPageFault(req->getVaddr());
}
- req->setPaddr((pte->ppn << AlphaISA::PageShift) +
- (AlphaISA::VAddr(req->getVaddr()).offset()
+ req->setPaddr((entry->ppn << PageShift) +
+ (VAddr(req->getVaddr()).offset()
& ~3));
// check permissions for this access
- if (!(pte->xre &
- (1 << ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM))))) {
+ if (!(entry->xre &
+ (1 << ICM_CM(tc->readMiscRegNoEffect(IPR_ICM))))) {
// instruction access fault
- acv++;
+ fetch_acv++;
return new ItbAcvFault(req->getVaddr());
}
- hits++;
+ fetch_hits++;
}
}
if (req->getPaddr() & ~PAddrImplMask)
return genMachineCheckFault();
- return checkCacheability(req);
-
-}
-
-///////////////////////////////////////////////////////////////////////
-//
-// Alpha DTB
-//
-AlphaDTB::AlphaDTB(const std::string &name, int size)
- : AlphaTLB(name, size)
-{}
-
-void
-AlphaDTB::regStats()
-{
- read_hits
- .name(name() + ".read_hits")
- .desc("DTB read hits")
- ;
-
- read_misses
- .name(name() + ".read_misses")
- .desc("DTB read misses")
- ;
-
- read_acv
- .name(name() + ".read_acv")
- .desc("DTB read access violations")
- ;
-
- read_accesses
- .name(name() + ".read_accesses")
- .desc("DTB read accesses")
- ;
-
- write_hits
- .name(name() + ".write_hits")
- .desc("DTB write hits")
- ;
-
- write_misses
- .name(name() + ".write_misses")
- .desc("DTB write misses")
- ;
-
- write_acv
- .name(name() + ".write_acv")
- .desc("DTB write access violations")
- ;
-
- write_accesses
- .name(name() + ".write_accesses")
- .desc("DTB write accesses")
- ;
-
- hits
- .name(name() + ".hits")
- .desc("DTB hits")
- ;
-
- misses
- .name(name() + ".misses")
- .desc("DTB misses")
- ;
-
- acv
- .name(name() + ".acv")
- .desc("DTB access violations")
- ;
-
- accesses
- .name(name() + ".accesses")
- .desc("DTB accesses")
- ;
+ return checkCacheability(req, true);
- hits = read_hits + write_hits;
- misses = read_misses + write_misses;
- acv = read_acv + write_acv;
- accesses = read_accesses + write_accesses;
}
Fault
-AlphaDTB::translate(RequestPtr &req, ExecContext *xc, bool write) const
+TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
{
- Addr pc = xc->readPC();
-
- AlphaISA::mode_type mode =
- (AlphaISA::mode_type)DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM));
+ Addr pc = tc->readPC();
+ mode_type mode =
+ (mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM));
/**
* Check for alignment faults
*/
if (req->getVaddr() & (req->getSize() - 1)) {
- DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(),
+ DPRINTF(TLB, "Alignment Fault on %#x, size = %d\n", req->getVaddr(),
req->getSize());
uint64_t flags = write ? MM_STAT_WR_MASK : 0;
return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags);
}
- if (pc & 0x1) {
- mode = (req->getFlags() & ALTMODE) ?
- (AlphaISA::mode_type)ALT_MODE_AM(
- xc->readMiscReg(AlphaISA::IPR_ALT_MODE))
- : AlphaISA::mode_kernel;
+ if (PcPAL(pc)) {
+ mode = (req->getFlags() & Request::ALTMODE) ?
+ (mode_type)ALT_MODE_AM(
+ tc->readMiscRegNoEffect(IPR_ALT_MODE))
+ : mode_kernel;
}
- if (req->getFlags() & PHYSICAL) {
+ if (req->getFlags() & Request::PHYSICAL) {
req->setPaddr(req->getVaddr());
} else {
// verify that this is a good virtual address
}
// Check for "superpage" mapping
-#if ALPHA_TLASER
- if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) &&
- VAddrSpaceEV5(req->getVaddr()) == 2) {
-#else
if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
-#endif
-
// only valid in kernel mode
- if (DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)) !=
- AlphaISA::mode_kernel) {
+ if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) !=
+ mode_kernel) {
if (write) { write_acv++; } else { read_acv++; }
uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
MM_STAT_ACV_MASK);
- return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
+
+ return new DtbAcvFault(req->getVaddr(), req->getFlags(),
+ flags);
}
req->setPaddr(req->getVaddr() & PAddrImplMask);
-#if !ALPHA_TLASER
// sign extend the physical address properly
if (req->getPaddr() & PAddrUncachedBit40)
req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
else
req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
-#endif
-
} else {
if (write)
write_accesses++;
else
read_accesses++;
- int asn = DTB_ASN_ASN(xc->readMiscReg(AlphaISA::IPR_DTB_ASN));
+ int asn = DTB_ASN_ASN(tc->readMiscRegNoEffect(IPR_DTB_ASN));
// not a physical address: need to look up pte
- AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(),
- asn);
+ TlbEntry *entry = lookup(VAddr(req->getVaddr()).vpn(), asn);
- if (!pte) {
+ if (!entry) {
// page fault
if (write) { write_misses++; } else { read_misses++; }
uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
MM_STAT_DTB_MISS_MASK;
- return (req->getFlags() & VPTE) ?
+ return (req->getFlags() & Request::VPTE) ?
(Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(),
flags)) :
(Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(),
flags));
}
- req->setPaddr((pte->ppn << AlphaISA::PageShift) +
- AlphaISA::VAddr(req->getVaddr()).offset());
+ req->setPaddr((entry->ppn << PageShift) +
+ VAddr(req->getVaddr()).offset());
if (write) {
- if (!(pte->xwe & MODE2MASK(mode))) {
+ if (!(entry->xwe & MODE2MASK(mode))) {
// declare the instruction access fault
write_acv++;
uint64_t flags = MM_STAT_WR_MASK |
MM_STAT_ACV_MASK |
- (pte->fonw ? MM_STAT_FONW_MASK : 0);
- return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
+ (entry->fonw ? MM_STAT_FONW_MASK : 0);
+ return new DtbPageFault(req->getVaddr(), req->getFlags(),
+ flags);
}
- if (pte->fonw) {
+ if (entry->fonw) {
write_acv++;
- uint64_t flags = MM_STAT_WR_MASK |
- MM_STAT_FONW_MASK;
- return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
+ uint64_t flags = MM_STAT_WR_MASK | MM_STAT_FONW_MASK;
+ return new DtbPageFault(req->getVaddr(), req->getFlags(),
+ flags);
}
} else {
- if (!(pte->xre & MODE2MASK(mode))) {
+ if (!(entry->xre & MODE2MASK(mode))) {
read_acv++;
uint64_t flags = MM_STAT_ACV_MASK |
- (pte->fonr ? MM_STAT_FONR_MASK : 0);
- return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
+ (entry->fonr ? MM_STAT_FONR_MASK : 0);
+ return new DtbAcvFault(req->getVaddr(), req->getFlags(),
+ flags);
}
- if (pte->fonr) {
+ if (entry->fonr) {
read_acv++;
uint64_t flags = MM_STAT_FONR_MASK;
- return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
+ return new DtbPageFault(req->getVaddr(), req->getFlags(),
+ flags);
}
}
}
return checkCacheability(req);
}
-AlphaISA::PTE &
-AlphaTLB::index(bool advance)
+TlbEntry &
+TLB::index(bool advance)
{
- AlphaISA::PTE *pte = &table[nlu];
+ TlbEntry *entry = &table[nlu];
if (advance)
nextnlu();
- return *pte;
+ return *entry;
}
-DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", AlphaTLB)
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaITB)
-
- Param<int> size;
-
-END_DECLARE_SIM_OBJECT_PARAMS(AlphaITB)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaITB)
-
- INIT_PARAM_DFLT(size, "TLB size", 48)
-
-END_INIT_SIM_OBJECT_PARAMS(AlphaITB)
-
-
-CREATE_SIM_OBJECT(AlphaITB)
+Fault
+TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
{
- return new AlphaITB(getInstanceName(), size);
+ if (mode == Execute)
+ return translateInst(req, tc);
+ else
+ return translateData(req, tc, mode == Write);
}
-REGISTER_SIM_OBJECT("AlphaITB", AlphaITB)
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB)
-
- Param<int> size;
-
-END_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDTB)
-
- INIT_PARAM_DFLT(size, "TLB size", 64)
-
-END_INIT_SIM_OBJECT_PARAMS(AlphaDTB)
-
-
-CREATE_SIM_OBJECT(AlphaDTB)
+void
+TLB::translateTiming(RequestPtr req, ThreadContext *tc,
+ Translation *translation, Mode mode)
{
- return new AlphaDTB(getInstanceName(), size);
+ assert(translation);
+ translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
}
-REGISTER_SIM_OBJECT("AlphaDTB", AlphaDTB)
+/* end namespace AlphaISA */ }
+AlphaISA::TLB *
+AlphaTLBParams::create()
+{
+ return new AlphaISA::TLB(this);
+}