diff options
Diffstat (limited to 'src')
59 files changed, 1370 insertions, 1304 deletions
diff --git a/src/SConscript b/src/SConscript index 429e1bee1..f54e1de0d 100644 --- a/src/SConscript +++ b/src/SConscript @@ -108,6 +108,7 @@ base_sources = Split(''' mem/cache/coherence/coherence_protocol.cc mem/cache/coherence/uni_coherence.cc mem/cache/miss/blocking_buffer.cc + mem/cache/miss/miss_buffer.cc mem/cache/miss/miss_queue.cc mem/cache/miss/mshr.cc mem/cache/miss/mshr_queue.cc diff --git a/src/arch/alpha/miscregfile.cc b/src/arch/alpha/miscregfile.cc index 962d4609f..67f6c98e4 100644 --- a/src/arch/alpha/miscregfile.cc +++ b/src/arch/alpha/miscregfile.cc @@ -89,12 +89,26 @@ namespace AlphaISA MiscReg MiscRegFile::readRegWithEffect(int misc_reg, ThreadContext *tc) { + switch(misc_reg) { + case MISCREG_FPCR: + return fpcr; + case MISCREG_UNIQ: + return uniq; + case MISCREG_LOCKFLAG: + return lock_flag; + case MISCREG_LOCKADDR: + return lock_addr; + case MISCREG_INTR: + return intr_flag; #if FULL_SYSTEM - return readIpr(misc_reg, tc); + default: + return readIpr(misc_reg, tc); #else - panic("No faulting misc regs in SE mode!"); - return 0; + default: + panic("No faulting misc regs in SE mode!"); + return 0; #endif + } } void diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index af69e45c0..c21bf94f5 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -48,589 +48,589 @@ using namespace EV5; namespace AlphaISA { - /////////////////////////////////////////////////////////////////////// - // - // Alpha TLB - // +/////////////////////////////////////////////////////////////////////// +// +// Alpha TLB +// #ifdef DEBUG - bool uncacheBit39 = false; - bool uncacheBit40 = false; +bool uncacheBit39 = false; +bool uncacheBit40 = false; #endif #define MODE2MASK(X) (1 << (X)) - 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])); +} - TLB::~TLB() - { - if (table) - delete [] table; - } +TLB::~TLB() +{ + if (table) + delete [] table; +} - // look up an entry in the TLB - PTE * - TLB::lookup(Addr vpn, uint8_t asn) const - { - // assume not found... - PTE *retval = NULL; - - 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; - } +// look up an entry in the TLB +PTE * +TLB::lookup(Addr vpn, uint8_t asn) const +{ + // assume not found... + PTE *retval = NULL; - ++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; } - } - DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, - retval ? "hit" : "miss", retval ? retval->ppn : 0); - return retval; + ++i; + } } + DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, + retval ? "hit" : "miss", retval ? retval->ppn : 0); + return retval; +} - Fault - TLB::checkCacheability(RequestPtr &req) - { - // 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. - */ +Fault +TLB::checkCacheability(RequestPtr &req) +{ +// 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. + */ #if ALPHA_TLASER - if (req->getPaddr() & PAddrUncachedBit39) { + if (req->getPaddr() & PAddrUncachedBit39) { #else - if (req->getPaddr() & PAddrUncachedBit43) { + 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); + // 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); #if !ALPHA_TLASER - // 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); #endif - } } - return NoFault; } + return NoFault; +} - // 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); - - if (i == lookupTable.end()) - panic("TLB entry not found in lookupTable"); - - int index; - while ((index = i->second) != nlu) { - if (table[index].tag != oldvpn) - panic("TLB entry not found in lookupTable"); +// 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); - ++i; - } + if (i == lookupTable.end()) + panic("TLB entry not found in lookupTable"); - DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); + int index; + while ((index = i->second) != nlu) { + if (table[index].tag != oldvpn) + panic("TLB entry not found in lookupTable"); - lookupTable.erase(i); + ++i; } - DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn); + DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); - table[nlu] = pte; - table[nlu].tag = vaddr.vpn(); - table[nlu].valid = true; - - lookupTable.insert(make_pair(vaddr.vpn(), nlu)); - nextnlu(); + lookupTable.erase(i); } - void - TLB::flushAll() - { - DPRINTF(TLB, "flushAll\n"); - memset(table, 0, sizeof(PTE[size])); - lookupTable.clear(); - nlu = 0; - } + DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn); - 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); + table[nlu] = pte; + table[nlu].tag = vaddr.vpn(); + table[nlu].valid = true; - // 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; + lookupTable.insert(make_pair(vaddr.vpn(), nlu)); + nextnlu(); +} - if (!pte->asma) { - DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); - pte->valid = false; - lookupTable.erase(cur); - } +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); + + // 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); } } +} - void - TLB::flushAddr(Addr addr, uint8_t asn) - { - VAddr vaddr = addr; +void +TLB::flushAddr(Addr addr, uint8_t asn) +{ + VAddr vaddr = addr; - PageTable::iterator i = lookupTable.find(vaddr.vpn()); - if (i == lookupTable.end()) - return; + PageTable::iterator i = lookupTable.find(vaddr.vpn()); + if (i == lookupTable.end()) + return; - while (i->first == vaddr.vpn()) { - int index = i->second; - PTE *pte = &table[index]; - assert(pte->valid); - - if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) { - DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(), - pte->ppn); + while (i->first == vaddr.vpn()) { + int index = i->second; + PTE *pte = &table[index]; + assert(pte->valid); - // invalidate this entry - pte->valid = false; + if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) { + DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(), + pte->ppn); - lookupTable.erase(i); - } + // invalidate this entry + pte->valid = false; - ++i; + lookupTable.erase(i); } + + ++i; } +} - void - TLB::serialize(ostream &os) - { - SERIALIZE_SCALAR(size); - SERIALIZE_SCALAR(nlu); +void +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)); - table[i].serialize(os); - } + for (int i = 0; i < size; i++) { + nameOut(os, csprintf("%s.PTE%d", name(), i)); + table[i].serialize(os); } +} - void - TLB::unserialize(Checkpoint *cp, const string §ion) - { - UNSERIALIZE_SCALAR(size); - UNSERIALIZE_SCALAR(nlu); +void +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)); - 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)); } } +} - /////////////////////////////////////////////////////////////////////// - // - // Alpha ITB - // - ITB::ITB(const std::string &name, int size) - : TLB(name, size) - {} - - - 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"); - - accesses = hits + misses; - } +/////////////////////////////////////////////////////////////////////// +// +// Alpha ITB +// +ITB::ITB(const std::string &name, int size) + : TLB(name, size) +{} - 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; - } +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"); + + accesses = hits + misses; +} - 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()); - } +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()); + } - // 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 #if ALPHA_TLASER - if ((MCSR_SP(tc->readMiscReg(IPR_MCSR)) & 2) && - VAddrSpaceEV5(req->getVaddr()) == 2) { + if ((MCSR_SP(tc->readMiscReg(IPR_MCSR)) & 2) && + VAddrSpaceEV5(req->getVaddr()) == 2) { #else - if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) { + if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) { #endif - // 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()); + } - req->setPaddr(req->getVaddr() & PAddrImplMask); + 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)); + // 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(tc->readMiscReg(IPR_DTB_ASN)); - PTE *pte = lookup(VAddr(req->getVaddr()).vpn(), - asn); - - if (!pte) { - misses++; - return new ItbPageFault(req->getVaddr()); - } - - req->setPaddr((pte->ppn << PageShift) + - (VAddr(req->getVaddr()).offset() - & ~3)); + } 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); + + if (!pte) { + misses++; + return new ItbPageFault(req->getVaddr()); + } - // check permissions for this access - if (!(pte->xre & - (1 << ICM_CM(tc->readMiscReg(IPR_ICM))))) { - // instruction access fault - acv++; - return new ItbAcvFault(req->getVaddr()); - } + req->setPaddr((pte->ppn << PageShift) + + (VAddr(req->getVaddr()).offset() + & ~3)); - 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()); } + + hits++; } + } - // 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(); - return checkCacheability(req); + return checkCacheability(req); - } +} - /////////////////////////////////////////////////////////////////////// - // - // Alpha DTB - // - DTB::DTB(const std::string &name, int size) - : TLB(name, size) - {} - - void - DTB::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") - ; - - hits = read_hits + write_hits; - misses = read_misses + write_misses; - acv = read_acv + write_acv; - accesses = read_accesses + write_accesses; - } +/////////////////////////////////////////////////////////////////////// +// +// Alpha DTB +// + DTB::DTB(const std::string &name, int size) + : TLB(name, size) +{} - Fault - DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const - { - Addr pc = tc->readPC(); +void +DTB::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") + ; + + hits = read_hits + write_hits; + misses = read_misses + write_misses; + acv = read_acv + write_acv; + accesses = read_accesses + write_accesses; +} - mode_type mode = - (mode_type)DTB_CM_CM(tc->readMiscReg(IPR_DTB_CM)); +Fault +DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const +{ + Addr pc = tc->readPC(); + mode_type mode = + (mode_type)DTB_CM_CM(tc->readMiscReg(IPR_DTB_CM)); - /** - * 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); - } - if (pc & 0x1) { - mode = (req->getFlags() & ALTMODE) ? - (mode_type)ALT_MODE_AM( - tc->readMiscReg(IPR_ALT_MODE)) - : mode_kernel; - } + /** + * 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); + } - 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); - } + if (PcPAL(pc)) { + mode = (req->getFlags() & ALTMODE) ? + (mode_type)ALT_MODE_AM( + tc->readMiscReg(IPR_ALT_MODE)) + : mode_kernel; + } - // Check for "superpage" mapping + 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 #if ALPHA_TLASER - if ((MCSR_SP(tc->readMiscReg(IPR_MCSR)) & 2) && - VAddrSpaceEV5(req->getVaddr()) == 2) { + if ((MCSR_SP(tc->readMiscReg(IPR_MCSR)) & 2) && + VAddrSpaceEV5(req->getVaddr()) == 2) { #else - if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) { + if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) { #endif - // 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); + } - req->setPaddr(req->getVaddr() & PAddrImplMask); + 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)); + // 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(tc->readMiscReg(IPR_DTB_ASN)); + + // not a physical address: need to look up pte + PTE *pte = lookup(VAddr(req->getVaddr()).vpn(), + asn); + + 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)); + } + + req->setPaddr((pte->ppn << PageShift) + + VAddr(req->getVaddr()).offset()); + + 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 (write) - write_accesses++; - else - read_accesses++; - - int asn = DTB_ASN_ASN(tc->readMiscReg(IPR_DTB_ASN)); - - // not a physical address: need to look up pte - PTE *pte = lookup(VAddr(req->getVaddr()).vpn(), - asn); - - 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->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); } - - req->setPaddr((pte->ppn << PageShift) + - VAddr(req->getVaddr()).offset()); - - 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 (pte->fonr) { + read_acv++; + uint64_t flags = MM_STAT_FONR_MASK; + return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); } } - - if (write) - write_hits++; - else - read_hits++; } - // 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++; } - 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(); - if (advance) - nextnlu(); + return checkCacheability(req); +} - return *pte; - } +PTE & +TLB::index(bool advance) +{ + PTE *pte = &table[nlu]; + + if (advance) + nextnlu(); - DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", TLB) + return *pte; +} - BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITB) +DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", TLB) - Param<int> size; +BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITB) - END_DECLARE_SIM_OBJECT_PARAMS(ITB) + Param<int> size; - BEGIN_INIT_SIM_OBJECT_PARAMS(ITB) +END_DECLARE_SIM_OBJECT_PARAMS(ITB) - INIT_PARAM_DFLT(size, "TLB size", 48) +BEGIN_INIT_SIM_OBJECT_PARAMS(ITB) - END_INIT_SIM_OBJECT_PARAMS(ITB) + INIT_PARAM_DFLT(size, "TLB size", 48) +END_INIT_SIM_OBJECT_PARAMS(ITB) - CREATE_SIM_OBJECT(ITB) - { - return new ITB(getInstanceName(), size); - } - REGISTER_SIM_OBJECT("AlphaITB", ITB) +CREATE_SIM_OBJECT(ITB) +{ + return new ITB(getInstanceName(), size); +} - BEGIN_DECLARE_SIM_OBJECT_PARAMS(DTB) +REGISTER_SIM_OBJECT("AlphaITB", ITB) - Param<int> size; +BEGIN_DECLARE_SIM_OBJECT_PARAMS(DTB) - END_DECLARE_SIM_OBJECT_PARAMS(DTB) + Param<int> size; - BEGIN_INIT_SIM_OBJECT_PARAMS(DTB) +END_DECLARE_SIM_OBJECT_PARAMS(DTB) - INIT_PARAM_DFLT(size, "TLB size", 64) +BEGIN_INIT_SIM_OBJECT_PARAMS(DTB) - END_INIT_SIM_OBJECT_PARAMS(DTB) + INIT_PARAM_DFLT(size, "TLB size", 64) +END_INIT_SIM_OBJECT_PARAMS(DTB) - CREATE_SIM_OBJECT(DTB) - { - return new DTB(getInstanceName(), size); - } - REGISTER_SIM_OBJECT("AlphaDTB", DTB) +CREATE_SIM_OBJECT(DTB) +{ + return new DTB(getInstanceName(), size); +} + +REGISTER_SIM_OBJECT("AlphaDTB", DTB) } diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index 2086473d6..59eb18c9c 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -1180,15 +1180,16 @@ class IntRegOperand(Operand): if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to read integer register as FP') if (self.size == self.dflt_size): - return '%s = xc->readIntReg(this, %d);\n' % \ + return '%s = xc->readIntRegOperand(this, %d);\n' % \ (self.base_name, self.src_reg_idx) elif (self.size > self.dflt_size): - int_reg_val = 'xc->readIntReg(this, %d)' % (self.src_reg_idx) + int_reg_val = 'xc->readIntRegOperand(this, %d)' % \ + (self.src_reg_idx) if (self.is_signed): int_reg_val = 'sext<%d>(%s)' % (self.dflt_size, int_reg_val) return '%s = %s;\n' % (self.base_name, int_reg_val) else: - return '%s = bits(xc->readIntReg(this, %d), %d, 0);\n' % \ + return '%s = bits(xc->readIntRegOperand(this, %d), %d, 0);\n' % \ (self.base_name, self.src_reg_idx, self.size-1) def makeWrite(self): @@ -1201,7 +1202,7 @@ class IntRegOperand(Operand): wb = ''' { %s final_val = %s; - xc->setIntReg(this, %d, final_val);\n + xc->setIntRegOperand(this, %d, final_val);\n if (traceData) { traceData->setData(final_val); } }''' % (self.dflt_ctype, final_val, self.dest_reg_idx) return wb @@ -1227,13 +1228,13 @@ class FloatRegOperand(Operand): bit_select = 0 width = 0; if (self.ctype == 'float'): - func = 'readFloatReg' + func = 'readFloatRegOperand' width = 32; elif (self.ctype == 'double'): - func = 'readFloatReg' + func = 'readFloatRegOperand' width = 64; else: - func = 'readFloatRegBits' + func = 'readFloatRegOperandBits' if (self.ctype == 'uint32_t'): width = 32; elif (self.ctype == 'uint64_t'): @@ -1259,18 +1260,18 @@ class FloatRegOperand(Operand): width = 0 if (self.ctype == 'float'): width = 32 - func = 'setFloatReg' + func = 'setFloatRegOperand' elif (self.ctype == 'double'): width = 64 - func = 'setFloatReg' + func = 'setFloatRegOperand' elif (self.ctype == 'uint32_t'): - func = 'setFloatRegBits' + func = 'setFloatRegOperandBits' width = 32 elif (self.ctype == 'uint64_t'): - func = 'setFloatRegBits' + func = 'setFloatRegOperandBits' width = 64 else: - func = 'setFloatRegBits' + func = 'setFloatRegOperandBits' final_ctype = 'uint%d_t' % self.dflt_size if (self.size != self.dflt_size and self.is_signed): final_val = 'sext<%d>(%s)' % (self.size, self.base_name) diff --git a/src/arch/mips/isa/formats/fp.isa b/src/arch/mips/isa/formats/fp.isa index cdb892b3f..153f3f949 100644 --- a/src/arch/mips/isa/formats/fp.isa +++ b/src/arch/mips/isa/formats/fp.isa @@ -99,7 +99,7 @@ output exec {{ int size = sizeof(src_op) * 8; for (int i = 0; i < inst->numSrcRegs(); i++) { - uint64_t src_bits = xc->readFloatRegBits(inst, 0, size); + uint64_t src_bits = xc->readFloatRegOperandBits(inst, 0, size); if (isNan(&src_bits, size) ) { if (isSnan(&src_bits, size)) { @@ -113,7 +113,7 @@ output exec {{ mips_nan = src_bits; } - xc->setFloatRegBits(inst, 0, mips_nan, size); + xc->setFloatRegOperandBits(inst, 0, mips_nan, size); if (traceData) { traceData->setData(mips_nan); } return true; } @@ -139,7 +139,7 @@ output exec {{ } //Set value to QNAN - cpu->setFloatRegBits(inst, 0, mips_nan, size); + cpu->setFloatRegOperandBits(inst, 0, mips_nan, size); //Read FCSR from FloatRegFile uint32_t fcsr_bits = cpu->tcBase()->readFloatRegBits(FCSR); diff --git a/src/arch/mips/mmaped_ipr.hh b/src/arch/mips/mmaped_ipr.hh index 041c76fdc..fa82a645c 100644 --- a/src/arch/mips/mmaped_ipr.hh +++ b/src/arch/mips/mmaped_ipr.hh @@ -37,8 +37,10 @@ * ISA-specific helper functions for memory mapped IPR accesses. */ +#include "base/misc.hh" #include "mem/packet.hh" +class ThreadContext; namespace MipsISA { @@ -48,7 +50,6 @@ handleIprRead(ThreadContext *xc, Packet *pkt) panic("No implementation for handleIprRead in MIPS\n"); } - inline Tick handleIprWrite(ThreadContext *xc, Packet *pkt) { diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 5bc11aae6..53559c072 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -341,7 +341,6 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) case MISCREG_SOFTINT: case MISCREG_TICK_CMPR: case MISCREG_STICK_CMPR: - case MISCREG_HPSTATE: case MISCREG_HINTP: case MISCREG_HTSTATE: case MISCREG_HTBA: @@ -357,9 +356,16 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) case MISCREG_QUEUE_NRES_ERROR_HEAD: case MISCREG_QUEUE_NRES_ERROR_TAIL: #if FULL_SYSTEM + case MISCREG_HPSTATE: return readFSRegWithEffect(miscReg, tc); #else - panic("Accessing Fullsystem register is SE mode\n"); + case MISCREG_HPSTATE: + //HPSTATE is special because because sometimes in privilege checks for instructions + //it will read HPSTATE to make sure the priv. level is ok + //So, we'll just have to tell it it isn't, instead of panicing. + return 0; + + panic("Accessing Fullsystem register %s in SE mode\n",getMiscRegName(miscReg)); #endif } @@ -633,7 +639,6 @@ void MiscRegFile::setRegWithEffect(int miscReg, case MISCREG_SOFTINT: case MISCREG_TICK_CMPR: case MISCREG_STICK_CMPR: - case MISCREG_HPSTATE: case MISCREG_HINTP: case MISCREG_HTSTATE: case MISCREG_HTBA: @@ -649,10 +654,15 @@ void MiscRegFile::setRegWithEffect(int miscReg, case MISCREG_QUEUE_NRES_ERROR_HEAD: case MISCREG_QUEUE_NRES_ERROR_TAIL: #if FULL_SYSTEM + case MISCREG_HPSTATE: setFSRegWithEffect(miscReg, val, tc); return; #else - panic("Accessing Fullsystem register is SE mode\n"); + case MISCREG_HPSTATE: + //HPSTATE is special because normal trap processing saves HPSTATE when + //it goes into a trap, and restores it when it returns. + return; + panic("Accessing Fullsystem register %s to %#x in SE mode\n", getMiscRegName(miscReg), val); #endif } setReg(miscReg, val); diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 37d384473..675287d18 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -45,7 +45,7 @@ namespace SparcISA { TLB::TLB(const std::string &name, int s) - : SimObject(name), size(s) + : SimObject(name), size(s), usedEntries(0), cacheValid(false) { // To make this work you'll have to change the hypervisor and OS if (size > 64) @@ -79,6 +79,8 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real, TlbEntry *new_entry = NULL; int x; + cacheValid = false; + DPRINTF(TLB, "TLB: Inserting TLB Entry; va=%#x pa=%#x pid=%d cid=%d r=%d\n", va, PTE.paddr(), partition_id, context_id, (int)real); @@ -194,6 +196,8 @@ TLB::demapPage(Addr va, int partition_id, bool real, int context_id) TlbRange tr; MapIter i; + cacheValid = false; + // Assemble full address structure tr.va = va; tr.size = va + MachineBytes; @@ -217,6 +221,7 @@ void TLB::demapContext(int partition_id, int context_id) { int x; + cacheValid = false; for (x = 0; x < size; x++) { if (tlb[x].range.contextId == context_id && tlb[x].range.partitionId == partition_id) { @@ -234,6 +239,7 @@ void TLB::demapAll(int partition_id) { int x; + cacheValid = false; for (x = 0; x < size; x++) { if (!tlb[x].pte.locked() && tlb[x].range.partitionId == partition_id) { tlb[x].valid = false; @@ -250,6 +256,8 @@ void TLB::invalidateAll() { int x; + cacheValid = false; + for (x = 0; x < size; x++) { tlb[x].valid = false; } @@ -337,7 +345,7 @@ DTB::writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct, tc->setMiscRegWithEffect(MISCREG_MMU_DTLB_SFAR, a); } - void +void DTB::writeTagAccess(ThreadContext *tc, Addr va, int context) { TLB::writeTagAccess(tc, MISCREG_MMU_DTLB_TAG_ACCESS, va, context); @@ -350,6 +358,29 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) { uint64_t tlbdata = tc->readMiscReg(MISCREG_TLB_DATA); + Addr vaddr = req->getVaddr(); + TlbEntry *e; + + assert(req->getAsi() == ASI_IMPLICIT); + + DPRINTF(TLB, "TLB: ITB Request to translate va=%#x size=%d\n", + vaddr, req->getSize()); + + // Be fast if we can! + if (cacheValid && cacheState == tlbdata) { + 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; + } + } else { + req->setPaddr(vaddr & PAddrImplMask); + return NoFault; + } + } + bool hpriv = bits(tlbdata,0,0); bool red = bits(tlbdata,1,1); bool priv = bits(tlbdata,2,2); @@ -359,21 +390,14 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) int part_id = bits(tlbdata,15,8); int tl = bits(tlbdata,18,16); int pri_context = bits(tlbdata,47,32); - - Addr vaddr = req->getVaddr(); int context; ContextType ct; int asi; bool real = false; - TlbEntry *e; - DPRINTF(TLB, "TLB: ITB Request to translate va=%#x size=%d\n", - vaddr, req->getSize()); DPRINTF(TLB, "TLB: priv:%d hpriv:%d red:%d lsuim:%d part_id: %#X\n", priv, hpriv, red, lsu_im, part_id); - assert(req->getAsi() == ASI_IMPLICIT); - if (tl > 0) { asi = ASI_N; ct = Nucleus; @@ -385,12 +409,15 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) } if ( hpriv || red ) { - req->setPaddr(req->getVaddr() & PAddrImplMask); + cacheValid = true; + cacheState = tlbdata; + cacheEntry = NULL; + req->setPaddr(vaddr & PAddrImplMask); return NoFault; } - // If the asi is unaligned trap - if (vaddr & req->getSize()-1) { + // If the access is unaligned trap + if (vaddr & 0x3) { writeSfsr(tc, false, ct, false, OtherFault, asi); return new MemAddressNotAligned; } @@ -404,7 +431,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) } if (!lsu_im) { - e = lookup(req->getVaddr(), part_id, true); + e = lookup(vaddr, part_id, true); real = true; context = 0; } else { @@ -426,9 +453,14 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) return new InstructionAccessException; } + // cache translation date for next translation + cacheValid = true; + cacheState = tlbdata; + cacheEntry = e; + req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) | - req->getVaddr() & e->pte.size()-1 ); - DPRINTF(TLB, "TLB: %#X -> %#X\n", req->getVaddr(), req->getPaddr()); + vaddr & e->pte.size()-1 ); + DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); return NoFault; } @@ -439,8 +471,40 @@ 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); - + Addr vaddr = req->getVaddr(); + Addr size = req->getSize(); + ASI asi; + asi = (ASI)req->getAsi(); + bool implicit = false; bool hpriv = bits(tlbdata,0,0); + + 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) { + req->setPaddr(cacheEntry[0]->pte.paddr() & ~(cacheEntry[0]->pte.size()-1) | + vaddr & cacheEntry[0]->pte.size()-1 ); + return NoFault; + } + if (cacheEntry[1] && cacheAsi[1] == asi && cacheEntry[1]->range.va < vaddr + size && + cacheEntry[1]->range.va + cacheEntry[1]->range.size >= vaddr) { + req->setPaddr(cacheEntry[1]->pte.paddr() & ~(cacheEntry[1]->pte.size()-1) | + vaddr & cacheEntry[1]->pte.size()-1 ); + return NoFault; + } + } + bool red = bits(tlbdata,1,1); bool priv = bits(tlbdata,2,2); bool addr_mask = bits(tlbdata,3,3); @@ -451,23 +515,14 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) int pri_context = bits(tlbdata,47,32); int sec_context = bits(tlbdata,47,32); - bool implicit = false; bool real = false; - Addr vaddr = req->getVaddr(); - Addr size = req->getSize(); ContextType ct = Primary; int context = 0; - ASI asi; TlbEntry *e; - asi = (ASI)req->getAsi(); - DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n", - vaddr, size, asi); DPRINTF(TLB, "TLB: priv:%d hpriv:%d red:%d lsudm:%d part_id: %#X\n", priv, hpriv, red, lsu_dm, part_id); - if (asi == ASI_IMPLICIT) - implicit = true; if (implicit) { if (tl > 0) { @@ -562,11 +617,11 @@ continueDtbFlow: }; if (hpriv && (implicit || (!AsiIsAsIfUser(asi) && !AsiIsReal(asi)))) { - req->setPaddr(req->getVaddr() & PAddrImplMask); + req->setPaddr(vaddr & PAddrImplMask); return NoFault; } - e = lookup(req->getVaddr(), part_id, real, context); + e = lookup(vaddr, part_id, real, context); if (e == NULL || !e->valid) { tc->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS, @@ -599,9 +654,21 @@ continueDtbFlow: return new DataAccessException; } + // cache translation date for next translation + cacheValid = true; + cacheState = tlbdata; + if (cacheEntry[0] != e && cacheEntry[1] != e) { + cacheEntry[1] = cacheEntry[0]; + cacheEntry[0] = e; + cacheAsi[1] = cacheAsi[0]; + cacheAsi[0] = asi; + if (implicit) + cacheAsi[0] = (ASI)0; + } + req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) | - req->getVaddr() & e->pte.size()-1); - DPRINTF(TLB, "TLB: %#X -> %#X\n", req->getVaddr(), req->getPaddr()); + vaddr & e->pte.size()-1); + DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); return NoFault; /** Normal flow ends here. */ @@ -773,8 +840,6 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) data = mbits(tsbtemp,63,13); data |= temp >> (9 + bits(cnftemp,2,0) * 3) & mbits((uint64_t)-1ll,12+bits(tsbtemp,3,0), 4); - warn("base addr: %#X tag access: %#X page size: %#X tsb size: %#X\n", - bits(tsbtemp,63,13), temp, bits(cnftemp,2,0), bits(tsbtemp,3,0)); pkt->set(data); break; case ASI_DMMU_TSB_PS1_PTR_REG: diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh index b35f472cf..a6e6a8bd3 100644 --- a/src/arch/sparc/tlb.hh +++ b/src/arch/sparc/tlb.hh @@ -31,6 +31,7 @@ #ifndef __ARCH_SPARC_TLB_HH__ #define __ARCH_SPARC_TLB_HH__ +#include "arch/sparc/asi.hh" #include "arch/sparc/tlb_map.hh" #include "base/misc.hh" #include "mem/request.hh" @@ -54,6 +55,9 @@ class TLB : public SimObject int size; int usedEntries; + uint64_t cacheState; + bool cacheValid; + enum FaultTypes { OtherFault = 0, PrivViolation = 0x1, @@ -131,6 +135,7 @@ class ITB : public TLB public: ITB(const std::string &name, int size) : TLB(name, size) { + cacheEntry = NULL; } Fault translate(RequestPtr &req, ThreadContext *tc); @@ -138,6 +143,7 @@ class ITB : public TLB void writeSfsr(ThreadContext *tc, bool write, ContextType ct, bool se, FaultTypes ft, int asi); void writeTagAccess(ThreadContext *tc, Addr va, int context); + TlbEntry *cacheEntry; friend class DTB; }; @@ -146,6 +152,8 @@ class DTB : public TLB public: DTB(const std::string &name, int size) : TLB(name, size) { + cacheEntry[0] = NULL; + cacheEntry[1] = NULL; } Fault translate(RequestPtr &req, ThreadContext *tc, bool write); @@ -157,7 +165,8 @@ class DTB : public TLB bool se, FaultTypes ft, int asi); void writeTagAccess(ThreadContext *tc, Addr va, int context); - + TlbEntry *cacheEntry[2]; + ASI cacheAsi[2]; }; } diff --git a/src/base/compression/base.hh b/src/base/compression/base.hh new file mode 100644 index 000000000..8d1f8d6b5 --- /dev/null +++ b/src/base/compression/base.hh @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * 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: Erik Hallnor + * Nathan Binkert + */ + +#ifndef __BASE_COMPRESSION_BASE_HH__ +#define __BASE_COMPRESSION_BASE_HH__ + +/** + * @file + * This file defines a base (abstract virtual) compression algorithm object. + */ + +#include <inttypes.h> + +/** + * Abstract virtual compression algorithm object. + */ +class CompressionAlgorithm +{ + public: + virtual ~CompressionAlgorithm() {} + + /** + * Uncompress the data, causes a fatal since no data should be compressed. + * @param dest The output buffer. + * @param src The compressed data. + * @param size The number of bytes in src. + * + * @retval The size of the uncompressed data. + */ + virtual int uncompress(uint8_t * dest, uint8_t *src, int size) = 0; + + /** + * Compress the data, just returns the source data. + * @param dest The output buffer. + * @param src The data to be compressed. + * @param size The number of bytes in src. + * + * @retval The size of the compressed data. + */ + virtual int compress(uint8_t *dest, uint8_t *src, int size) = 0; +}; + +#endif //__BASE_COMPRESSION_BASE_HH__ diff --git a/src/base/compression/lzss_compression.hh b/src/base/compression/lzss_compression.hh index 35e4dcb3f..a23d07ffd 100644 --- a/src/base/compression/lzss_compression.hh +++ b/src/base/compression/lzss_compression.hh @@ -35,12 +35,12 @@ * LZSSCompression declarations. */ -#include "sim/host.hh" // for uint8_t +#include "base/compression/base.hh" /** * Simple LZSS compression scheme. */ -class LZSSCompression +class LZSSCompression : public CompressionAlgorithm { /** * Finds the longest substring for the given offset. diff --git a/src/base/compression/null_compression.hh b/src/base/compression/null_compression.hh index 5a582d828..ff110807a 100644 --- a/src/base/compression/null_compression.hh +++ b/src/base/compression/null_compression.hh @@ -38,41 +38,23 @@ */ #include "base/misc.hh" // for fatal() -#include "sim/host.hh" +#include "base/compression/base.hh" /** * A dummy compression class to use when no data compression is desired. */ -class NullCompression +class NullCompression : public CompressionAlgorithm { public: - /** - * Uncompress the data, causes a fatal since no data should be compressed. - * @param dest The output buffer. - * @param src The compressed data. - * @param size The number of bytes in src. - * - * @retval The size of the uncompressed data. - */ - static int uncompress(uint8_t * dest, uint8_t *src, int size) + int uncompress(uint8_t * dest, uint8_t *src, int size) { fatal("Can't uncompress data"); } - /** - * Compress the data, just returns the source data. - * @param dest The output buffer. - * @param src The data to be compressed. - * @param size The number of bytes in src. - * - * @retval The size of the compressed data. - */ - - static int compress(uint8_t *dest, uint8_t *src, int size) + int compress(uint8_t *dest, uint8_t *src, int size) { - memcpy(dest,src,size); - return size; + fatal("Can't compress data"); } }; diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index 4a4555566..9037c96df 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -406,14 +406,15 @@ class BaseDynInst : public FastAlloc, public RefCounted double readDoubleResult() { return instResult.dbl; } /** Records an integer register being set to a value. */ - void setIntReg(const StaticInst *si, int idx, uint64_t val) + void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) { if (recordResult) instResult.integer = val; } /** Records an fp register being set to a value. */ - void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, + int width) { if (recordResult) { if (width == 32) @@ -426,21 +427,22 @@ class BaseDynInst : public FastAlloc, public RefCounted } /** Records an fp register being set to a value. */ - void setFloatReg(const StaticInst *si, int idx, FloatReg val) + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) { if (recordResult) instResult.dbl = (double)val; } /** Records an fp register being set to an integer value. */ - void setFloatRegBits(const StaticInst *si, int idx, uint64_t val, int width) + void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val, + int width) { if (recordResult) instResult.integer = val; } /** Records an fp register being set to an integer value. */ - void setFloatRegBits(const StaticInst *si, int idx, uint64_t val) + void setFloatRegOperandBits(const StaticInst *si, int idx, uint64_t val) { if (recordResult) instResult.integer = val; diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 9be54529f..3e08193ee 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -216,42 +216,44 @@ class CheckerCPU : public BaseCPU // storage (which is pretty hard to imagine they would have reason // to do). - uint64_t readIntReg(const StaticInst *si, int idx) + uint64_t readIntRegOperand(const StaticInst *si, int idx) { return thread->readIntReg(si->srcRegIdx(idx)); } - FloatReg readFloatReg(const StaticInst *si, int idx, int width) + FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return thread->readFloatReg(reg_idx, width); } - FloatReg readFloatReg(const StaticInst *si, int idx) + FloatReg readFloatRegOperand(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return thread->readFloatReg(reg_idx); } - FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) + FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx, + int width) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return thread->readFloatRegBits(reg_idx, width); } - FloatRegBits readFloatRegBits(const StaticInst *si, int idx) + FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return thread->readFloatRegBits(reg_idx); } - void setIntReg(const StaticInst *si, int idx, uint64_t val) + void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) { thread->setIntReg(si->destRegIdx(idx), val); result.integer = val; } - void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, + int width) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; thread->setFloatReg(reg_idx, val, width); @@ -265,22 +267,23 @@ class CheckerCPU : public BaseCPU }; } - void setFloatReg(const StaticInst *si, int idx, FloatReg val) + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; thread->setFloatReg(reg_idx, val); result.dbl = (double)val; } - void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val, - int width) + void setFloatRegOperandBits(const StaticInst *si, int idx, + FloatRegBits val, int width) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; thread->setFloatRegBits(reg_idx, val, width); result.integer = val; } - void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) + void setFloatRegOperandBits(const StaticInst *si, int idx, + FloatRegBits val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; thread->setFloatRegBits(reg_idx, val); diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh index 13f70fa79..edccd747f 100644 --- a/src/cpu/exec_context.hh +++ b/src/cpu/exec_context.hh @@ -48,39 +48,42 @@ class ExecContext { // to do). /** Reads an integer register. */ - uint64_t readIntReg(const StaticInst *si, int idx); + uint64_t readIntRegOperand(const StaticInst *si, int idx); /** Reads a floating point register of a specific width. */ - FloatReg readFloatReg(const StaticInst *si, int idx, int width); + FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width); /** Reads a floating point register of single register width. */ - FloatReg readFloatReg(const StaticInst *si, int idx); + FloatReg readFloatRegOperand(const StaticInst *si, int idx); /** Reads a floating point register of a specific width in its * binary format, instead of by value. */ - FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width); + FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx, + int width); /** Reads a floating point register in its binary format, instead * of by value. */ - FloatRegBits readFloatRegBits(const StaticInst *si, int idx); + FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx); /** Sets an integer register to a value. */ - void setIntReg(const StaticInst *si, int idx, uint64_t val); + void setIntRegOperand(const StaticInst *si, int idx, uint64_t val); /** Sets a floating point register of a specific width to a value. */ - void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width); + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, + int width); /** Sets a floating point register of single width to a value. */ - void setFloatReg(const StaticInst *si, int idx, FloatReg val); + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val); /** Sets the bits of a floating point register of a specific width * to a binary value. */ - void setFloatRegBits(const StaticInst *si, int idx, - FloatRegBits val, int width); + void setFloatRegOperandBits(const StaticInst *si, int idx, + FloatRegBits val, int width); /** Sets the bits of a floating point register of single width * to a binary value. */ - void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val); + void setFloatRegOperandBits(const StaticInst *si, int idx, + FloatRegBits val); /** Reads the PC. */ uint64_t readPC(); diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 316716540..3fe40b4c1 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -57,7 +57,9 @@ using namespace std; using namespace TheISA; +#if THE_ISA == SPARC_ISA && FULL_SYSTEM static int diffcount = 0; +#endif namespace Trace { SharedData *shared_data = NULL; diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh index 7bf34d827..264309fd7 100644 --- a/src/cpu/memtest/memtest.hh +++ b/src/cpu/memtest/memtest.hh @@ -116,7 +116,7 @@ class MemTest : public MemObject virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); } + { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); } }; CpuPort cachePort; diff --git a/src/cpu/o3/alpha/dyn_inst.hh b/src/cpu/o3/alpha/dyn_inst.hh index 31df8ff78..49cc5a201 100644 --- a/src/cpu/o3/alpha/dyn_inst.hh +++ b/src/cpu/o3/alpha/dyn_inst.hh @@ -163,27 +163,28 @@ class AlphaDynInst : public BaseDynInst<Impl> // storage (which is pretty hard to imagine they would have reason // to do). - uint64_t readIntReg(const StaticInst *si, int idx) + uint64_t readIntRegOperand(const StaticInst *si, int idx) { return this->cpu->readIntReg(_srcRegIdx[idx]); } - FloatReg readFloatReg(const StaticInst *si, int idx, int width) + FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width) { return this->cpu->readFloatReg(_srcRegIdx[idx], width); } - FloatReg readFloatReg(const StaticInst *si, int idx) + FloatReg readFloatRegOperand(const StaticInst *si, int idx) { return this->cpu->readFloatReg(_srcRegIdx[idx]); } - FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) + FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx, + int width) { return this->cpu->readFloatRegBits(_srcRegIdx[idx], width); } - FloatRegBits readFloatRegBits(const StaticInst *si, int idx) + FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) { return this->cpu->readFloatRegBits(_srcRegIdx[idx]); } @@ -191,35 +192,37 @@ class AlphaDynInst : public BaseDynInst<Impl> /** @todo: Make results into arrays so they can handle multiple dest * registers. */ - void setIntReg(const StaticInst *si, int idx, uint64_t val) + void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) { this->cpu->setIntReg(_destRegIdx[idx], val); - BaseDynInst<Impl>::setIntReg(si, idx, val); + BaseDynInst<Impl>::setIntRegOperand(si, idx, val); } - void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, + int width) { this->cpu->setFloatReg(_destRegIdx[idx], val, width); - BaseDynInst<Impl>::setFloatReg(si, idx, val, width); + BaseDynInst<Impl>::setFloatRegOperand(si, idx, val, width); } - void setFloatReg(const StaticInst *si, int idx, FloatReg val) + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) { this->cpu->setFloatReg(_destRegIdx[idx], val); - BaseDynInst<Impl>::setFloatReg(si, idx, val); + BaseDynInst<Impl>::setFloatRegOperand(si, idx, val); } - void setFloatRegBits(const StaticInst *si, int idx, - FloatRegBits val, int width) + void setFloatRegOperandBits(const StaticInst *si, int idx, + FloatRegBits val, int width) { this->cpu->setFloatRegBits(_destRegIdx[idx], val, width); - BaseDynInst<Impl>::setFloatRegBits(si, idx, val); + BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val); } - void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) + void setFloatRegOperandBits(const StaticInst *si, int idx, + FloatRegBits val) { this->cpu->setFloatRegBits(_destRegIdx[idx], val); - BaseDynInst<Impl>::setFloatRegBits(si, idx, val); + BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val); } /** Returns the physical register index of the i'th destination diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index e72679710..f400d757b 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -748,6 +748,7 @@ DefaultCommit<Impl>::commit() } } else { bdelay_done_seq_num = squashed_inst; + squash_bdelay_slot = true; } #endif @@ -1196,16 +1197,16 @@ DefaultCommit<Impl>::getInsts() rename_idx < fromRename->size; rename_idx++) { DynInstPtr inst = fromRename->insts[rename_idx]; - int tid = inst->threadNumber; if (!inst->isSquashed()) { DPRINTF(Commit, "Inserting PC %#x [sn:%i] [tid:%i] into ", - "skidBuffer.\n", inst->readPC(), inst->seqNum, tid); + "skidBuffer.\n", inst->readPC(), inst->seqNum, + inst->threadNumber); skidBuffer.push(inst); } else { DPRINTF(Commit, "Instruction PC %#x [sn:%i] [tid:%i] was " "squashed, skipping.\n", - inst->readPC(), inst->seqNum, tid); + inst->readPC(), inst->seqNum, inst->threadNumber); } } } diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index 04016347a..e880e14e4 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -98,7 +98,7 @@ class DefaultFetch /** Returns the address ranges of this device. */ virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); } + { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); } /** Timing version of receive. Handles setting fetch to the * proper status to start fetching. */ diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 63d22b293..622259495 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -151,36 +151,6 @@ DefaultFetch<Impl>::DefaultFetch(Params *params) " RoundRobin,LSQcount,IQcount}\n"); } - // Size of cache block. - cacheBlkSize = 64; - - // Create mask to get rid of offset bits. - cacheBlkMask = (cacheBlkSize - 1); - - for (int tid=0; tid < numThreads; tid++) { - - fetchStatus[tid] = Running; - - priorityList.push_back(tid); - - memReq[tid] = NULL; - - // Create space to store a cache line. - cacheData[tid] = new uint8_t[cacheBlkSize]; - cacheDataPC[tid] = 0; - cacheDataValid[tid] = false; - - delaySlotInfo[tid].branchSeqNum = -1; - delaySlotInfo[tid].numInsts = 0; - delaySlotInfo[tid].targetAddr = 0; - delaySlotInfo[tid].targetReady = false; - - stalls[tid].decode = false; - stalls[tid].rename = false; - stalls[tid].iew = false; - stalls[tid].commit = false; - } - // Get the size of an instruction. instSize = sizeof(TheISA::MachInst); } @@ -353,6 +323,36 @@ DefaultFetch<Impl>::initStage() nextNPC[tid] = cpu->readNextNPC(tid); #endif } + + // Size of cache block. + cacheBlkSize = icachePort->peerBlockSize(); + + // Create mask to get rid of offset bits. + cacheBlkMask = (cacheBlkSize - 1); + + for (int tid=0; tid < numThreads; tid++) { + + fetchStatus[tid] = Running; + + priorityList.push_back(tid); + + memReq[tid] = NULL; + + // Create space to store a cache line. + cacheData[tid] = new uint8_t[cacheBlkSize]; + cacheDataPC[tid] = 0; + cacheDataValid[tid] = false; + + delaySlotInfo[tid].branchSeqNum = -1; + delaySlotInfo[tid].numInsts = 0; + delaySlotInfo[tid].targetAddr = 0; + delaySlotInfo[tid].targetReady = false; + + stalls[tid].decode = false; + stalls[tid].rename = false; + stalls[tid].iew = false; + stalls[tid].commit = false; + } } template<class Impl> @@ -1139,6 +1139,8 @@ DefaultFetch<Impl>::fetch(bool &status_change) ext_inst = TheISA::makeExtMI(inst, fetch_PC); #elif THE_ISA == SPARC_ISA ext_inst = TheISA::makeExtMI(inst, cpu->thread[tid]->getTC()); +#elif THE_ISA == MIPS_ISA + ext_inst = TheISA::makeExtMI(inst, cpu->thread[tid]->getTC()); #endif // Create a new DynInst from the instruction fetched. diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index ba5260fe2..76047b295 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -514,6 +514,7 @@ DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid) toCommit->squash[tid] = true; toCommit->squashedSeqNum[tid] = inst->seqNum; toCommit->nextPC[tid] = inst->readNextPC(); + toCommit->branchMispredict[tid] = false; toCommit->includeSquashInst[tid] = false; @@ -530,6 +531,7 @@ DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid) toCommit->squash[tid] = true; toCommit->squashedSeqNum[tid] = inst->seqNum; toCommit->nextPC[tid] = inst->readPC(); + toCommit->branchMispredict[tid] = false; // Must include the broadcasted SN in the squash. toCommit->includeSquashInst[tid] = true; @@ -1291,7 +1293,8 @@ DefaultIEW<Impl>::executeInsts() } else if (fault != NoFault) { // If the instruction faulted, then we need to send it along to commit // without the instruction completing. - DPRINTF(IEW, "Store has fault! [sn:%lli]\n", inst->seqNum); + DPRINTF(IEW, "Store has fault %s! [sn:%lli]\n", + fault->name(), inst->seqNum); // Send this instruction to commit, also make sure iew stage // realizes there is activity. @@ -1328,7 +1331,8 @@ DefaultIEW<Impl>::executeInsts() // instruction first, so the branch resolution order will be correct. unsigned tid = inst->threadNumber; - if (!fetchRedirect[tid]) { + if (!fetchRedirect[tid] || + toCommit->squashedSeqNum[tid] > inst->seqNum) { if (inst->mispredicted()) { fetchRedirect[tid] = true; @@ -1350,8 +1354,6 @@ DefaultIEW<Impl>::executeInsts() predictedNotTakenIncorrect++; } } else if (ldstQueue.violation(tid)) { - fetchRedirect[tid] = true; - // If there was an ordering violation, then get the // DynInst that caused the violation. Note that this // clears the violation signal. @@ -1362,6 +1364,14 @@ DefaultIEW<Impl>::executeInsts() "%#x, inst PC: %#x. Addr is: %#x.\n", violator->readPC(), inst->readPC(), inst->physEffAddr); + // Ensure the violating instruction is older than + // current squash + if (fetchRedirect[tid] && + violator->seqNum >= toCommit->squashedSeqNum[tid]) + continue; + + fetchRedirect[tid] = true; + // Tell the instruction queue that a violation has occured. instQueue.violation(inst, violator); diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh index 7559a36d5..e68085cfd 100644 --- a/src/cpu/o3/lsq.hh +++ b/src/cpu/o3/lsq.hh @@ -313,7 +313,7 @@ class LSQ { /** Returns the address ranges of this device. */ virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); } + { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); } /** Timing version of receive. Handles writing back and * completing the load or store that has returned from diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index 4facea9f9..3b84d3411 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -418,7 +418,8 @@ LSQUnit<Impl>::executeLoad(DynInstPtr &inst) // realizes there is activity. // Mark it as executed unless it is an uncached load that // needs to hit the head of commit. - if (!(inst->req->isUncacheable()) || inst->isAtCommit()) { + if (!(inst->req && inst->req->isUncacheable()) || + inst->isAtCommit()) { inst->setExecuted(); } iewStage->instToCommit(inst); diff --git a/src/cpu/o3/mips/dyn_inst.hh b/src/cpu/o3/mips/dyn_inst.hh index 9e95b2bfb..833371e00 100755 --- a/src/cpu/o3/mips/dyn_inst.hh +++ b/src/cpu/o3/mips/dyn_inst.hh @@ -156,27 +156,28 @@ class MipsDynInst : public BaseDynInst<Impl> // storage (which is pretty hard to imagine they would have reason // to do). - uint64_t readIntReg(const StaticInst *si, int idx) + uint64_t readIntRegOperand(const StaticInst *si, int idx) { return this->cpu->readIntReg(_srcRegIdx[idx]); } - FloatReg readFloatReg(const StaticInst *si, int idx, int width) + FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width) { return this->cpu->readFloatReg(_srcRegIdx[idx], width); } - FloatReg readFloatReg(const StaticInst *si, int idx) + FloatReg readFloatRegOperand(const StaticInst *si, int idx) { return this->cpu->readFloatReg(_srcRegIdx[idx]); } - FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) + FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx, + int width) { return this->cpu->readFloatRegBits(_srcRegIdx[idx], width); } - FloatRegBits readFloatRegBits(const StaticInst *si, int idx) + FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) { return this->cpu->readFloatRegBits(_srcRegIdx[idx]); } @@ -184,35 +185,37 @@ class MipsDynInst : public BaseDynInst<Impl> /** @todo: Make results into arrays so they can handle multiple dest * registers. */ - void setIntReg(const StaticInst *si, int idx, uint64_t val) + void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) { this->cpu->setIntReg(_destRegIdx[idx], val); - BaseDynInst<Impl>::setIntReg(si, idx, val); + BaseDynInst<Impl>::setIntRegOperand(si, idx, val); } - void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, + int width) { this->cpu->setFloatReg(_destRegIdx[idx], val, width); - BaseDynInst<Impl>::setFloatReg(si, idx, val, width); + BaseDynInst<Impl>::setFloatRegOperand(si, idx, val, width); } - void setFloatReg(const StaticInst *si, int idx, FloatReg val) + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) { this->cpu->setFloatReg(_destRegIdx[idx], val); - BaseDynInst<Impl>::setFloatReg(si, idx, val); + BaseDynInst<Impl>::setFloatRegOperand(si, idx, val); } - void setFloatRegBits(const StaticInst *si, int idx, - FloatRegBits val, int width) + void setFloatRegOperandBits(const StaticInst *si, int idx, + FloatRegBits val, int width) { this->cpu->setFloatRegBits(_destRegIdx[idx], val, width); - BaseDynInst<Impl>::setFloatRegBits(si, idx, val); + BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val); } - void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) + void setFloatRegOperandBits(const StaticInst *si, int idx, + FloatRegBits val) { this->cpu->setFloatRegBits(_destRegIdx[idx], val); - BaseDynInst<Impl>::setFloatRegBits(si, idx, val); + BaseDynInst<Impl>::setFloatRegOperandBits(si, idx, val); } /** Returns the physical register index of the i'th destination diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh index c1373944d..0da446c9c 100644 --- a/src/cpu/ozone/cpu.hh +++ b/src/cpu/ozone/cpu.hh @@ -448,30 +448,6 @@ class OzoneCPU : public BaseCPU } #endif - /** Old CPU read from memory function. No longer used. */ - template <class T> - Fault read(Request *req, T &data) - { -#if 0 -#if FULL_SYSTEM && defined(TARGET_ALPHA) - if (req->isLocked()) { - req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr); - req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true); - } -#endif - if (req->isLocked()) { - lockAddrList.insert(req->paddr); - lockFlag = true; - } -#endif - Fault error; - - error = this->mem->read(req, data); - data = gtoh(data); - return error; - } - - /** CPU read function, forwards read to LSQ. */ template <class T> Fault read(Request *req, T &data, int load_idx) @@ -479,81 +455,6 @@ class OzoneCPU : public BaseCPU return backEnd->read(req, data, load_idx); } - /** Old CPU write to memory function. No longer used. */ - template <class T> - Fault write(Request *req, T &data) - { -#if 0 -#if FULL_SYSTEM && defined(TARGET_ALPHA) - ExecContext *xc; - - // If this is a store conditional, act appropriately - if (req->isLocked()) { - xc = req->xc; - - if (req->isUncacheable()) { - // Don't update result register (see stq_c in isa_desc) - req->result = 2; - xc->setStCondFailures(0);//Needed? [RGD] - } else { - bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag); - Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag); - req->result = lock_flag; - if (!lock_flag || - ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { - xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); - xc->setStCondFailures(xc->readStCondFailures() + 1); - if (((xc->readStCondFailures()) % 100000) == 0) { - std::cerr << "Warning: " - << xc->readStCondFailures() - << " consecutive store conditional failures " - << "on cpu " << req->xc->readCpuId() - << std::endl; - } - return NoFault; - } - else xc->setStCondFailures(0); - } - } - - // Need to clear any locked flags on other proccessors for - // this address. Only do this for succsful Store Conditionals - // and all other stores (WH64?). Unsuccessful Store - // Conditionals would have returned above, and wouldn't fall - // through. - for (int i = 0; i < this->system->threadContexts.size(); i++){ - xc = this->system->threadContexts[i]; - if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) == - (req->paddr & ~0xf)) { - xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); - } - } - -#endif - - if (req->isLocked()) { - if (req->isUncacheable()) { - req->result = 2; - } else { - if (this->lockFlag) { - if (lockAddrList.find(req->paddr) != - lockAddrList.end()) { - req->result = 1; - } else { - req->result = 0; - return NoFault; - } - } else { - req->result = 0; - return NoFault; - } - } - } -#endif - - return this->mem->write(req, (T)htog(data)); - } - /** CPU write function, forwards write to LSQ. */ template <class T> Fault write(Request *req, T &data, int store_idx) diff --git a/src/cpu/ozone/dyn_inst.hh b/src/cpu/ozone/dyn_inst.hh index 9445a5309..88f96b14b 100644 --- a/src/cpu/ozone/dyn_inst.hh +++ b/src/cpu/ozone/dyn_inst.hh @@ -146,12 +146,12 @@ class OzoneDynInst : public BaseDynInst<Impl> // storage (which is pretty hard to imagine they would have reason // to do). - uint64_t readIntReg(const StaticInst *si, int idx) + uint64_t readIntRegOperand(const StaticInst *si, int idx) { return srcInsts[idx]->readIntResult(); } - FloatReg readFloatReg(const StaticInst *si, int idx, int width) + FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width) { switch(width) { case 32: @@ -164,17 +164,18 @@ class OzoneDynInst : public BaseDynInst<Impl> } } - FloatReg readFloatReg(const StaticInst *si, int idx) + FloatReg readFloatRegOperand(const StaticInst *si, int idx) { return srcInsts[idx]->readFloatResult(); } - FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) + FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx, + int width) { return srcInsts[idx]->readIntResult(); } - FloatRegBits readFloatRegBits(const StaticInst *si, int idx) + FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) { return srcInsts[idx]->readIntResult(); } @@ -182,28 +183,30 @@ class OzoneDynInst : public BaseDynInst<Impl> /** @todo: Make results into arrays so they can handle multiple dest * registers. */ - void setIntReg(const StaticInst *si, int idx, uint64_t val) + void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) { BaseDynInst<Impl>::setIntReg(si, idx, val); } - void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, + int width) { BaseDynInst<Impl>::setFloatReg(si, idx, val, width); } - void setFloatReg(const StaticInst *si, int idx, FloatReg val) + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) { BaseDynInst<Impl>::setFloatReg(si, idx, val); } - void setFloatRegBits(const StaticInst *si, int idx, - FloatRegBits val, int width) + void setFloatRegOperandBits(const StaticInst *si, int idx, + FloatRegBits val, int width) { BaseDynInst<Impl>::setFloatRegBits(si, idx, val); } - void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) + void setFloatRegOperandBits(const StaticInst *si, int idx, + FloatRegBits val) { BaseDynInst<Impl>::setFloatRegBits(si, idx, val); } diff --git a/src/cpu/ozone/front_end.hh b/src/cpu/ozone/front_end.hh index e09e4de9c..0acf99ead 100644 --- a/src/cpu/ozone/front_end.hh +++ b/src/cpu/ozone/front_end.hh @@ -92,7 +92,7 @@ class FrontEnd /** Returns the address ranges of this device. */ virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); } + { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); } /** Timing version of receive. Handles setting fetch to the * proper status to start fetching. */ diff --git a/src/cpu/ozone/inorder_back_end.hh b/src/cpu/ozone/inorder_back_end.hh index b2522bdc8..4fd8e02f8 100644 --- a/src/cpu/ozone/inorder_back_end.hh +++ b/src/cpu/ozone/inorder_back_end.hh @@ -236,25 +236,6 @@ InorderBackEnd<Impl>::read(Addr addr, T &data, unsigned flags) */ return fault; } -#if 0 -template <class Impl> -template <class T> -Fault -InorderBackEnd<Impl>::read(MemReqPtr &req, T &data) -{ -#if FULL_SYSTEM && defined(TARGET_ALPHA) - if (req->isLocked()) { - req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr); - req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true); - } -#endif - - Fault error; - error = thread->mem->read(req, data); - data = LittleEndianGuest::gtoh(data); - return error; -} -#endif template <class Impl> template <class T> @@ -296,61 +277,6 @@ InorderBackEnd<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res) */ return fault; } -#if 0 -template <class Impl> -template <class T> -Fault -InorderBackEnd<Impl>::write(MemReqPtr &req, T &data) -{ -#if FULL_SYSTEM && defined(TARGET_ALPHA) - ExecContext *xc; - - // If this is a store conditional, act appropriately - if (req->isLocked()) { - xc = req->xc; - - if (req->isUncacheable()) { - // Don't update result register (see stq_c in isa_desc) - req->result = 2; - xc->setStCondFailures(0);//Needed? [RGD] - } else { - bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag); - Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag); - req->result = lock_flag; - if (!lock_flag || - ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { - xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); - xc->setStCondFailures(xc->readStCondFailures() + 1); - if (((xc->readStCondFailures()) % 100000) == 0) { - std::cerr << "Warning: " - << xc->readStCondFailures() - << " consecutive store conditional failures " - << "on cpu " << req->xc->readCpuId() - << std::endl; - } - return NoFault; - } - else xc->setStCondFailures(0); - } - } - - // Need to clear any locked flags on other proccessors for - // this address. Only do this for succsful Store Conditionals - // and all other stores (WH64?). Unsuccessful Store - // Conditionals would have returned above, and wouldn't fall - // through. - for (int i = 0; i < cpu->system->execContexts.size(); i++){ - xc = cpu->system->execContexts[i]; - if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) == - (req->paddr & ~0xf)) { - xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); - } - } - -#endif - return thread->mem->write(req, (T)LittleEndianGuest::htog(data)); -} -#endif template <class Impl> template <class T> diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh index 7e6849668..c981b8e63 100644 --- a/src/cpu/ozone/lw_lsq.hh +++ b/src/cpu/ozone/lw_lsq.hh @@ -258,7 +258,7 @@ class OzoneLWLSQ { virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); } + { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); } virtual bool recvTiming(PacketPtr pkt); diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index 0df6fe079..42c7bf23a 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -106,7 +106,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); } + { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); } }; CpuPort icachePort; diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index efb884325..c39bfa9cd 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -213,60 +213,63 @@ class BaseSimpleCPU : public BaseCPU // storage (which is pretty hard to imagine they would have reason // to do). - uint64_t readIntReg(const StaticInst *si, int idx) + uint64_t readIntRegOperand(const StaticInst *si, int idx) { return thread->readIntReg(si->srcRegIdx(idx)); } - FloatReg readFloatReg(const StaticInst *si, int idx, int width) + FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return thread->readFloatReg(reg_idx, width); } - FloatReg readFloatReg(const StaticInst *si, int idx) + FloatReg readFloatRegOperand(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return thread->readFloatReg(reg_idx); } - FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) + FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx, + int width) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return thread->readFloatRegBits(reg_idx, width); } - FloatRegBits readFloatRegBits(const StaticInst *si, int idx) + FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return thread->readFloatRegBits(reg_idx); } - void setIntReg(const StaticInst *si, int idx, uint64_t val) + void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) { thread->setIntReg(si->destRegIdx(idx), val); } - void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, + int width) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; thread->setFloatReg(reg_idx, val, width); } - void setFloatReg(const StaticInst *si, int idx, FloatReg val) + void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; thread->setFloatReg(reg_idx, val); } - void setFloatRegBits(const StaticInst *si, int idx, - FloatRegBits val, int width) + void setFloatRegOperandBits(const StaticInst *si, int idx, + FloatRegBits val, int width) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; thread->setFloatRegBits(reg_idx, val, width); } - void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) + void setFloatRegOperandBits(const StaticInst *si, int idx, + FloatRegBits val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; thread->setFloatRegBits(reg_idx, val); diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh index fe5d03666..abcb224bf 100644 --- a/src/cpu/simple/timing.hh +++ b/src/cpu/simple/timing.hh @@ -94,7 +94,7 @@ class TimingSimpleCPU : public BaseSimpleCPU virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) - { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); } + { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,0)); } struct TickEvent : public Event { diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index e8757c8c2..10bbe292c 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -232,75 +232,6 @@ class SimpleThread : public ThreadState /// Set the status to Halted. void halt(); -/* - template <class T> - Fault read(RequestPtr &req, T &data) - { -#if FULL_SYSTEM && THE_ISA == ALPHA_ISA - if (req->isLocked()) { - req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr); - req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true); - } -#endif - - Fault error; - error = mem->prot_read(req->paddr, data, req->size); - data = LittleEndianGuest::gtoh(data); - return error; - } - - template <class T> - Fault write(RequestPtr &req, T &data) - { -#if FULL_SYSTEM && THE_ISA == ALPHA_ISA - ExecContext *xc; - - // If this is a store conditional, act appropriately - if (req->isLocked()) { - xc = req->xc; - - if (req->isUncacheable()) { - // Don't update result register (see stq_c in isa_desc) - req->result = 2; - xc->setStCondFailures(0);//Needed? [RGD] - } else { - bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag); - Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag); - req->result = lock_flag; - if (!lock_flag || - ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { - xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); - xc->setStCondFailures(xc->readStCondFailures() + 1); - if (((xc->readStCondFailures()) % 100000) == 0) { - std::cerr << "Warning: " - << xc->readStCondFailures() - << " consecutive store conditional failures " - << "on cpu " << req->xc->readCpuId() - << std::endl; - } - return NoFault; - } - else xc->setStCondFailures(0); - } - } - - // Need to clear any locked flags on other proccessors for - // this address. Only do this for succsful Store Conditionals - // and all other stores (WH64?). Unsuccessful Store - // Conditionals would have returned above, and wouldn't fall - // through. - for (int i = 0; i < system->execContexts.size(); i++){ - xc = system->execContexts[i]; - if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) == - (req->paddr & ~0xf)) { - xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); - } - } - -#endif - return mem->prot_write(req->paddr, (T)htog(data), req->size); - } -*/ virtual bool misspeculating(); Fault instRead(RequestPtr &req) diff --git a/src/dev/alpha/tsunami_cchip.cc b/src/dev/alpha/tsunami_cchip.cc index 924e1d462..eb51d4e49 100644 --- a/src/dev/alpha/tsunami_cchip.cc +++ b/src/dev/alpha/tsunami_cchip.cc @@ -57,7 +57,7 @@ using namespace TheISA; TsunamiCChip::TsunamiCChip(Params *p) : BasicPioDevice(p), tsunami(p->tsunami) { - pioSize = 0xfffffff; + pioSize = 0x10000000; drir = 0; ipint = 0; diff --git a/src/dev/alpha/tsunami_io.cc b/src/dev/alpha/tsunami_io.cc index def214a95..8430856ef 100644 --- a/src/dev/alpha/tsunami_io.cc +++ b/src/dev/alpha/tsunami_io.cc @@ -430,7 +430,7 @@ TsunamiIO::TsunamiIO(Params *p) : BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"), rtc(p->name + ".rtc", p->tsunami, p->frequency) { - pioSize = 0xff; + pioSize = 0x100; // set the back pointer from tsunami to myself tsunami->io = this; diff --git a/src/dev/alpha/tsunami_pchip.cc b/src/dev/alpha/tsunami_pchip.cc index 94a7f96e5..f30199337 100644 --- a/src/dev/alpha/tsunami_pchip.cc +++ b/src/dev/alpha/tsunami_pchip.cc @@ -53,7 +53,7 @@ using namespace TheISA; TsunamiPChip::TsunamiPChip(Params *p) : BasicPioDevice(p) { - pioSize = 0xfff; + pioSize = 0x1000; for (int i = 0; i < 4; i++) { wsba[i] = 0; diff --git a/src/dev/baddev.cc b/src/dev/baddev.cc index 1bab93492..6a7060455 100644 --- a/src/dev/baddev.cc +++ b/src/dev/baddev.cc @@ -49,7 +49,7 @@ using namespace TheISA; BadDevice::BadDevice(Params *p) : BasicPioDevice(p), devname(p->device_name) { - pioSize = 0xf; + pioSize = 0x10; } Tick diff --git a/src/mem/bus.cc b/src/mem/bus.cc index e9a870b80..bd721dd68 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -260,19 +260,12 @@ Bus::findPort(Addr addr, int id) { /* An interval tree would be a better way to do this. --ali. */ int dest_id = -1; - int i = 0; - bool found = false; AddrRangeIter iter; + range_map<Addr,int>::iterator i; - while (i < portList.size() && !found) - { - if (portList[i].range == addr) { - dest_id = portList[i].portId; - found = true; - DPRINTF(Bus, " found addr %#llx on device %d\n", addr, dest_id); - } - i++; - } + i = portMap.find(RangeSize(addr,1)); + if (i != portMap.end()) + dest_id = i->second; // Check if this matches the default range if (dest_id == -1) { @@ -463,13 +456,13 @@ Bus::recvStatusChange(Port::Status status, int id) assert((id < interfaces.size() && id >= 0) || id == defaultId); Port *port = interfaces[id]; - std::vector<DevMap>::iterator portIter; + range_map<Addr,int>::iterator portIter; std::vector<DevMap>::iterator snoopIter; // Clean out any previously existent ids - for (portIter = portList.begin(); portIter != portList.end(); ) { - if (portIter->portId == id) - portIter = portList.erase(portIter); + for (portIter = portMap.begin(); portIter != portMap.end(); ) { + if (portIter->second == id) + portMap.erase(portIter++); else portIter++; } @@ -495,16 +488,14 @@ Bus::recvStatusChange(Port::Status status, int id) } for(iter = ranges.begin(); iter != ranges.end(); iter++) { - DevMap dm; - dm.portId = id; - dm.range = *iter; - DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for id %d\n", - dm.range.start, dm.range.end, id); - portList.push_back(dm); + iter->start, iter->end, id); + if (portMap.insert(*iter, id) == portMap.end()) + panic("Two devices with same range\n"); + } } - DPRINTF(MMU, "port list has %d entries\n", portList.size()); + DPRINTF(MMU, "port list has %d entries\n", portMap.size()); // tell all our peers that our address range has changed. // Don't tell the device that caused this change, it already knows @@ -519,7 +510,8 @@ Bus::recvStatusChange(Port::Status status, int id) void Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id) { - std::vector<DevMap>::iterator portIter; + std::vector<DevMap>::iterator snoopIter; + range_map<Addr,int>::iterator portIter; AddrRangeIter dflt_iter; bool subset; @@ -534,37 +526,37 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id) DPRINTF(BusAddrRanges, " -- Dflt: %#llx : %#llx\n",dflt_iter->start, dflt_iter->end); } - for (portIter = portList.begin(); portIter != portList.end(); portIter++) { + for (portIter = portMap.begin(); portIter != portMap.end(); portIter++) { subset = false; for (dflt_iter = defaultRange.begin(); dflt_iter != defaultRange.end(); dflt_iter++) { - if ((portIter->range.start < dflt_iter->start && - portIter->range.end >= dflt_iter->start) || - (portIter->range.start < dflt_iter->end && - portIter->range.end >= dflt_iter->end)) + if ((portIter->first.start < dflt_iter->start && + portIter->first.end >= dflt_iter->start) || + (portIter->first.start < dflt_iter->end && + portIter->first.end >= dflt_iter->end)) fatal("Devices can not set ranges that itersect the default set\ but are not a subset of the default set.\n"); - if (portIter->range.start >= dflt_iter->start && - portIter->range.end <= dflt_iter->end) { + if (portIter->first.start >= dflt_iter->start && + portIter->first.end <= dflt_iter->end) { subset = true; DPRINTF(BusAddrRanges, " -- %#llx : %#llx is a SUBSET\n", - portIter->range.start, portIter->range.end); + portIter->first.start, portIter->first.end); } } - if (portIter->portId != id && !subset) { - resp.push_back(portIter->range); + if (portIter->second != id && !subset) { + resp.push_back(portIter->first); DPRINTF(BusAddrRanges, " -- %#llx : %#llx\n", - portIter->range.start, portIter->range.end); + portIter->first.start, portIter->first.end); } } - for (portIter = portSnoopList.begin(); - portIter != portSnoopList.end(); portIter++) + for (snoopIter = portSnoopList.begin(); + snoopIter != portSnoopList.end(); snoopIter++) { - if (portIter->portId != id) { - snoop.push_back(portIter->range); + if (snoopIter->portId != id) { + snoop.push_back(snoopIter->range); DPRINTF(BusAddrRanges, " -- Snoop: %#llx : %#llx\n", - portIter->range.start, portIter->range.end); + snoopIter->range.start, snoopIter->range.end); //@todo We need to properly insert snoop ranges //not overlapping the ranges (multiple) } diff --git a/src/mem/bus.hh b/src/mem/bus.hh index c472b6143..0ad4aad60 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -42,6 +42,7 @@ #include <inttypes.h> #include "base/range.hh" +#include "base/range_map.hh" #include "mem/mem_object.hh" #include "mem/packet.hh" #include "mem/port.hh" @@ -67,7 +68,7 @@ class Bus : public MemObject int portId; Range<Addr> range; }; - std::vector<DevMap> portList; + range_map<Addr, int> portMap; AddrRangeList defaultRange; std::vector<DevMap> portSnoopList; diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc index db66c096e..29ca09060 100644 --- a/src/mem/cache/cache.cc +++ b/src/mem/cache/cache.cc @@ -37,7 +37,6 @@ */ #include "mem/config/cache.hh" -#include "mem/config/compression.hh" #include "mem/cache/tags/cache_tags.hh" @@ -61,11 +60,6 @@ #include "mem/cache/tags/split_lifo.hh" #endif -#include "base/compression/null_compression.hh" -#if defined(USE_LZSS_COMPRESSION) -#include "base/compression/lzss_compression.hh" -#endif - #include "mem/cache/miss/miss_queue.hh" #include "mem/cache/miss/blocking_buffer.hh" @@ -79,68 +73,28 @@ #if defined(USE_CACHE_FALRU) -template class Cache<CacheTags<FALRU,NullCompression>, BlockingBuffer, SimpleCoherence>; -template class Cache<CacheTags<FALRU,NullCompression>, BlockingBuffer, UniCoherence>; -template class Cache<CacheTags<FALRU,NullCompression>, MissQueue, SimpleCoherence>; -template class Cache<CacheTags<FALRU,NullCompression>, MissQueue, UniCoherence>; -#if defined(USE_LZSS_COMPRESSION) -template class Cache<CacheTags<FALRU,LZSSCompression>, BlockingBuffer, SimpleCoherence>; -template class Cache<CacheTags<FALRU,LZSSCompression>, BlockingBuffer, UniCoherence>; -template class Cache<CacheTags<FALRU,LZSSCompression>, MissQueue, SimpleCoherence>; -template class Cache<CacheTags<FALRU,LZSSCompression>, MissQueue, UniCoherence>; -#endif +template class Cache<CacheTags<FALRU>, SimpleCoherence>; +template class Cache<CacheTags<FALRU>, UniCoherence>; #endif #if defined(USE_CACHE_IIC) -template class Cache<CacheTags<IIC,NullCompression>, BlockingBuffer, SimpleCoherence>; -template class Cache<CacheTags<IIC,NullCompression>, BlockingBuffer, UniCoherence>; -template class Cache<CacheTags<IIC,NullCompression>, MissQueue, SimpleCoherence>; -template class Cache<CacheTags<IIC,NullCompression>, MissQueue, UniCoherence>; -#if defined(USE_LZSS_COMPRESSION) -template class Cache<CacheTags<IIC,LZSSCompression>, BlockingBuffer, SimpleCoherence>; -template class Cache<CacheTags<IIC,LZSSCompression>, BlockingBuffer, UniCoherence>; -template class Cache<CacheTags<IIC,LZSSCompression>, MissQueue, SimpleCoherence>; -template class Cache<CacheTags<IIC,LZSSCompression>, MissQueue, UniCoherence>; -#endif +template class Cache<CacheTags<IIC>, SimpleCoherence>; +template class Cache<CacheTags<IIC>, UniCoherence>; #endif #if defined(USE_CACHE_LRU) -template class Cache<CacheTags<LRU,NullCompression>, BlockingBuffer, SimpleCoherence>; -template class Cache<CacheTags<LRU,NullCompression>, BlockingBuffer, UniCoherence>; -template class Cache<CacheTags<LRU,NullCompression>, MissQueue, SimpleCoherence>; -template class Cache<CacheTags<LRU,NullCompression>, MissQueue, UniCoherence>; -#if defined(USE_LZSS_COMPRESSION) -template class Cache<CacheTags<LRU,LZSSCompression>, BlockingBuffer, SimpleCoherence>; -template class Cache<CacheTags<LRU,LZSSCompression>, BlockingBuffer, UniCoherence>; -template class Cache<CacheTags<LRU,LZSSCompression>, MissQueue, SimpleCoherence>; -template class Cache<CacheTags<LRU,LZSSCompression>, MissQueue, UniCoherence>; -#endif +template class Cache<CacheTags<LRU>, SimpleCoherence>; +template class Cache<CacheTags<LRU>, UniCoherence>; #endif #if defined(USE_CACHE_SPLIT) -template class Cache<CacheTags<Split,NullCompression>, BlockingBuffer, SimpleCoherence>; -template class Cache<CacheTags<Split,NullCompression>, BlockingBuffer, UniCoherence>; -template class Cache<CacheTags<Split,NullCompression>, MissQueue, SimpleCoherence>; -template class Cache<CacheTags<Split,NullCompression>, MissQueue, UniCoherence>; -#if defined(USE_LZSS_COMPRESSION) -template class Cache<CacheTags<Split,LZSSCompression>, BlockingBuffer, SimpleCoherence>; -template class Cache<CacheTags<Split,LZSSCompression>, BlockingBuffer, UniCoherence>; -template class Cache<CacheTags<Split,LZSSCompression>, MissQueue, SimpleCoherence>; -template class Cache<CacheTags<Split,LZSSCompression>, MissQueue, UniCoherence>; -#endif +template class Cache<CacheTags<Split>, SimpleCoherence>; +template class Cache<CacheTags<Split>, UniCoherence>; #endif #if defined(USE_CACHE_SPLIT_LIFO) -template class Cache<CacheTags<SplitLIFO,NullCompression>, BlockingBuffer, SimpleCoherence>; -template class Cache<CacheTags<SplitLIFO,NullCompression>, BlockingBuffer, UniCoherence>; -template class Cache<CacheTags<SplitLIFO,NullCompression>, MissQueue, SimpleCoherence>; -template class Cache<CacheTags<SplitLIFO,NullCompression>, MissQueue, UniCoherence>; -#if defined(USE_LZSS_COMPRESSION) -template class Cache<CacheTags<SplitLIFO,LZSSCompression>, BlockingBuffer, SimpleCoherence>; -template class Cache<CacheTags<SplitLIFO,LZSSCompression>, BlockingBuffer, UniCoherence>; -template class Cache<CacheTags<SplitLIFO,LZSSCompression>, MissQueue, SimpleCoherence>; -template class Cache<CacheTags<SplitLIFO,LZSSCompression>, MissQueue, UniCoherence>; -#endif +template class Cache<CacheTags<SplitLIFO>, SimpleCoherence>; +template class Cache<CacheTags<SplitLIFO>, UniCoherence>; #endif #endif //DOXYGEN_SHOULD_SKIP_THIS diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index 1f3b087bb..29502042c 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -42,6 +42,7 @@ #include "cpu/smt.hh" // SMT_MAX_THREADS #include "mem/cache/base_cache.hh" +#include "mem/cache/miss/miss_buffer.hh" #include "mem/cache/prefetch/prefetcher.hh" //Forward decleration @@ -55,7 +56,7 @@ class MSHR; * @sa MissQueue. Coherence handles all coherence policy details @sa * UniCoherence, SimpleMultiCoherence. */ -template <class TagStore, class Buffering, class Coherence> +template <class TagStore, class Coherence> class Cache : public BaseCache { public: @@ -68,12 +69,12 @@ class Cache : public BaseCache /** Tag and data Storage */ TagStore *tags; /** Miss and Writeback handler */ - Buffering *missQueue; + MissBuffer *missQueue; /** Coherence protocol. */ Coherence *coherence; /** Prefetcher */ - Prefetcher<TagStore, Buffering> *prefetcher; + Prefetcher<TagStore> *prefetcher; /** * The clock ratio of the outgoing bus. @@ -105,16 +106,16 @@ class Cache : public BaseCache { public: TagStore *tags; - Buffering *missQueue; + MissBuffer *missQueue; Coherence *coherence; BaseCache::Params baseParams; - Prefetcher<TagStore, Buffering> *prefetcher; + Prefetcher<TagStore> *prefetcher; bool prefetchAccess; int hitLatency; - Params(TagStore *_tags, Buffering *mq, Coherence *coh, + Params(TagStore *_tags, MissBuffer *mq, Coherence *coh, BaseCache::Params params, - Prefetcher<TagStore, Buffering> *_prefetcher, + Prefetcher<TagStore> *_prefetcher, bool prefetch_access, int hit_latency) : tags(_tags), missQueue(mq), coherence(coh), baseParams(params), diff --git a/src/mem/cache/cache_builder.cc b/src/mem/cache/cache_builder.cc index 03646ec2a..4b1b19718 100644 --- a/src/mem/cache/cache_builder.cc +++ b/src/mem/cache/cache_builder.cc @@ -37,7 +37,6 @@ // Must be included first to determine which caches we want #include "mem/config/cache.hh" -#include "mem/config/compression.hh" #include "mem/config/prefetch.hh" #include "mem/cache/base_cache.hh" @@ -69,9 +68,7 @@ // Compression Templates #include "base/compression/null_compression.hh" -#if defined(USE_LZSS_COMPRESSION) #include "base/compression/lzss_compression.hh" -#endif // CacheTags Templates #include "mem/cache/tags/cache_tags.hh" @@ -211,156 +208,127 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(BaseCache) END_INIT_SIM_OBJECT_PARAMS(BaseCache) -#define BUILD_CACHE(t, comp, b, c) do { \ - Prefetcher<CacheTags<t, comp>, b> *pf; \ +#define BUILD_CACHE(t, c) do { \ + Prefetcher<CacheTags<t> > *pf; \ if (pf_policy == "tagged") { \ - BUILD_TAGGED_PREFETCHER(t, comp, b); \ + BUILD_TAGGED_PREFETCHER(t); \ } \ else if (pf_policy == "stride") { \ - BUILD_STRIDED_PREFETCHER(t, comp, b); \ + BUILD_STRIDED_PREFETCHER(t); \ } \ else if (pf_policy == "ghb") { \ - BUILD_GHB_PREFETCHER(t, comp, b); \ + BUILD_GHB_PREFETCHER(t); \ } \ else { \ - BUILD_NULL_PREFETCHER(t, comp, b); \ + BUILD_NULL_PREFETCHER(t); \ } \ - Cache<CacheTags<t, comp>, b, c>::Params params(tagStore, mq, coh, \ + Cache<CacheTags<t>, c>::Params params(tagStore, mq, coh, \ base_params, \ - /*in_bus, out_bus,*/ pf, \ + pf, \ prefetch_access, hit_latency); \ - Cache<CacheTags<t, comp>, b, c> *retval = \ - new Cache<CacheTags<t, comp>, b, c>(getInstanceName(), /*hier,*/ \ - params); \ -/* if (in_bus == NULL) { \ - retval->setSlaveInterface(new MemoryInterface<Cache<CacheTags<t, comp>, b, c> >(getInstanceName(), hier, retval, mem_trace)); \ - } else { \ - retval->setSlaveInterface(new SlaveInterface<Cache<CacheTags<t, comp>, b, c>, Bus>(getInstanceName(), hier, retval, in_bus, mem_trace)); \ - } \ - retval->setMasterInterface(new MasterInterface<Cache<CacheTags<t, comp>, b, c>, Bus>(getInstanceName(), hier, retval, out_bus)); \ - out_bus->rangeChange(); \ - return retval; \ -*/return retval; \ + Cache<CacheTags<t>, c> *retval = \ + new Cache<CacheTags<t>, c>(getInstanceName(), params); \ +return retval; \ } while (0) #define BUILD_CACHE_PANIC(x) do { \ panic("%s not compiled into M5", x); \ } while (0) -#if defined(USE_LZSS_COMPRESSION) -#define BUILD_COMPRESSED_CACHE(TAGS, tags, b, c) do { \ - if (compressed_bus || store_compressed){ \ - CacheTags<TAGS, LZSSCompression> *tagStore = \ - new CacheTags<TAGS, LZSSCompression>(tags, \ - compression_latency, \ - true, store_compressed, \ - adaptive_compression, \ - prefetch_miss); \ - BUILD_CACHE(TAGS, LZSSCompression, b, c); \ - } else { \ - CacheTags<TAGS, NullCompression> *tagStore = \ - new CacheTags<TAGS, NullCompression>(tags, \ - compression_latency, \ - true, store_compressed, \ - adaptive_compression, \ - prefetch_miss); \ - BUILD_CACHE(TAGS, NullCompression, b, c); \ - } \ - } while (0) -#else -#define BUILD_COMPRESSED_CACHE(TAGS, tags, b, c) do { \ - if (compressed_bus || store_compressed){ \ - BUILD_CACHE_PANIC("compressed caches"); \ +#define BUILD_COMPRESSED_CACHE(TAGS, tags, c) \ + do { \ + CompressionAlgorithm *compAlg; \ + if (compressed_bus || store_compressed) { \ + compAlg = new LZSSCompression(); \ } else { \ - CacheTags<TAGS, NullCompression> *tagStore = \ - new CacheTags<TAGS, NullCompression>(tags, \ - compression_latency, \ - true, store_compressed, \ - adaptive_compression \ - prefetch_miss); \ - BUILD_CACHE(TAGS, NullCompression, b, c); \ + compAlg = new NullCompression(); \ } \ + CacheTags<TAGS> *tagStore = \ + new CacheTags<TAGS>(tags, compression_latency, true, \ + store_compressed, adaptive_compression, \ + compressed_bus, \ + compAlg, prefetch_miss); \ + BUILD_CACHE(TAGS, c); \ } while (0) -#endif #if defined(USE_CACHE_FALRU) -#define BUILD_FALRU_CACHE(b,c) do { \ +#define BUILD_FALRU_CACHE(c) do { \ FALRU *tags = new FALRU(block_size, size, latency); \ - BUILD_COMPRESSED_CACHE(FALRU, tags, b, c); \ + BUILD_COMPRESSED_CACHE(FALRU, tags, c); \ } while (0) #else -#define BUILD_FALRU_CACHE(b, c) BUILD_CACHE_PANIC("falru cache") +#define BUILD_FALRU_CACHE(c) BUILD_CACHE_PANIC("falru cache") #endif #if defined(USE_CACHE_LRU) -#define BUILD_LRU_CACHE(b, c) do { \ +#define BUILD_LRU_CACHE(c) do { \ LRU *tags = new LRU(numSets, block_size, assoc, latency); \ - BUILD_COMPRESSED_CACHE(LRU, tags, b, c); \ + BUILD_COMPRESSED_CACHE(LRU, tags, c); \ } while (0) #else -#define BUILD_LRU_CACHE(b, c) BUILD_CACHE_PANIC("lru cache") +#define BUILD_LRU_CACHE(c) BUILD_CACHE_PANIC("lru cache") #endif #if defined(USE_CACHE_SPLIT) -#define BUILD_SPLIT_CACHE(b, c) do { \ +#define BUILD_SPLIT_CACHE(c) do { \ Split *tags = new Split(numSets, block_size, assoc, split_size, lifo, \ two_queue, latency); \ - BUILD_COMPRESSED_CACHE(Split, tags, b, c); \ + BUILD_COMPRESSED_CACHE(Split, tags, c); \ } while (0) #else -#define BUILD_SPLIT_CACHE(b, c) BUILD_CACHE_PANIC("split cache") +#define BUILD_SPLIT_CACHE(c) BUILD_CACHE_PANIC("split cache") #endif #if defined(USE_CACHE_SPLIT_LIFO) -#define BUILD_SPLIT_LIFO_CACHE(b, c) do { \ +#define BUILD_SPLIT_LIFO_CACHE(c) do { \ SplitLIFO *tags = new SplitLIFO(block_size, size, assoc, \ latency, two_queue, -1); \ - BUILD_COMPRESSED_CACHE(SplitLIFO, tags, b, c); \ + BUILD_COMPRESSED_CACHE(SplitLIFO, tags, c); \ } while (0) #else -#define BUILD_SPLIT_LIFO_CACHE(b, c) BUILD_CACHE_PANIC("lifo cache") +#define BUILD_SPLIT_LIFO_CACHE(c) BUILD_CACHE_PANIC("lifo cache") #endif #if defined(USE_CACHE_IIC) -#define BUILD_IIC_CACHE(b ,c) do { \ +#define BUILD_IIC_CACHE(c) do { \ IIC *tags = new IIC(iic_params); \ - BUILD_COMPRESSED_CACHE(IIC, tags, b, c); \ + BUILD_COMPRESSED_CACHE(IIC, tags, c); \ } while (0) #else -#define BUILD_IIC_CACHE(b, c) BUILD_CACHE_PANIC("iic") +#define BUILD_IIC_CACHE(c) BUILD_CACHE_PANIC("iic") #endif -#define BUILD_CACHES(b, c) do { \ +#define BUILD_CACHES(c) do { \ if (repl == NULL) { \ if (numSets == 1) { \ - BUILD_FALRU_CACHE(b, c); \ + BUILD_FALRU_CACHE(c); \ } else { \ if (split == true) { \ - BUILD_SPLIT_CACHE(b, c); \ + BUILD_SPLIT_CACHE(c); \ } else if (lifo == true) { \ - BUILD_SPLIT_LIFO_CACHE(b, c); \ + BUILD_SPLIT_LIFO_CACHE(c); \ } else { \ - BUILD_LRU_CACHE(b, c); \ + BUILD_LRU_CACHE(c); \ } \ } \ } else { \ - BUILD_IIC_CACHE(b, c); \ + BUILD_IIC_CACHE(c); \ } \ } while (0) #define BUILD_COHERENCE(b) do { \ if (protocol == NULL) { \ UniCoherence *coh = new UniCoherence(); \ - BUILD_CACHES(b, UniCoherence); \ + BUILD_CACHES(UniCoherence); \ } else { \ SimpleCoherence *coh = new SimpleCoherence(protocol); \ - BUILD_CACHES(b, SimpleCoherence); \ + BUILD_CACHES(SimpleCoherence); \ } \ } while (0) #if defined(USE_TAGGED) -#define BUILD_TAGGED_PREFETCHER(t, comp, b) pf = new \ - TaggedPrefetcher<CacheTags<t, comp>, b>(prefetcher_size, \ +#define BUILD_TAGGED_PREFETCHER(t) pf = new \ + TaggedPrefetcher<CacheTags<t> >(prefetcher_size, \ !prefetch_past_page, \ prefetch_serial_squash, \ prefetch_cache_check_push, \ @@ -368,12 +336,12 @@ END_INIT_SIM_OBJECT_PARAMS(BaseCache) prefetch_latency, \ prefetch_degree) #else -#define BUILD_TAGGED_PREFETCHER(t, comp, b) BUILD_CACHE_PANIC("Tagged Prefetcher") +#define BUILD_TAGGED_PREFETCHER(t) BUILD_CACHE_PANIC("Tagged Prefetcher") #endif #if defined(USE_STRIDED) -#define BUILD_STRIDED_PREFETCHER(t, comp, b) pf = new \ - StridePrefetcher<CacheTags<t, comp>, b>(prefetcher_size, \ +#define BUILD_STRIDED_PREFETCHER(t) pf = new \ + StridePrefetcher<CacheTags<t> >(prefetcher_size, \ !prefetch_past_page, \ prefetch_serial_squash, \ prefetch_cache_check_push, \ @@ -382,12 +350,12 @@ END_INIT_SIM_OBJECT_PARAMS(BaseCache) prefetch_degree, \ prefetch_use_cpu_id) #else -#define BUILD_STRIDED_PREFETCHER(t, comp, b) BUILD_CACHE_PANIC("Stride Prefetcher") +#define BUILD_STRIDED_PREFETCHER(t) BUILD_CACHE_PANIC("Stride Prefetcher") #endif #if defined(USE_GHB) -#define BUILD_GHB_PREFETCHER(t, comp, b) pf = new \ - GHBPrefetcher<CacheTags<t, comp>, b>(prefetcher_size, \ +#define BUILD_GHB_PREFETCHER(t) pf = new \ + GHBPrefetcher<CacheTags<t> >(prefetcher_size, \ !prefetch_past_page, \ prefetch_serial_squash, \ prefetch_cache_check_push, \ @@ -396,12 +364,12 @@ END_INIT_SIM_OBJECT_PARAMS(BaseCache) prefetch_degree, \ prefetch_use_cpu_id) #else -#define BUILD_GHB_PREFETCHER(t, comp, b) BUILD_CACHE_PANIC("GHB Prefetcher") +#define BUILD_GHB_PREFETCHER(t) BUILD_CACHE_PANIC("GHB Prefetcher") #endif #if defined(USE_TAGGED) -#define BUILD_NULL_PREFETCHER(t, comp, b) pf = new \ - TaggedPrefetcher<CacheTags<t, comp>, b>(prefetcher_size, \ +#define BUILD_NULL_PREFETCHER(t) pf = new \ + TaggedPrefetcher<CacheTags<t> >(prefetcher_size, \ !prefetch_past_page, \ prefetch_serial_squash, \ prefetch_cache_check_push, \ @@ -409,7 +377,7 @@ END_INIT_SIM_OBJECT_PARAMS(BaseCache) prefetch_latency, \ prefetch_degree) #else -#define BUILD_NULL_PREFETCHER(t, comp, b) BUILD_CACHE_PANIC("NULL Prefetcher (uses Tagged)") +#define BUILD_NULL_PREFETCHER(t) BUILD_CACHE_PANIC("NULL Prefetcher (uses Tagged)") #endif CREATE_SIM_OBJECT(BaseCache) diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 3a681bc52..6742d5892 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -55,9 +55,9 @@ bool SIGNAL_NACK_HACK; -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> bool -Cache<TagStore,Buffering,Coherence>:: +Cache<TagStore,Coherence>:: doTimingAccess(PacketPtr pkt, CachePort *cachePort, bool isCpuSide) { if (isCpuSide) @@ -81,9 +81,9 @@ doTimingAccess(PacketPtr pkt, CachePort *cachePort, bool isCpuSide) return true; } -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> Tick -Cache<TagStore,Buffering,Coherence>:: +Cache<TagStore,Coherence>:: doAtomicAccess(PacketPtr pkt, bool isCpuSide) { if (isCpuSide) @@ -103,9 +103,9 @@ doAtomicAccess(PacketPtr pkt, bool isCpuSide) return hitLatency; } -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> void -Cache<TagStore,Buffering,Coherence>:: +Cache<TagStore,Coherence>:: doFunctionalAccess(PacketPtr pkt, bool isCpuSide) { if (isCpuSide) @@ -123,19 +123,19 @@ doFunctionalAccess(PacketPtr pkt, bool isCpuSide) } } -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> void -Cache<TagStore,Buffering,Coherence>:: +Cache<TagStore,Coherence>:: recvStatusChange(Port::Status status, bool isCpuSide) { } -template<class TagStore, class Buffering, class Coherence> -Cache<TagStore,Buffering,Coherence>:: +template<class TagStore, class Coherence> +Cache<TagStore,Coherence>:: Cache(const std::string &_name, - Cache<TagStore,Buffering,Coherence>::Params ¶ms) + Cache<TagStore,Coherence>::Params ¶ms) : BaseCache(_name, params.baseParams), prefetchAccess(params.prefetchAccess), tags(params.tags), missQueue(params.missQueue), @@ -154,9 +154,9 @@ Cache(const std::string &_name, invalidatePkt = new Packet(invalidateReq, Packet::InvalidateReq, 0); } -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> void -Cache<TagStore,Buffering,Coherence>::regStats() +Cache<TagStore,Coherence>::regStats() { BaseCache::regStats(); tags->regStats(name()); @@ -165,9 +165,9 @@ Cache<TagStore,Buffering,Coherence>::regStats() prefetcher->regStats(name()); } -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> bool -Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt) +Cache<TagStore,Coherence>::access(PacketPtr &pkt) { //@todo Add back in MemDebug Calls // MemDebug::cacheAccess(pkt); @@ -253,9 +253,9 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt) } -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> PacketPtr -Cache<TagStore,Buffering,Coherence>::getPacket() +Cache<TagStore,Coherence>::getPacket() { assert(missQueue->havePending()); PacketPtr pkt = missQueue->getPacket(); @@ -276,9 +276,9 @@ Cache<TagStore,Buffering,Coherence>::getPacket() return pkt; } -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> void -Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr, +Cache<TagStore,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr, bool success) { if (success && !(SIGNAL_NACK_HACK)) { @@ -319,9 +319,9 @@ Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr, } } -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> void -Cache<TagStore,Buffering,Coherence>::handleResponse(PacketPtr &pkt) +Cache<TagStore,Coherence>::handleResponse(PacketPtr &pkt) { BlkType *blk = NULL; if (pkt->senderState) { @@ -363,16 +363,16 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(PacketPtr &pkt) } } -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> PacketPtr -Cache<TagStore,Buffering,Coherence>::getCoherencePacket() +Cache<TagStore,Coherence>::getCoherencePacket() { return coherence->getPacket(); } -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> void -Cache<TagStore,Buffering,Coherence>::sendCoherenceResult(PacketPtr &pkt, +Cache<TagStore,Coherence>::sendCoherenceResult(PacketPtr &pkt, MSHR *cshr, bool success) { @@ -380,9 +380,9 @@ Cache<TagStore,Buffering,Coherence>::sendCoherenceResult(PacketPtr &pkt, } -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> void -Cache<TagStore,Buffering,Coherence>::snoop(PacketPtr &pkt) +Cache<TagStore,Coherence>::snoop(PacketPtr &pkt) { if (pkt->req->isUncacheable()) { //Can't get a hit on an uncacheable address @@ -514,9 +514,9 @@ Cache<TagStore,Buffering,Coherence>::snoop(PacketPtr &pkt) tags->handleSnoop(blk, new_state); } -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> void -Cache<TagStore,Buffering,Coherence>::snoopResponse(PacketPtr &pkt) +Cache<TagStore,Coherence>::snoopResponse(PacketPtr &pkt) { //Need to handle the response, if NACKED if (pkt->flags & NACKED_LINE) { @@ -533,9 +533,9 @@ Cache<TagStore,Buffering,Coherence>::snoopResponse(PacketPtr &pkt) } } -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> void -Cache<TagStore,Buffering,Coherence>::invalidateBlk(Addr addr) +Cache<TagStore,Coherence>::invalidateBlk(Addr addr) { tags->invalidateBlk(addr); } @@ -544,9 +544,9 @@ Cache<TagStore,Buffering,Coherence>::invalidateBlk(Addr addr) /** * @todo Fix to not assume write allocate */ -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> Tick -Cache<TagStore,Buffering,Coherence>::probe(PacketPtr &pkt, bool update, +Cache<TagStore,Coherence>::probe(PacketPtr &pkt, bool update, CachePort* otherSidePort) { // MemDebug::cacheProbe(pkt); @@ -694,9 +694,9 @@ return 0; return 0; } -template<class TagStore, class Buffering, class Coherence> +template<class TagStore, class Coherence> Tick -Cache<TagStore,Buffering,Coherence>::snoopProbe(PacketPtr &pkt) +Cache<TagStore,Coherence>::snoopProbe(PacketPtr &pkt) { //Send a atomic (false) invalidate up if the protocol calls for it if (coherence->propogateInvalidate(pkt, false)) { diff --git a/src/mem/cache/miss/blocking_buffer.cc b/src/mem/cache/miss/blocking_buffer.cc index bf741e547..4a431d82d 100644 --- a/src/mem/cache/miss/blocking_buffer.cc +++ b/src/mem/cache/miss/blocking_buffer.cc @@ -33,11 +33,9 @@ * Definitions of a simple buffer for a blocking cache. */ -#include "cpu/smt.hh" //for maxThreadsPerCPU #include "mem/cache/base_cache.hh" #include "mem/cache/miss/blocking_buffer.hh" #include "mem/cache/prefetch/base_prefetcher.hh" -#include "sim/eventq.hh" // for Event declaration. #include "mem/request.hh" /** @@ -46,28 +44,11 @@ void BlockingBuffer::regStats(const std::string &name) { - using namespace Stats; - writebacks - .init(maxThreadsPerCPU) - .name(name + ".writebacks") - .desc("number of writebacks") - .flags(total) - ; + MissBuffer::regStats(name); } -void -BlockingBuffer::setCache(BaseCache *_cache) -{ - cache = _cache; - blkSize = cache->getBlockSize(); -} void -BlockingBuffer::setPrefetcher(BasePrefetcher *_prefetcher) -{ - prefetcher = _prefetcher; -} -void BlockingBuffer::handleMiss(PacketPtr &pkt, int blk_size, Tick time) { Addr blk_addr = pkt->getAddr() & ~(Addr)(blk_size - 1); @@ -241,3 +222,23 @@ BlockingBuffer::doWriteback(PacketPtr &pkt) cache->setBlocked(Blocked_NoWBBuffers); cache->setMasterRequest(Request_WB, curTick); } + + +MSHR * +BlockingBuffer::findMSHR(Addr addr) +{ + if (miss.addr == addr && miss.pkt) + return &miss; + return NULL; +} + + +bool +BlockingBuffer::findWrites(Addr addr, std::vector<MSHR*>& writes) +{ + if (wb.addr == addr && wb.pkt) { + writes.push_back(&wb); + return true; + } + return false; +} diff --git a/src/mem/cache/miss/blocking_buffer.hh b/src/mem/cache/miss/blocking_buffer.hh index 934a843a6..205068a8c 100644 --- a/src/mem/cache/miss/blocking_buffer.hh +++ b/src/mem/cache/miss/blocking_buffer.hh @@ -38,16 +38,14 @@ #include <vector> +#include "base/misc.hh" // for fatal() +#include "mem/cache/miss/miss_buffer.hh" #include "mem/cache/miss/mshr.hh" -#include "base/statistics.hh" - -class BaseCache; -class BasePrefetcher; /** * Miss and writeback storage for a blocking cache. */ -class BlockingBuffer +class BlockingBuffer : public MissBuffer { protected: /** Miss storage. */ @@ -55,38 +53,13 @@ protected: /** WB storage. */ MSHR wb; - //Params - - /** Allocate on write misses. */ - const bool writeAllocate; - - /** Pointer to the parent cache. */ - BaseCache* cache; - - BasePrefetcher* prefetcher; - - /** Block size of the parent cache. */ - int blkSize; - - // Statistics - /** - * @addtogroup CacheStatistics - * @{ - */ - /** Number of blocks written back per thread. */ - Stats::Vector<> writebacks; - - /** - * @} - */ - public: /** * Builds and initializes this buffer. * @param write_allocate If true, treat write misses the same as reads. */ BlockingBuffer(bool write_allocate) - : writeAllocate(write_allocate) + : MissBuffer(write_allocate) { } @@ -97,14 +70,6 @@ public: void regStats(const std::string &name); /** - * Called by the parent cache to set the back pointer. - * @param _cache A pointer to the parent cache. - */ - void setCache(BaseCache *_cache); - - void setPrefetcher(BasePrefetcher *_prefetcher); - - /** * Handle a cache miss properly. Requests the bus and marks the cache as * blocked. * @param pkt The request that missed in the cache. @@ -183,12 +148,7 @@ public: * @param asid The address space id. * @return A pointer to miss if it matches. */ - MSHR* findMSHR(Addr addr) - { - if (miss.addr == addr && miss.pkt) - return &miss; - return NULL; - } + MSHR* findMSHR(Addr addr); /** * Searches for the supplied address in the write buffer. @@ -197,16 +157,7 @@ public: * @param writes List of pointers to the matching writes. * @return True if there is a matching write. */ - bool findWrites(Addr addr, std::vector<MSHR*>& writes) - { - if (wb.addr == addr && wb.pkt) { - writes.push_back(&wb); - return true; - } - return false; - } - - + bool findWrites(Addr addr, std::vector<MSHR*>& writes); /** * Perform a writeback of dirty data to the given address. diff --git a/src/mem/cache/miss/miss_buffer.cc b/src/mem/cache/miss/miss_buffer.cc new file mode 100644 index 000000000..4d9cd0958 --- /dev/null +++ b/src/mem/cache/miss/miss_buffer.cc @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2003-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * 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: Erik Hallnor + */ + +#include "cpu/smt.hh" //for maxThreadsPerCPU +#include "mem/cache/base_cache.hh" +#include "mem/cache/miss/miss_buffer.hh" +#include "mem/cache/prefetch/base_prefetcher.hh" + +/** + * @todo Move writebacks into shared BaseBuffer class. + */ +void +MissBuffer::regStats(const std::string &name) +{ + using namespace Stats; + writebacks + .init(maxThreadsPerCPU) + .name(name + ".writebacks") + .desc("number of writebacks") + .flags(total) + ; +} + +void +MissBuffer::setCache(BaseCache *_cache) +{ + cache = _cache; + blkSize = cache->getBlockSize(); +} + +void +MissBuffer::setPrefetcher(BasePrefetcher *_prefetcher) +{ + prefetcher = _prefetcher; +} diff --git a/src/mem/cache/miss/miss_buffer.hh b/src/mem/cache/miss/miss_buffer.hh new file mode 100644 index 000000000..3e3080578 --- /dev/null +++ b/src/mem/cache/miss/miss_buffer.hh @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2003-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * 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: Steve Reinhardt + */ + +/** + * @file + * MissBuffer declaration. + */ + +#ifndef __MISS_BUFFER_HH__ +#define __MISS_BUFFER_HH__ + +class BaseCache; +class BasePrefetcher; +class MSHR; + +/** + * Abstract base class for cache miss buffering. + */ +class MissBuffer +{ + protected: + /** True if the cache should allocate on a write miss. */ + const bool writeAllocate; + + /** Pointer to the parent cache. */ + BaseCache *cache; + + /** The Prefetcher */ + BasePrefetcher *prefetcher; + + /** Block size of the parent cache. */ + int blkSize; + + // Statistics + /** + * @addtogroup CacheStatistics + * @{ + */ + /** Number of blocks written back per thread. */ + Stats::Vector<> writebacks; + + /** + * @} + */ + + public: + MissBuffer(bool write_allocate) + : writeAllocate(write_allocate) + { + } + + virtual ~MissBuffer() {} + + /** + * Called by the parent cache to set the back pointer. + * @param _cache A pointer to the parent cache. + */ + void setCache(BaseCache *_cache); + + void setPrefetcher(BasePrefetcher *_prefetcher); + + /** + * Register statistics for this object. + * @param name The name of the parent cache. + */ + virtual void regStats(const std::string &name); + + /** + * Handle a cache miss properly. Either allocate an MSHR for the request, + * or forward it through the write buffer. + * @param pkt The request that missed in the cache. + * @param blk_size The block size of the cache. + * @param time The time the miss is detected. + */ + virtual void handleMiss(PacketPtr &pkt, int blk_size, Tick time) = 0; + + /** + * Fetch the block for the given address and buffer the given target. + * @param addr The address to fetch. + * @param asid The address space of the address. + * @param blk_size The block size of the cache. + * @param time The time the miss is detected. + * @param target The target for the fetch. + */ + virtual MSHR *fetchBlock(Addr addr, int blk_size, Tick time, + PacketPtr &target) = 0; + + /** + * Selects a outstanding request to service. + * @return The request to service, NULL if none found. + */ + virtual PacketPtr getPacket() = 0; + + /** + * Set the command to the given bus command. + * @param pkt The request to update. + * @param cmd The bus command to use. + */ + virtual void setBusCmd(PacketPtr &pkt, Packet::Command cmd) = 0; + + /** + * Restore the original command in case of a bus transmission error. + * @param pkt The request to reset. + */ + virtual void restoreOrigCmd(PacketPtr &pkt) = 0; + + /** + * Marks a request as in service (sent on the bus). This can have side + * effect since storage for no response commands is deallocated once they + * are successfully sent. + * @param pkt The request that was sent on the bus. + */ + virtual void markInService(PacketPtr &pkt, MSHR* mshr) = 0; + + /** + * Collect statistics and free resources of a satisfied request. + * @param pkt The request that has been satisfied. + * @param time The time when the request is satisfied. + */ + virtual void handleResponse(PacketPtr &pkt, Tick time) = 0; + + /** + * Removes all outstanding requests for a given thread number. If a request + * has been sent to the bus, this function removes all of its targets. + * @param threadNum The thread number of the requests to squash. + */ + virtual void squash(int threadNum) = 0; + + /** + * Return the current number of outstanding misses. + * @return the number of outstanding misses. + */ + virtual int getMisses() = 0; + + /** + * Searches for the supplied address in the miss queue. + * @param addr The address to look for. + * @param asid The address space id. + * @return The MSHR that contains the address, NULL if not found. + * @warning Currently only searches the miss queue. If non write allocate + * might need to search the write buffer for coherence. + */ + virtual MSHR* findMSHR(Addr addr) = 0; + + /** + * Searches for the supplied address in the write buffer. + * @param addr The address to look for. + * @param asid The address space id. + * @param writes The list of writes that match the address. + * @return True if any writes are found + */ + virtual bool findWrites(Addr addr, std::vector<MSHR*>& writes) = 0; + + /** + * Perform a writeback of dirty data to the given address. + * @param addr The address to write to. + * @param asid The address space id. + * @param xc The execution context of the address space. + * @param size The number of bytes to write. + * @param data The data to write, can be NULL. + * @param compressed True if the data is compressed. + */ + virtual void doWriteback(Addr addr, int size, uint8_t *data, + bool compressed) = 0; + + /** + * Perform the given writeback request. + * @param pkt The writeback request. + */ + virtual void doWriteback(PacketPtr &pkt) = 0; + + /** + * Returns true if there are outstanding requests. + * @return True if there are outstanding requests. + */ + virtual bool havePending() = 0; + + /** + * Add a target to the given MSHR. This assumes it is in the miss queue. + * @param mshr The mshr to add a target to. + * @param pkt The target to add. + */ + virtual void addTarget(MSHR *mshr, PacketPtr &pkt) = 0; + + /** + * Allocate a MSHR to hold a list of targets to a block involved in a copy. + * If the block is marked done then the MSHR already holds the data to + * fill the block. Otherwise the block needs to be fetched. + * @param addr The address to buffer. + * @param asid The address space ID. + * @return A pointer to the allocated MSHR. + */ + virtual MSHR* allocateTargetList(Addr addr) = 0; +}; + +#endif //__MISS_BUFFER_HH__ diff --git a/src/mem/cache/miss/miss_queue.cc b/src/mem/cache/miss/miss_queue.cc index 3c4586272..1d3e22326 100644 --- a/src/mem/cache/miss/miss_queue.cc +++ b/src/mem/cache/miss/miss_queue.cc @@ -48,16 +48,25 @@ using namespace std; */ MissQueue::MissQueue(int numMSHRs, int numTargets, int write_buffers, bool write_allocate, bool prefetch_miss) - : mq(numMSHRs, 4), wb(write_buffers,numMSHRs+1000), numMSHR(numMSHRs), + : MissBuffer(write_allocate), + mq(numMSHRs, 4), wb(write_buffers,numMSHRs+1000), numMSHR(numMSHRs), numTarget(numTargets), writeBuffers(write_buffers), - writeAllocate(write_allocate), order(0), prefetchMiss(prefetch_miss) + order(0), prefetchMiss(prefetch_miss) { noTargetMSHR = NULL; } + +MissQueue::~MissQueue() +{ +} + + void MissQueue::regStats(const string &name) { + MissBuffer::regStats(name); + Request temp_req((Addr) NULL, 4, 0); Packet::Command temp_cmd = Packet::ReadReq; Packet temp_pkt(&temp_req, temp_cmd, 0); //@todo FIx command strings so this isn't neccessary @@ -65,13 +74,6 @@ MissQueue::regStats(const string &name) using namespace Stats; - writebacks - .init(maxThreadsPerCPU) - .name(name + ".writebacks") - .desc("number of writebacks") - .flags(total) - ; - // MSHR hit statistics for (int access_idx = 0; access_idx < NUM_MEM_CMDS; ++access_idx) { Packet::Command cmd = (Packet::Command)access_idx; @@ -336,18 +338,6 @@ MissQueue::regStats(const string &name) } -void -MissQueue::setCache(BaseCache *_cache) -{ - cache = _cache; - blkSize = cache->getBlockSize(); -} - -void -MissQueue::setPrefetcher(BasePrefetcher *_prefetcher) -{ - prefetcher = _prefetcher; -} MSHR* MissQueue::allocateMiss(PacketPtr &pkt, int size, Tick time) @@ -706,13 +696,13 @@ MissQueue::squash(int threadNum) } MSHR* -MissQueue::findMSHR(Addr addr) const +MissQueue::findMSHR(Addr addr) { return mq.findMatch(addr); } bool -MissQueue::findWrites(Addr addr, vector<MSHR*> &writes) const +MissQueue::findWrites(Addr addr, vector<MSHR*> &writes) { return wb.findMatches(addr,writes); } diff --git a/src/mem/cache/miss/miss_queue.hh b/src/mem/cache/miss/miss_queue.hh index b67a896f4..1f9bb1e0c 100644 --- a/src/mem/cache/miss/miss_queue.hh +++ b/src/mem/cache/miss/miss_queue.hh @@ -38,19 +38,18 @@ #include <vector> +#include "mem/cache/miss/miss_buffer.hh" #include "mem/cache/miss/mshr.hh" #include "mem/cache/miss/mshr_queue.hh" #include "base/statistics.hh" -class BaseCache; -class BasePrefetcher; /** * Manages cache misses and writebacks. Contains MSHRs to store miss data * and the writebuffer for writes/writebacks. * @todo need to handle data on writes better (encapsulate). * @todo need to make replacements/writebacks happen in Cache::access */ -class MissQueue +class MissQueue : public MissBuffer { protected: /** The MSHRs. */ @@ -66,16 +65,6 @@ class MissQueue const int numTarget; /** The number of write buffers. */ const int writeBuffers; - /** True if the cache should allocate on a write miss. */ - const bool writeAllocate; - /** Pointer to the parent cache. */ - BaseCache* cache; - - /** The Prefetcher */ - BasePrefetcher *prefetcher; - - /** The block size of the parent cache. */ - int blkSize; /** Increasing order number assigned to each incoming request. */ uint64_t order; @@ -87,9 +76,6 @@ class MissQueue * @addtogroup CacheStatistics * @{ */ - /** Number of blocks written back per thread. */ - Stats::Vector<> writebacks; - /** Number of misses that hit in the MSHRs per command and thread. */ Stats::Vector<> mshr_hits[NUM_MEM_CMDS]; /** Demand misses that hit in the MSHRs. */ @@ -204,14 +190,6 @@ class MissQueue void regStats(const std::string &name); /** - * Called by the parent cache to set the back pointer. - * @param _cache A pointer to the parent cache. - */ - void setCache(BaseCache *_cache); - - void setPrefetcher(BasePrefetcher *_prefetcher); - - /** * Handle a cache miss properly. Either allocate an MSHR for the request, * or forward it through the write buffer. * @param pkt The request that missed in the cache. @@ -289,7 +267,7 @@ class MissQueue * @warning Currently only searches the miss queue. If non write allocate * might need to search the write buffer for coherence. */ - MSHR* findMSHR(Addr addr) const; + MSHR* findMSHR(Addr addr); /** * Searches for the supplied address in the write buffer. @@ -298,7 +276,7 @@ class MissQueue * @param writes The list of writes that match the address. * @return True if any writes are found */ - bool findWrites(Addr addr, std::vector<MSHR*>& writes) const; + bool findWrites(Addr addr, std::vector<MSHR*>& writes); /** * Perform a writeback of dirty data to the given address. diff --git a/src/mem/cache/prefetch/ghb_prefetcher.cc b/src/mem/cache/prefetch/ghb_prefetcher.cc index 247ec6e8b..a6c419113 100644 --- a/src/mem/cache/prefetch/ghb_prefetcher.cc +++ b/src/mem/cache/prefetch/ghb_prefetcher.cc @@ -38,17 +38,11 @@ #include "mem/cache/tags/lru.hh" -#include "base/compression/null_compression.hh" - -#include "mem/cache/miss/miss_queue.hh" -#include "mem/cache/miss/blocking_buffer.hh" - #include "mem/cache/prefetch/ghb_prefetcher.hh" // Template Instantiations #ifndef DOXYGEN_SHOULD_SKIP_THIS -template class GHBPrefetcher<CacheTags<LRU,NullCompression>, MissQueue>; -template class GHBPrefetcher<CacheTags<LRU,NullCompression>, BlockingBuffer>; +template class GHBPrefetcher<CacheTags<LRU> >; #endif //DOXYGEN_SHOULD_SKIP_THIS diff --git a/src/mem/cache/prefetch/ghb_prefetcher.hh b/src/mem/cache/prefetch/ghb_prefetcher.hh index 14f5747df..c558a3e64 100644 --- a/src/mem/cache/prefetch/ghb_prefetcher.hh +++ b/src/mem/cache/prefetch/ghb_prefetcher.hh @@ -43,16 +43,16 @@ /** * A template-policy based cache. The behavior of the cache can be altered by * supplying different template policies. TagStore handles all tag and data - * storage @sa TagStore. Buffering handles all misses and writes/writebacks + * storage @sa TagStore. MissBuffer handles all misses and writes/writebacks * @sa MissQueue. Coherence handles all coherence policy details @sa * UniCoherence, SimpleMultiCoherence. */ -template <class TagStore, class Buffering> -class GHBPrefetcher : public Prefetcher<TagStore, Buffering> +template <class TagStore> +class GHBPrefetcher : public Prefetcher<TagStore> { protected: - Buffering* mq; + MissBuffer* mq; TagStore* tags; Addr second_last_miss_addr[64/*MAX_CPUS*/]; @@ -67,7 +67,7 @@ class GHBPrefetcher : public Prefetcher<TagStore, Buffering> GHBPrefetcher(int size, bool pageStop, bool serialSquash, bool cacheCheckPush, bool onlyData, Tick latency, int degree, bool useCPUId) - :Prefetcher<TagStore, Buffering>(size, pageStop, serialSquash, + :Prefetcher<TagStore>(size, pageStop, serialSquash, cacheCheckPush, onlyData), latency(latency), degree(degree), useCPUId(useCPUId) { diff --git a/src/mem/cache/prefetch/stride_prefetcher.cc b/src/mem/cache/prefetch/stride_prefetcher.cc index 93a096468..2204871cc 100644 --- a/src/mem/cache/prefetch/stride_prefetcher.cc +++ b/src/mem/cache/prefetch/stride_prefetcher.cc @@ -38,17 +38,11 @@ #include "mem/cache/tags/lru.hh" -#include "base/compression/null_compression.hh" - -#include "mem/cache/miss/miss_queue.hh" -#include "mem/cache/miss/blocking_buffer.hh" - #include "mem/cache/prefetch/stride_prefetcher.hh" // Template Instantiations #ifndef DOXYGEN_SHOULD_SKIP_THIS -template class StridePrefetcher<CacheTags<LRU,NullCompression>, MissQueue>; -template class StridePrefetcher<CacheTags<LRU,NullCompression>, BlockingBuffer>; +template class StridePrefetcher<CacheTags<LRU> >; #endif //DOXYGEN_SHOULD_SKIP_THIS diff --git a/src/mem/cache/prefetch/stride_prefetcher.hh b/src/mem/cache/prefetch/stride_prefetcher.hh index d6fb8ab66..57e430400 100644 --- a/src/mem/cache/prefetch/stride_prefetcher.hh +++ b/src/mem/cache/prefetch/stride_prefetcher.hh @@ -43,16 +43,16 @@ /** * A template-policy based cache. The behavior of the cache can be altered by * supplying different template policies. TagStore handles all tag and data - * storage @sa TagStore. Buffering handles all misses and writes/writebacks + * storage @sa TagStore. MissBuffer handles all misses and writes/writebacks * @sa MissQueue. Coherence handles all coherence policy details @sa * UniCoherence, SimpleMultiCoherence. */ -template <class TagStore, class Buffering> -class StridePrefetcher : public Prefetcher<TagStore, Buffering> +template <class TagStore> +class StridePrefetcher : public Prefetcher<TagStore> { protected: - Buffering* mq; + MissBuffer* mq; TagStore* tags; class strideEntry @@ -84,7 +84,7 @@ class StridePrefetcher : public Prefetcher<TagStore, Buffering> StridePrefetcher(int size, bool pageStop, bool serialSquash, bool cacheCheckPush, bool onlyData, Tick latency, int degree, bool useCPUId) - :Prefetcher<TagStore, Buffering>(size, pageStop, serialSquash, + :Prefetcher<TagStore>(size, pageStop, serialSquash, cacheCheckPush, onlyData), latency(latency), degree(degree), useCPUId(useCPUId) { diff --git a/src/mem/cache/prefetch/tagged_prefetcher.hh b/src/mem/cache/prefetch/tagged_prefetcher.hh index b61e57dcc..dc2aaec50 100644 --- a/src/mem/cache/prefetch/tagged_prefetcher.hh +++ b/src/mem/cache/prefetch/tagged_prefetcher.hh @@ -41,16 +41,16 @@ /** * A template-policy based cache. The behavior of the cache can be altered by * supplying different template policies. TagStore handles all tag and data - * storage @sa TagStore. Buffering handles all misses and writes/writebacks + * storage @sa TagStore. MissBuffer handles all misses and writes/writebacks * @sa MissQueue. Coherence handles all coherence policy details @sa * UniCoherence, SimpleMultiCoherence. */ -template <class TagStore, class Buffering> -class TaggedPrefetcher : public Prefetcher<TagStore, Buffering> +template <class TagStore> +class TaggedPrefetcher : public Prefetcher<TagStore> { protected: - Buffering* mq; + MissBuffer* mq; TagStore* tags; Tick latency; diff --git a/src/mem/cache/prefetch/tagged_prefetcher_impl.hh b/src/mem/cache/prefetch/tagged_prefetcher_impl.hh index a18de4571..b3d4284c7 100644 --- a/src/mem/cache/prefetch/tagged_prefetcher_impl.hh +++ b/src/mem/cache/prefetch/tagged_prefetcher_impl.hh @@ -36,20 +36,20 @@ #include "arch/isa_traits.hh" #include "mem/cache/prefetch/tagged_prefetcher.hh" -template <class TagStore, class Buffering> -TaggedPrefetcher<TagStore, Buffering>:: +template <class TagStore> +TaggedPrefetcher<TagStore>:: TaggedPrefetcher(int size, bool pageStop, bool serialSquash, bool cacheCheckPush, bool onlyData, Tick latency, int degree) - :Prefetcher<TagStore, Buffering>(size, pageStop, serialSquash, + :Prefetcher<TagStore>(size, pageStop, serialSquash, cacheCheckPush, onlyData), latency(latency), degree(degree) { } -template <class TagStore, class Buffering> +template <class TagStore> void -TaggedPrefetcher<TagStore, Buffering>:: +TaggedPrefetcher<TagStore>:: calculatePrefetch(PacketPtr &pkt, std::list<Addr> &addresses, std::list<Tick> &delays) { diff --git a/src/python/m5/objects/Repl.py b/src/python/m5/objects/Repl.py index 10892cf6f..b76aa1d6e 100644 --- a/src/python/m5/objects/Repl.py +++ b/src/python/m5/objects/Repl.py @@ -6,6 +6,6 @@ class Repl(SimObject): class GenRepl(Repl): type = 'GenRepl' - fresh_res = Param.Int("associativity") - num_pools = Param.Int("capacity in bytes") - pool_res = Param.Int("block size in bytes") + fresh_res = Param.Int("Fresh pool residency time") + num_pools = Param.Int("Number of priority pools") + pool_res = Param.Int("Pool residency time") diff --git a/src/python/m5/objects/Tsunami.py b/src/python/m5/objects/Tsunami.py index c18210bba..ac9020b47 100644 --- a/src/python/m5/objects/Tsunami.py +++ b/src/python/m5/objects/Tsunami.py @@ -36,7 +36,7 @@ class Tsunami(Platform): fake_uart3 = IsaFake(pio_addr=0x801fc0002e8) fake_uart4 = IsaFake(pio_addr=0x801fc0003f0) - fake_ppc = IsaFake(pio_addr=0x801fc0003bc) + fake_ppc = IsaFake(pio_addr=0x801fc0003bb) fake_OROM = IsaFake(pio_addr=0x800000a0000, pio_size=0x60000) diff --git a/src/python/m5/params.py b/src/python/m5/params.py index 9e5f985c3..d83d5f73f 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -237,6 +237,12 @@ class NumericParamValue(ParamValue): def __float__(self): return float(self.value) + def __long__(self): + return long(self.value) + + def __int__(self): + return int(self.value) + # hook for bounds checking def _check(self): return @@ -308,8 +314,11 @@ class CheckedInt(NumericParamValue): def __init__(self, value): if isinstance(value, str): self.value = convert.toInteger(value) - elif isinstance(value, (int, long, float)): + elif isinstance(value, (int, long, float, NumericParamValue)): self.value = long(value) + else: + raise TypeError, "Can't convert object of type %s to CheckedInt" \ + % type(value).__name__ self._check() class Int(CheckedInt): cxx_type = 'int'; size = 32; unsigned = False |