51,54c51,54
< ///////////////////////////////////////////////////////////////////////
< //
< // Alpha TLB
< //
---
> ///////////////////////////////////////////////////////////////////////
> //
> // Alpha TLB
> //
56,57c56,57
< bool uncacheBit39 = false;
< bool uncacheBit40 = false;
---
> bool uncacheBit39 = false;
> bool uncacheBit40 = false;
62,67c62,67
< TLB::TLB(const string &name, int s)
< : SimObject(name), size(s), nlu(0)
< {
< table = new PTE[size];
< memset(table, 0, sizeof(PTE[size]));
< }
---
> TLB::TLB(const string &name, int s)
> : SimObject(name), size(s), nlu(0)
> {
> table = new PTE[size];
> memset(table, 0, sizeof(PTE[size]));
> }
69,73c69,73
< TLB::~TLB()
< {
< if (table)
< delete [] table;
< }
---
> TLB::~TLB()
> {
> if (table)
> delete [] table;
> }
75,80c75,80
< // look up an entry in the TLB
< PTE *
< TLB::lookup(Addr vpn, uint8_t asn) const
< {
< // assume not found...
< PTE *retval = NULL;
---
> // look up an entry in the TLB
> PTE *
> TLB::lookup(Addr vpn, uint8_t asn) const
> {
> // assume not found...
> PTE *retval = NULL;
82,93c82,90
< PageTable::const_iterator i = lookupTable.find(vpn);
< if (i != lookupTable.end()) {
< while (i->first == vpn) {
< int index = i->second;
< PTE *pte = &table[index];
< assert(pte->valid);
< if (vpn == pte->tag && (pte->asma || pte->asn == asn)) {
< retval = pte;
< break;
< }
<
< ++i;
---
> PageTable::const_iterator i = lookupTable.find(vpn);
> if (i != lookupTable.end()) {
> while (i->first == vpn) {
> int index = i->second;
> PTE *pte = &table[index];
> assert(pte->valid);
> if (vpn == pte->tag && (pte->asma || pte->asn == asn)) {
> retval = pte;
> break;
95d91
< }
97,99c93,94
< DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
< retval ? "hit" : "miss", retval ? retval->ppn : 0);
< return retval;
---
> ++i;
> }
101a97,100
> DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
> retval ? "hit" : "miss", retval ? retval->ppn : 0);
> return retval;
> }
103,107d101
< Fault
< TLB::checkCacheability(RequestPtr &req)
< {
< // in Alpha, cacheability is controlled by upper-level bits of the
< // physical address
109,115c103,107
< /*
< * 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.
< */
---
> Fault
> TLB::checkCacheability(RequestPtr &req)
> {
> // in Alpha, cacheability is controlled by upper-level bits of the
> // physical address
116a109,115
> /*
> * 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.
> */
117a117
>
119c119
< if (req->getPaddr() & PAddrUncachedBit39) {
---
> if (req->getPaddr() & PAddrUncachedBit39) {
121c121
< if (req->getPaddr() & PAddrUncachedBit43) {
---
> if (req->getPaddr() & PAddrUncachedBit43) {
123,128c123,128
< // 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);
---
> // 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);
131,132c131,132
< // Clear bits 42:35 of the physical address (10-2 in Tsunami manual)
< req->setPaddr(req->getPaddr() & PAddrUncachedMask);
---
> // Clear bits 42:35 of the physical address (10-2 in Tsunami manual)
> req->setPaddr(req->getPaddr() & PAddrUncachedMask);
134d133
< }
136d134
< return NoFault;
137a136,137
> return NoFault;
> }
140,147c140,147
< // insert a new TLB entry
< void
< TLB::insert(Addr addr, PTE &pte)
< {
< VAddr vaddr = addr;
< if (table[nlu].valid) {
< Addr oldvpn = table[nlu].tag;
< PageTable::iterator i = lookupTable.find(oldvpn);
---
> // insert a new TLB entry
> void
> TLB::insert(Addr addr, PTE &pte)
> {
> VAddr vaddr = addr;
> if (table[nlu].valid) {
> Addr oldvpn = table[nlu].tag;
> PageTable::iterator i = lookupTable.find(oldvpn);
149c149,154
< if (i == lookupTable.end())
---
> if (i == lookupTable.end())
> panic("TLB entry not found in lookupTable");
>
> int index;
> while ((index = i->second) != nlu) {
> if (table[index].tag != oldvpn)
152,155c157,158
< int index;
< while ((index = i->second) != nlu) {
< if (table[index].tag != oldvpn)
< panic("TLB entry not found in lookupTable");
---
> ++i;
> }
157,158c160
< ++i;
< }
---
> DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn);
160c162,163
< DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn);
---
> lookupTable.erase(i);
> }
162,163c165
< lookupTable.erase(i);
< }
---
> DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn);
165c167,169
< DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn);
---
> table[nlu] = pte;
> table[nlu].tag = vaddr.vpn();
> table[nlu].valid = true;
167,169c171,173
< table[nlu] = pte;
< table[nlu].tag = vaddr.vpn();
< table[nlu].valid = true;
---
> lookupTable.insert(make_pair(vaddr.vpn(), nlu));
> nextnlu();
> }
171,173c175,182
< lookupTable.insert(make_pair(vaddr.vpn(), nlu));
< nextnlu();
< }
---
> void
> TLB::flushAll()
> {
> DPRINTF(TLB, "flushAll\n");
> memset(table, 0, sizeof(PTE[size]));
> lookupTable.clear();
> nlu = 0;
> }
175,182c184,192
< void
< TLB::flushAll()
< {
< DPRINTF(TLB, "flushAll\n");
< memset(table, 0, sizeof(PTE[size]));
< lookupTable.clear();
< nlu = 0;
< }
---
> void
> TLB::flushProcesses()
> {
> PageTable::iterator i = lookupTable.begin();
> PageTable::iterator end = lookupTable.end();
> while (i != end) {
> int index = i->second;
> PTE *pte = &table[index];
> assert(pte->valid);
184,192c194,197
< void
< TLB::flushProcesses()
< {
< PageTable::iterator i = lookupTable.begin();
< PageTable::iterator end = lookupTable.end();
< while (i != end) {
< int index = i->second;
< PTE *pte = &table[index];
< assert(pte->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;
194,203c199,202
< // 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;
< lookupTable.erase(cur);
< }
---
> if (!pte->asma) {
> DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn);
> pte->valid = false;
> lookupTable.erase(cur);
205a205
> }
207,210c207,210
< void
< TLB::flushAddr(Addr addr, uint8_t asn)
< {
< VAddr vaddr = addr;
---
> void
> TLB::flushAddr(Addr addr, uint8_t asn)
> {
> VAddr vaddr = addr;
212,214c212,214
< PageTable::iterator i = lookupTable.find(vaddr.vpn());
< if (i == lookupTable.end())
< return;
---
> PageTable::iterator i = lookupTable.find(vaddr.vpn());
> if (i == lookupTable.end())
> return;
216,219c216,219
< while (i->first == vaddr.vpn()) {
< int index = i->second;
< PTE *pte = &table[index];
< assert(pte->valid);
---
> while (i->first == vaddr.vpn()) {
> int index = i->second;
> PTE *pte = &table[index];
> assert(pte->valid);
221,223c221,223
< if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) {
< DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(),
< pte->ppn);
---
> if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) {
> DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(),
> pte->ppn);
225,226c225,226
< // invalidate this entry
< pte->valid = false;
---
> // invalidate this entry
> pte->valid = false;
228,231c228
< lookupTable.erase(i);
< }
<
< ++i;
---
> lookupTable.erase(i);
232a230,231
>
> ++i;
233a233
> }
236,240c236,240
< void
< TLB::serialize(ostream &os)
< {
< SERIALIZE_SCALAR(size);
< SERIALIZE_SCALAR(nlu);
---
> void
> TLB::serialize(ostream &os)
> {
> SERIALIZE_SCALAR(size);
> SERIALIZE_SCALAR(nlu);
242,245c242,244
< for (int i = 0; i < size; i++) {
< nameOut(os, csprintf("%s.PTE%d", name(), i));
< table[i].serialize(os);
< }
---
> for (int i = 0; i < size; i++) {
> nameOut(os, csprintf("%s.PTE%d", name(), i));
> table[i].serialize(os);
246a246
> }
248,252c248,252
< void
< TLB::unserialize(Checkpoint *cp, const string &section)
< {
< UNSERIALIZE_SCALAR(size);
< UNSERIALIZE_SCALAR(nlu);
---
> void
> TLB::unserialize(Checkpoint *cp, const string &section)
> {
> UNSERIALIZE_SCALAR(size);
> UNSERIALIZE_SCALAR(nlu);
254,258c254,257
< for (int i = 0; i < size; i++) {
< table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
< if (table[i].valid) {
< lookupTable.insert(make_pair(table[i].tag, i));
< }
---
> for (int i = 0; i < size; i++) {
> table[i].unserialize(cp, csprintf("%s.PTE%d", section, i));
> if (table[i].valid) {
> lookupTable.insert(make_pair(table[i].tag, i));
260a260
> }
263,269c263,269
< ///////////////////////////////////////////////////////////////////////
< //
< // Alpha ITB
< //
< ITB::ITB(const std::string &name, int size)
< : TLB(name, size)
< {}
---
> ///////////////////////////////////////////////////////////////////////
> //
> // Alpha ITB
> //
> ITB::ITB(const std::string &name, int size)
> : TLB(name, size)
> {}
272,286c272,286
< void
< ITB::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");
---
> void
> ITB::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");
288,289c288,289
< accesses = hits + misses;
< }
---
> accesses = hits + misses;
> }
292,299c292,308
< Fault
< ITB::translate(RequestPtr &req, ThreadContext *tc) const
< {
< if (PcPAL(req->getPC())) {
< // strip off PAL PC marker (lsb is 1)
< req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask);
< hits++;
< return NoFault;
---
> Fault
> ITB::translate(RequestPtr &req, ThreadContext *tc) const
> {
> if (PcPAL(req->getPC())) {
> // strip off PAL PC marker (lsb is 1)
> req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask);
> hits++;
> return NoFault;
> }
>
> if (req->getFlags() & PHYSICAL) {
> req->setPaddr(req->getVaddr());
> } else {
> // verify that this is a good virtual address
> if (!validVirtualAddress(req->getVaddr())) {
> acv++;
> return new ItbAcvFault(req->getVaddr());
302,309d310
< if (req->getFlags() & PHYSICAL) {
< req->setPaddr(req->getVaddr());
< } else {
< // verify that this is a good virtual address
< if (!validVirtualAddress(req->getVaddr())) {
< acv++;
< return new ItbAcvFault(req->getVaddr());
< }
311,313c312,313
<
< // 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
---
> // 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
315,316c315,316
< if ((MCSR_SP(tc->readMiscReg(IPR_MCSR)) & 2) &&
< VAddrSpaceEV5(req->getVaddr()) == 2) {
---
> if ((MCSR_SP(tc->readMiscReg(IPR_MCSR)) & 2) &&
> VAddrSpaceEV5(req->getVaddr()) == 2) {
318c318
< if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
---
> if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
320,325c320,325
< // only valid in kernel mode
< if (ICM_CM(tc->readMiscReg(IPR_ICM)) !=
< mode_kernel) {
< acv++;
< return new ItbAcvFault(req->getVaddr());
< }
---
> // only valid in kernel mode
> if (ICM_CM(tc->readMiscReg(IPR_ICM)) !=
> mode_kernel) {
> acv++;
> return new ItbAcvFault(req->getVaddr());
> }
327c327
< req->setPaddr(req->getVaddr() & PAddrImplMask);
---
> req->setPaddr(req->getVaddr() & PAddrImplMask);
330,334c330,334
< // sign extend the physical address properly
< if (req->getPaddr() & PAddrUncachedBit40)
< req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
< else
< req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
---
> // sign extend the physical address properly
> if (req->getPaddr() & PAddrUncachedBit40)
> req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
> else
> req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
337,341c337,341
< } else {
< // not a physical address: need to look up pte
< int asn = DTB_ASN_ASN(tc->readMiscReg(IPR_DTB_ASN));
< PTE *pte = lookup(VAddr(req->getVaddr()).vpn(),
< asn);
---
> } else {
> // not a physical address: need to look up pte
> int asn = DTB_ASN_ASN(tc->readMiscReg(IPR_DTB_ASN));
> PTE *pte = lookup(VAddr(req->getVaddr()).vpn(),
> asn);
343,346c343,346
< if (!pte) {
< misses++;
< return new ItbPageFault(req->getVaddr());
< }
---
> if (!pte) {
> misses++;
> return new ItbPageFault(req->getVaddr());
> }
348,350c348,350
< req->setPaddr((pte->ppn << PageShift) +
< (VAddr(req->getVaddr()).offset()
< & ~3));
---
> req->setPaddr((pte->ppn << PageShift) +
> (VAddr(req->getVaddr()).offset()
> & ~3));
352,360c352,357
< // check permissions for this access
< if (!(pte->xre &
< (1 << ICM_CM(tc->readMiscReg(IPR_ICM))))) {
< // instruction access fault
< acv++;
< return new ItbAcvFault(req->getVaddr());
< }
<
< hits++;
---
> // check permissions for this access
> if (!(pte->xre &
> (1 << ICM_CM(tc->readMiscReg(IPR_ICM))))) {
> // instruction access fault
> acv++;
> return new ItbAcvFault(req->getVaddr());
361a359,360
>
> hits++;
362a362
> }
364,366c364,366
< // check that the physical address is ok (catch bad physical addresses)
< if (req->getPaddr() & ~PAddrImplMask)
< return genMachineCheckFault();
---
> // check that the physical address is ok (catch bad physical addresses)
> if (req->getPaddr() & ~PAddrImplMask)
> return genMachineCheckFault();
368c368
< return checkCacheability(req);
---
> return checkCacheability(req);
370c370
< }
---
> }
372,378c372,378
< ///////////////////////////////////////////////////////////////////////
< //
< // Alpha DTB
< //
< DTB::DTB(const std::string &name, int size)
< : TLB(name, size)
< {}
---
> ///////////////////////////////////////////////////////////////////////
> //
> // Alpha DTB
> //
> DTB::DTB(const std::string &name, int size)
> : TLB(name, size)
> {}
380,386c380,386
< void
< DTB::regStats()
< {
< read_hits
< .name(name() + ".read_hits")
< .desc("DTB read hits")
< ;
---
> void
> DTB::regStats()
> {
> read_hits
> .name(name() + ".read_hits")
> .desc("DTB read hits")
> ;
388,391c388,391
< read_misses
< .name(name() + ".read_misses")
< .desc("DTB read misses")
< ;
---
> read_misses
> .name(name() + ".read_misses")
> .desc("DTB read misses")
> ;
393,396c393,396
< read_acv
< .name(name() + ".read_acv")
< .desc("DTB read access violations")
< ;
---
> read_acv
> .name(name() + ".read_acv")
> .desc("DTB read access violations")
> ;
398,401c398,401
< read_accesses
< .name(name() + ".read_accesses")
< .desc("DTB read accesses")
< ;
---
> read_accesses
> .name(name() + ".read_accesses")
> .desc("DTB read accesses")
> ;
403,406c403,406
< write_hits
< .name(name() + ".write_hits")
< .desc("DTB write hits")
< ;
---
> write_hits
> .name(name() + ".write_hits")
> .desc("DTB write hits")
> ;
408,411c408,411
< write_misses
< .name(name() + ".write_misses")
< .desc("DTB write misses")
< ;
---
> write_misses
> .name(name() + ".write_misses")
> .desc("DTB write misses")
> ;
413,416c413,416
< write_acv
< .name(name() + ".write_acv")
< .desc("DTB write access violations")
< ;
---
> write_acv
> .name(name() + ".write_acv")
> .desc("DTB write access violations")
> ;
418,421c418,421
< write_accesses
< .name(name() + ".write_accesses")
< .desc("DTB write accesses")
< ;
---
> write_accesses
> .name(name() + ".write_accesses")
> .desc("DTB write accesses")
> ;
423,426c423,426
< hits
< .name(name() + ".hits")
< .desc("DTB hits")
< ;
---
> hits
> .name(name() + ".hits")
> .desc("DTB hits")
> ;
428,431c428,431
< misses
< .name(name() + ".misses")
< .desc("DTB misses")
< ;
---
> misses
> .name(name() + ".misses")
> .desc("DTB misses")
> ;
433,436c433,436
< acv
< .name(name() + ".acv")
< .desc("DTB access violations")
< ;
---
> acv
> .name(name() + ".acv")
> .desc("DTB access violations")
> ;
438,441c438,441
< accesses
< .name(name() + ".accesses")
< .desc("DTB accesses")
< ;
---
> accesses
> .name(name() + ".accesses")
> .desc("DTB accesses")
> ;
443,447c443,447
< hits = read_hits + write_hits;
< misses = read_misses + write_misses;
< acv = read_acv + write_acv;
< accesses = read_accesses + write_accesses;
< }
---
> hits = read_hits + write_hits;
> misses = read_misses + write_misses;
> acv = read_acv + write_acv;
> accesses = read_accesses + write_accesses;
> }
449,452c449,452
< Fault
< DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const
< {
< Addr pc = tc->readPC();
---
> Fault
> DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const
> {
> Addr pc = tc->readPC();
454,455c454,455
< mode_type mode =
< (mode_type)DTB_CM_CM(tc->readMiscReg(IPR_DTB_CM));
---
> mode_type mode =
> (mode_type)DTB_CM_CM(tc->readMiscReg(IPR_DTB_CM));
458,466c458,466
< /**
< * Check for alignment faults
< */
< if (req->getVaddr() & (req->getSize() - 1)) {
< DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(),
< req->getSize());
< uint64_t flags = write ? MM_STAT_WR_MASK : 0;
< return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags);
< }
---
> /**
> * Check for alignment faults
> */
> if (req->getVaddr() & (req->getSize() - 1)) {
> DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(),
> req->getSize());
> uint64_t flags = write ? MM_STAT_WR_MASK : 0;
> return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags);
> }
468,472c468,484
< if (pc & 0x1) {
< mode = (req->getFlags() & ALTMODE) ?
< (mode_type)ALT_MODE_AM(
< tc->readMiscReg(IPR_ALT_MODE))
< : mode_kernel;
---
> if (PcPAL(pc)) {
> mode = (req->getFlags() & ALTMODE) ?
> (mode_type)ALT_MODE_AM(
> tc->readMiscReg(IPR_ALT_MODE))
> : mode_kernel;
> }
>
> if (req->getFlags() & PHYSICAL) {
> req->setPaddr(req->getVaddr());
> } else {
> // verify that this is a good virtual address
> if (!validVirtualAddress(req->getVaddr())) {
> if (write) { write_acv++; } else { read_acv++; }
> uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
> MM_STAT_BAD_VA_MASK |
> MM_STAT_ACV_MASK;
> return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
475,487c487
< if (req->getFlags() & PHYSICAL) {
< req->setPaddr(req->getVaddr());
< } else {
< // verify that this is a good virtual address
< if (!validVirtualAddress(req->getVaddr())) {
< if (write) { write_acv++; } else { read_acv++; }
< uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
< MM_STAT_BAD_VA_MASK |
< MM_STAT_ACV_MASK;
< return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
< }
<
< // Check for "superpage" mapping
---
> // Check for "superpage" mapping
489,490c489,490
< if ((MCSR_SP(tc->readMiscReg(IPR_MCSR)) & 2) &&
< VAddrSpaceEV5(req->getVaddr()) == 2) {
---
> if ((MCSR_SP(tc->readMiscReg(IPR_MCSR)) & 2) &&
> VAddrSpaceEV5(req->getVaddr()) == 2) {
492c492
< if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
---
> if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
495,502c495,502
< // only valid in kernel mode
< if (DTB_CM_CM(tc->readMiscReg(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);
< }
---
> // only valid in kernel mode
> if (DTB_CM_CM(tc->readMiscReg(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);
> }
504c504
< req->setPaddr(req->getVaddr() & PAddrImplMask);
---
> req->setPaddr(req->getVaddr() & PAddrImplMask);
507,511c507,511
< // sign extend the physical address properly
< if (req->getPaddr() & PAddrUncachedBit40)
< req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
< else
< req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
---
> // sign extend the physical address properly
> if (req->getPaddr() & PAddrUncachedBit40)
> req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
> else
> req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
514,518c514,518
< } else {
< if (write)
< write_accesses++;
< else
< read_accesses++;
---
> } else {
> if (write)
> write_accesses++;
> else
> read_accesses++;
520c520
< int asn = DTB_ASN_ASN(tc->readMiscReg(IPR_DTB_ASN));
---
> int asn = DTB_ASN_ASN(tc->readMiscReg(IPR_DTB_ASN));
522,524c522,524
< // not a physical address: need to look up pte
< PTE *pte = lookup(VAddr(req->getVaddr()).vpn(),
< asn);
---
> // not a physical address: need to look up pte
> PTE *pte = lookup(VAddr(req->getVaddr()).vpn(),
> asn);
526,536c526,536
< if (!pte) {
< // 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) ?
< (Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(),
< flags)) :
< (Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(),
< flags));
< }
---
> if (!pte) {
> // 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) ?
> (Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(),
> flags)) :
> (Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(),
> flags));
> }
538,539c538,539
< req->setPaddr((pte->ppn << PageShift) +
< VAddr(req->getVaddr()).offset());
---
> req->setPaddr((pte->ppn << PageShift) +
> VAddr(req->getVaddr()).offset());
541,567c541,548
< if (write) {
< if (!(pte->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);
< }
< if (pte->fonw) {
< write_acv++;
< 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))) {
< read_acv++;
< uint64_t flags = MM_STAT_ACV_MASK |
< (pte->fonr ? MM_STAT_FONR_MASK : 0);
< return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
< }
< if (pte->fonr) {
< read_acv++;
< uint64_t flags = MM_STAT_FONR_MASK;
< return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
< }
---
> if (write) {
> if (!(pte->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);
568a550,567
> if (pte->fonw) {
> write_acv++;
> 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))) {
> read_acv++;
> uint64_t flags = MM_STAT_ACV_MASK |
> (pte->fonr ? MM_STAT_FONR_MASK : 0);
> return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags);
> }
> if (pte->fonr) {
> read_acv++;
> uint64_t flags = MM_STAT_FONR_MASK;
> return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
> }
570,574d568
<
< if (write)
< write_hits++;
< else
< read_hits++;
577,581c571,574
< // check that the physical address is ok (catch bad physical addresses)
< if (req->getPaddr() & ~PAddrImplMask)
< return genMachineCheckFault();
<
< return checkCacheability(req);
---
> if (write)
> write_hits++;
> else
> read_hits++;
584,587c577,579
< PTE &
< TLB::index(bool advance)
< {
< PTE *pte = &table[nlu];
---
> // check that the physical address is ok (catch bad physical addresses)
> if (req->getPaddr() & ~PAddrImplMask)
> return genMachineCheckFault();
589,590c581,582
< if (advance)
< nextnlu();
---
> return checkCacheability(req);
> }
592,593c584,587
< return *pte;
< }
---
> PTE &
> TLB::index(bool advance)
> {
> PTE *pte = &table[nlu];
595c589,590
< DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", TLB)
---
> if (advance)
> nextnlu();
597c592,593
< BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITB)
---
> return *pte;
> }
599c595
< Param<int> size;
---
> DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", TLB)
601c597
< END_DECLARE_SIM_OBJECT_PARAMS(ITB)
---
> BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITB)
603c599
< BEGIN_INIT_SIM_OBJECT_PARAMS(ITB)
---
> Param<int> size;
605c601
< INIT_PARAM_DFLT(size, "TLB size", 48)
---
> END_DECLARE_SIM_OBJECT_PARAMS(ITB)
607c603
< END_INIT_SIM_OBJECT_PARAMS(ITB)
---
> BEGIN_INIT_SIM_OBJECT_PARAMS(ITB)
608a605
> INIT_PARAM_DFLT(size, "TLB size", 48)
610,613c607
< CREATE_SIM_OBJECT(ITB)
< {
< return new ITB(getInstanceName(), size);
< }
---
> END_INIT_SIM_OBJECT_PARAMS(ITB)
615d608
< REGISTER_SIM_OBJECT("AlphaITB", ITB)
617c610,613
< BEGIN_DECLARE_SIM_OBJECT_PARAMS(DTB)
---
> CREATE_SIM_OBJECT(ITB)
> {
> return new ITB(getInstanceName(), size);
> }
619c615
< Param<int> size;
---
> REGISTER_SIM_OBJECT("AlphaITB", ITB)
621c617
< END_DECLARE_SIM_OBJECT_PARAMS(DTB)
---
> BEGIN_DECLARE_SIM_OBJECT_PARAMS(DTB)
623c619
< BEGIN_INIT_SIM_OBJECT_PARAMS(DTB)
---
> Param<int> size;
625c621
< INIT_PARAM_DFLT(size, "TLB size", 64)
---
> END_DECLARE_SIM_OBJECT_PARAMS(DTB)
627c623
< END_INIT_SIM_OBJECT_PARAMS(DTB)
---
> BEGIN_INIT_SIM_OBJECT_PARAMS(DTB)
628a625
> INIT_PARAM_DFLT(size, "TLB size", 64)
630,633c627
< CREATE_SIM_OBJECT(DTB)
< {
< return new DTB(getInstanceName(), size);
< }
---
> END_INIT_SIM_OBJECT_PARAMS(DTB)
635c629,632
< REGISTER_SIM_OBJECT("AlphaDTB", DTB)
---
>
> CREATE_SIM_OBJECT(DTB)
> {
> return new DTB(getInstanceName(), size);
636a634,636
>
> REGISTER_SIM_OBJECT("AlphaDTB", DTB)
> }