From 4862879a9420c52d48532d957b616c458b643a1e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 02:08:44 -0500 Subject: Put the Alpha tlb stuff into the AlphaISA namespace, and give the classes more neutral names. --HG-- extra : convert_revision : 702c715b7516a16602172deb1b78d6a7ab848fd4 --- src/arch/alpha/tlb.cc | 926 +++++++++++++++++++++++----------------------- src/arch/alpha/tlb.hh | 158 ++++---- src/cpu/simple/atomic.cc | 4 +- src/cpu/simple/base.hh | 11 +- src/cpu/simple/timing.cc | 4 +- src/cpu/simple_thread.cc | 2 +- src/cpu/simple_thread.hh | 10 +- src/cpu/thread_context.hh | 17 +- 8 files changed, 573 insertions(+), 559 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index bab44c434..ae302e686 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -46,589 +46,591 @@ using namespace std; using namespace EV5; -/////////////////////////////////////////////////////////////////////// -// -// Alpha TLB -// +namespace AlphaISA +{ + /////////////////////////////////////////////////////////////////////// + // + // Alpha TLB + // #ifdef DEBUG -bool uncacheBit39 = false; -bool uncacheBit40 = false; + bool uncacheBit39 = false; + bool uncacheBit40 = false; #endif #define MODE2MASK(X) (1 << (X)) -AlphaTLB::AlphaTLB(const string &name, int s) - : SimObject(name), size(s), nlu(0) -{ - table = new AlphaISA::PTE[size]; - memset(table, 0, sizeof(AlphaISA::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])); + } -AlphaTLB::~AlphaTLB() -{ - if (table) - delete [] table; -} + TLB::~TLB() + { + if (table) + delete [] table; + } -// look up an entry in the TLB -AlphaISA::PTE * -AlphaTLB::lookup(Addr vpn, uint8_t asn) const -{ - // assume not found... - AlphaISA::PTE *retval = NULL; + // look up an entry in the TLB + PTE * + TLB::lookup(Addr vpn, uint8_t asn) const + { + // assume not found... + PTE *retval = NULL; + + 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; + } - PageTable::const_iterator i = lookupTable.find(vpn); - if (i != lookupTable.end()) { - while (i->first == vpn) { - int index = i->second; - AlphaISA::PTE *pte = &table[index]; - assert(pte->valid); - if (vpn == pte->tag && (pte->asma || pte->asn == asn)) { - retval = pte; - break; + ++i; } - - ++i; } - } - DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, - retval ? "hit" : "miss", retval ? retval->ppn : 0); - return retval; -} + DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, + retval ? "hit" : "miss", retval ? retval->ppn : 0); + return retval; + } -Fault -AlphaTLB::checkCacheability(RequestPtr &req) -{ - // in Alpha, cacheability is controlled by upper-level bits of the - // physical address + 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. - */ + /* + * 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 -AlphaTLB::insert(Addr addr, AlphaISA::PTE &pte) -{ - AlphaISA::VAddr vaddr = addr; - if (table[nlu].valid) { - Addr oldvpn = table[nlu].tag; - PageTable::iterator i = lookupTable.find(oldvpn); + // insert a new TLB entry + void + TLB::insert(Addr addr, PTE &pte) + { + VAddr vaddr = addr; + if (table[nlu].valid) { + Addr oldvpn = table[nlu].tag; + PageTable::iterator i = lookupTable.find(oldvpn); - if (i == lookupTable.end()) - panic("TLB entry not found in lookupTable"); - - int index; - while ((index = i->second) != nlu) { - if (table[index].tag != oldvpn) + if (i == lookupTable.end()) panic("TLB entry not found in lookupTable"); - ++i; + int index; + while ((index = i->second) != nlu) { + if (table[index].tag != oldvpn) + panic("TLB entry not found in lookupTable"); + + ++i; + } + + DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); + + lookupTable.erase(i); } - DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); + DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn); - lookupTable.erase(i); - } + table[nlu] = pte; + table[nlu].tag = vaddr.vpn(); + table[nlu].valid = true; - DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn); + lookupTable.insert(make_pair(vaddr.vpn(), nlu)); + nextnlu(); + } - table[nlu] = pte; - table[nlu].tag = vaddr.vpn(); - table[nlu].valid = true; + void + TLB::flushAll() + { + DPRINTF(TLB, "flushAll\n"); + memset(table, 0, sizeof(PTE[size])); + lookupTable.clear(); + nlu = 0; + } - lookupTable.insert(make_pair(vaddr.vpn(), nlu)); - nextnlu(); -} + 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); -void -AlphaTLB::flushAll() -{ - DPRINTF(TLB, "flushAll\n"); - memset(table, 0, sizeof(AlphaISA::PTE[size])); - lookupTable.clear(); - nlu = 0; -} + // 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; -void -AlphaTLB::flushProcesses() -{ - PageTable::iterator i = lookupTable.begin(); - PageTable::iterator end = lookupTable.end(); - while (i != end) { - int index = i->second; - AlphaISA::PTE *pte = &table[index]; - assert(pte->valid); - - // we can't increment i after we erase it, so save a copy and - // increment it to get the next entry now - PageTable::iterator cur = i; - ++i; - - if (!pte->asma) { - DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); - pte->valid = false; - lookupTable.erase(cur); + if (!pte->asma) { + DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); + pte->valid = false; + lookupTable.erase(cur); + } } } -} -void -AlphaTLB::flushAddr(Addr addr, uint8_t asn) -{ - AlphaISA::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; - AlphaISA::PTE *pte = &table[index]; - assert(pte->valid); + 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); + if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) { + DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(), + pte->ppn); - // invalidate this entry - pte->valid = false; + // invalidate this entry + pte->valid = false; - lookupTable.erase(i); - } + lookupTable.erase(i); + } - ++i; + ++i; + } } -} -void -AlphaTLB::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 -AlphaTLB::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 -// -AlphaITB::AlphaITB(const std::string &name, int size) - : AlphaTLB(name, size) -{} - -void -AlphaITB::regStats() -{ - hits - .name(name() + ".hits") - .desc("ITB hits"); - misses - .name(name() + ".misses") - .desc("ITB misses"); - acv - .name(name() + ".acv") - .desc("ITB acv"); - accesses - .name(name() + ".accesses") - .desc("ITB accesses"); - - accesses = hits + misses; -} - - -Fault -AlphaITB::translate(RequestPtr &req, ThreadContext *tc) const -{ - if (AlphaISA::PcPAL(req->getVaddr())) { - // strip off PAL PC marker (lsb is 1) - req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask); - hits++; - return NoFault; + /////////////////////////////////////////////////////////////////////// + // + // 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; } - 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->getVaddr())) { + // 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(AlphaISA::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(AlphaISA::IPR_ICM)) != - AlphaISA::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(AlphaISA::IPR_DTB_ASN)); - AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(), - asn); - - if (!pte) { - misses++; - return new ItbPageFault(req->getVaddr()); - } + } 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 << AlphaISA::PageShift) + - (AlphaISA::VAddr(req->getVaddr()).offset() - & ~3)); + req->setPaddr((pte->ppn << PageShift) + + (VAddr(req->getVaddr()).offset() + & ~3)); - // check permissions for this access - if (!(pte->xre & - (1 << ICM_CM(tc->readMiscReg(AlphaISA::IPR_ICM))))) { - // instruction access fault - acv++; - return new ItbAcvFault(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()); + } - hits++; + hits++; + } } - } - - // check that the physical address is ok (catch bad physical addresses) - if (req->getPaddr() & ~PAddrImplMask) - return genMachineCheckFault(); - return checkCacheability(req); - -} + // check that the physical address is ok (catch bad physical addresses) + if (req->getPaddr() & ~PAddrImplMask) + return genMachineCheckFault(); -/////////////////////////////////////////////////////////////////////// -// -// Alpha DTB -// -AlphaDTB::AlphaDTB(const std::string &name, int size) - : AlphaTLB(name, size) -{} + return checkCacheability(req); -void -AlphaDTB::regStats() -{ - read_hits - .name(name() + ".read_hits") - .desc("DTB read hits") - ; - - read_misses - .name(name() + ".read_misses") - .desc("DTB read misses") - ; - - read_acv - .name(name() + ".read_acv") - .desc("DTB read access violations") - ; - - read_accesses - .name(name() + ".read_accesses") - .desc("DTB read accesses") - ; - - write_hits - .name(name() + ".write_hits") - .desc("DTB write hits") - ; - - write_misses - .name(name() + ".write_misses") - .desc("DTB write misses") - ; - - write_acv - .name(name() + ".write_acv") - .desc("DTB write access violations") - ; - - write_accesses - .name(name() + ".write_accesses") - .desc("DTB write accesses") - ; - - hits - .name(name() + ".hits") - .desc("DTB hits") - ; - - misses - .name(name() + ".misses") - .desc("DTB misses") - ; - - acv - .name(name() + ".acv") - .desc("DTB access violations") - ; - - accesses - .name(name() + ".accesses") - .desc("DTB accesses") - ; - - hits = read_hits + write_hits; - misses = read_misses + write_misses; - acv = read_acv + write_acv; - accesses = read_accesses + write_accesses; -} + } -Fault -AlphaDTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const -{ - Addr pc = tc->readPC(); + /////////////////////////////////////////////////////////////////////// + // + // 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; + } - AlphaISA::mode_type mode = - (AlphaISA::mode_type)DTB_CM_CM(tc->readMiscReg(AlphaISA::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) ? - (AlphaISA::mode_type)ALT_MODE_AM( - tc->readMiscReg(AlphaISA::IPR_ALT_MODE)) - : AlphaISA::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 (pc & 0x1) { + 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(AlphaISA::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(AlphaISA::IPR_DTB_CM)) != - AlphaISA::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(AlphaISA::IPR_DTB_ASN)); - - // not a physical address: need to look up pte - AlphaISA::PTE *pte = lookup(AlphaISA::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 << AlphaISA::PageShift) + - AlphaISA::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 (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->fonr) { - read_acv++; - uint64_t flags = MM_STAT_FONR_MASK; - return new DtbPageFault(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 (write) + write_hits++; + else + read_hits++; } - 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); } - // check that the physical address is ok (catch bad physical addresses) - if (req->getPaddr() & ~PAddrImplMask) - return genMachineCheckFault(); + PTE & + TLB::index(bool advance) + { + PTE *pte = &table[nlu]; - return checkCacheability(req); -} + if (advance) + nextnlu(); -AlphaISA::PTE & -AlphaTLB::index(bool advance) -{ - AlphaISA::PTE *pte = &table[nlu]; + return *pte; + } - if (advance) - nextnlu(); + DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", TLB) - return *pte; -} + BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITB) -DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", AlphaTLB) + Param size; -BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaITB) + END_DECLARE_SIM_OBJECT_PARAMS(ITB) - Param size; + BEGIN_INIT_SIM_OBJECT_PARAMS(ITB) -END_DECLARE_SIM_OBJECT_PARAMS(AlphaITB) + INIT_PARAM_DFLT(size, "TLB size", 48) -BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaITB) + END_INIT_SIM_OBJECT_PARAMS(ITB) - INIT_PARAM_DFLT(size, "TLB size", 48) - -END_INIT_SIM_OBJECT_PARAMS(AlphaITB) + CREATE_SIM_OBJECT(ITB) + { + return new ITB(getInstanceName(), size); + } -CREATE_SIM_OBJECT(AlphaITB) -{ - return new AlphaITB(getInstanceName(), size); -} + REGISTER_SIM_OBJECT("AlphaITB", ITB) -REGISTER_SIM_OBJECT("AlphaITB", AlphaITB) + BEGIN_DECLARE_SIM_OBJECT_PARAMS(DTB) -BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB) + Param size; - Param size; + END_DECLARE_SIM_OBJECT_PARAMS(DTB) -END_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB) + BEGIN_INIT_SIM_OBJECT_PARAMS(DTB) -BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDTB) + INIT_PARAM_DFLT(size, "TLB size", 64) - INIT_PARAM_DFLT(size, "TLB size", 64) + END_INIT_SIM_OBJECT_PARAMS(DTB) -END_INIT_SIM_OBJECT_PARAMS(AlphaDTB) + CREATE_SIM_OBJECT(DTB) + { + return new DTB(getInstanceName(), size); + } -CREATE_SIM_OBJECT(AlphaDTB) -{ - return new AlphaDTB(getInstanceName(), size); + REGISTER_SIM_OBJECT("AlphaDTB", DTB) } - -REGISTER_SIM_OBJECT("AlphaDTB", AlphaDTB) - diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index 955460649..ea5ba5539 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -36,6 +36,7 @@ #include "arch/alpha/ev5.hh" #include "arch/alpha/isa_traits.hh" +#include "arch/alpha/pagetable.hh" #include "arch/alpha/utility.hh" #include "arch/alpha/vtophys.hh" #include "base/statistics.hh" @@ -45,82 +46,87 @@ class ThreadContext; -class AlphaTLB : public SimObject +namespace AlphaISA { - protected: - typedef std::multimap PageTable; - PageTable lookupTable; // Quick lookup into page table - - AlphaISA::PTE *table; // the Page Table - int size; // TLB Size - int nlu; // not last used entry (for replacement) - - void nextnlu() { if (++nlu >= size) nlu = 0; } - AlphaISA::PTE *lookup(Addr vpn, uint8_t asn) const; - - public: - AlphaTLB(const std::string &name, int size); - virtual ~AlphaTLB(); - - int getsize() const { return size; } - - AlphaISA::PTE &index(bool advance = true); - void insert(Addr vaddr, AlphaISA::PTE &pte); - - void flushAll(); - void flushProcesses(); - void flushAddr(Addr addr, uint8_t asn); - - // static helper functions... really EV5 VM traits - static bool validVirtualAddress(Addr vaddr) { - // unimplemented bits must be all 0 or all 1 - Addr unimplBits = vaddr & EV5::VAddrUnImplMask; - return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask); - } - - static Fault checkCacheability(RequestPtr &req); - - // Checkpointing - virtual void serialize(std::ostream &os); - virtual void unserialize(Checkpoint *cp, const std::string §ion); -}; - -class AlphaITB : public AlphaTLB -{ - protected: - mutable Stats::Scalar<> hits; - mutable Stats::Scalar<> misses; - mutable Stats::Scalar<> acv; - mutable Stats::Formula accesses; - - public: - AlphaITB(const std::string &name, int size); - virtual void regStats(); - - Fault translate(RequestPtr &req, ThreadContext *tc) const; -}; - -class AlphaDTB : public AlphaTLB -{ - protected: - mutable Stats::Scalar<> read_hits; - mutable Stats::Scalar<> read_misses; - mutable Stats::Scalar<> read_acv; - mutable Stats::Scalar<> read_accesses; - mutable Stats::Scalar<> write_hits; - mutable Stats::Scalar<> write_misses; - mutable Stats::Scalar<> write_acv; - mutable Stats::Scalar<> write_accesses; - Stats::Formula hits; - Stats::Formula misses; - Stats::Formula acv; - Stats::Formula accesses; - - public: - AlphaDTB(const std::string &name, int size); - virtual void regStats(); - - Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const; -}; + class PTE; + + class TLB : public SimObject + { + protected: + typedef std::multimap PageTable; + PageTable lookupTable; // Quick lookup into page table + + PTE *table; // the Page Table + int size; // TLB Size + int nlu; // not last used entry (for replacement) + + void nextnlu() { if (++nlu >= size) nlu = 0; } + PTE *lookup(Addr vpn, uint8_t asn) const; + + public: + TLB(const std::string &name, int size); + virtual ~TLB(); + + int getsize() const { return size; } + + PTE &index(bool advance = true); + void insert(Addr vaddr, PTE &pte); + + void flushAll(); + void flushProcesses(); + void flushAddr(Addr addr, uint8_t asn); + + // static helper functions... really EV5 VM traits + static bool validVirtualAddress(Addr vaddr) { + // unimplemented bits must be all 0 or all 1 + Addr unimplBits = vaddr & EV5::VAddrUnImplMask; + return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask); + } + + static Fault checkCacheability(RequestPtr &req); + + // Checkpointing + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + }; + + class ITB : public TLB + { + protected: + mutable Stats::Scalar<> hits; + mutable Stats::Scalar<> misses; + mutable Stats::Scalar<> acv; + mutable Stats::Formula accesses; + + public: + ITB(const std::string &name, int size); + virtual void regStats(); + + Fault translate(RequestPtr &req, ThreadContext *tc) const; + }; + + class DTB : public TLB + { + protected: + mutable Stats::Scalar<> read_hits; + mutable Stats::Scalar<> read_misses; + mutable Stats::Scalar<> read_acv; + mutable Stats::Scalar<> read_accesses; + mutable Stats::Scalar<> write_hits; + mutable Stats::Scalar<> write_misses; + mutable Stats::Scalar<> write_acv; + mutable Stats::Scalar<> write_accesses; + Stats::Formula hits; + Stats::Formula misses; + Stats::Formula acv; + Stats::Formula accesses; + + public: + DTB(const std::string &name, int size); + virtual void regStats(); + + Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const; + }; +} #endif // __ALPHA_MEMORY_HH__ diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 11e4d2acb..1e12aadef 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -513,8 +513,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AtomicSimpleCPU) Param cpu_id; #if FULL_SYSTEM - SimObjectParam itb; - SimObjectParam dtb; + SimObjectParam itb; + SimObjectParam dtb; Param profile; #else SimObjectParam workload; diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index af6b6f835..1a9fc5127 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -47,8 +47,11 @@ // forward declarations #if FULL_SYSTEM class Processor; -class AlphaITB; -class AlphaDTB; +namespace TheISA +{ + class ITB; + class DTB; +} class MemObject; class RemoteGDB; @@ -97,8 +100,8 @@ class BaseSimpleCPU : public BaseCPU { MemObject *mem; #if FULL_SYSTEM - AlphaITB *itb; - AlphaDTB *dtb; + TheISA::ITB *itb; + TheISA::DTB *dtb; #else Process *process; #endif diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index fe6775ea4..438417882 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -665,8 +665,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TimingSimpleCPU) Param cpu_id; #if FULL_SYSTEM - SimObjectParam itb; - SimObjectParam dtb; + SimObjectParam itb; + SimObjectParam dtb; Param profile; #else SimObjectParam workload; diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 4fc47c982..95018ff8c 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -60,7 +60,7 @@ using namespace std; // constructor #if FULL_SYSTEM SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, - AlphaITB *_itb, AlphaDTB *_dtb, + TheISA::ITB *_itb, TheISA::DTB *_dtb, bool use_kernel_stats) : ThreadState(-1, _thread_num), cpu(_cpu), system(_sys), itb(_itb), dtb(_dtb) diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index fe22e6c43..10ec8faaa 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -107,14 +107,14 @@ class SimpleThread : public ThreadState System *system; #if FULL_SYSTEM - AlphaITB *itb; - AlphaDTB *dtb; + TheISA::ITB *itb; + TheISA::DTB *dtb; #endif // constructor: initialize SimpleThread from given process structure #if FULL_SYSTEM SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system, - AlphaITB *_itb, AlphaDTB *_dtb, + TheISA::ITB *_itb, TheISA::DTB *_dtb, bool use_kernel_stats = true); #else SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid, @@ -201,9 +201,9 @@ class SimpleThread : public ThreadState #if FULL_SYSTEM System *getSystemPtr() { return system; } - AlphaITB *getITBPtr() { return itb; } + TheISA::ITB *getITBPtr() { return itb; } - AlphaDTB *getDTBPtr() { return dtb; } + TheISA::DTB *getDTBPtr() { return dtb; } FunctionalPort *getPhysPort() { return physPort; } diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index 73046097d..448d67d02 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -31,9 +31,9 @@ #ifndef __CPU_THREAD_CONTEXT_HH__ #define __CPU_THREAD_CONTEXT_HH__ -#include "arch/types.hh" #include "arch/regfile.hh" #include "arch/syscallreturn.hh" +#include "arch/types.hh" #include "config/full_system.hh" #include "mem/request.hh" #include "sim/faults.hh" @@ -43,8 +43,11 @@ // @todo: Figure out a more architecture independent way to obtain the ITB and // DTB pointers. -class AlphaDTB; -class AlphaITB; +namespace TheISA +{ + class DTB; + class ITB; +} class BaseCPU; class EndQuiesceEvent; class Event; @@ -117,9 +120,9 @@ class ThreadContext #if FULL_SYSTEM virtual System *getSystemPtr() = 0; - virtual AlphaITB *getITBPtr() = 0; + virtual TheISA::ITB *getITBPtr() = 0; - virtual AlphaDTB * getDTBPtr() = 0; + virtual TheISA::DTB *getDTBPtr() = 0; virtual Kernel::Statistics *getKernelStats() = 0; @@ -292,9 +295,9 @@ class ProxyThreadContext : public ThreadContext #if FULL_SYSTEM System *getSystemPtr() { return actualTC->getSystemPtr(); } - AlphaITB *getITBPtr() { return actualTC->getITBPtr(); } + TheISA::ITB *getITBPtr() { return actualTC->getITBPtr(); } - AlphaDTB *getDTBPtr() { return actualTC->getDTBPtr(); } + TheISA::DTB *getDTBPtr() { return actualTC->getDTBPtr(); } Kernel::Statistics *getKernelStats() { return actualTC->getKernelStats(); } -- cgit v1.2.3 From 038217049a952a67f29b79c416a35d89fea31f70 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 03:37:01 -0500 Subject: Move IntrFlag into the MiscRegFile and get rid of specialized accessor functions. --HG-- extra : convert_revision : e0d12a150b01d05de9bc02bcbc7c22797975a5b9 --- src/arch/alpha/isa/decoder.isa | 8 ++++---- src/arch/alpha/isa/main.isa | 5 +++-- src/arch/alpha/isa_traits.hh | 3 ++- src/arch/alpha/regfile.hh | 2 ++ src/cpu/checker/cpu.hh | 2 -- src/cpu/exec_context.hh | 4 ---- src/cpu/o3/alpha/cpu.hh | 4 ---- src/cpu/o3/alpha/cpu_impl.hh | 14 -------------- src/cpu/o3/alpha/dyn_inst_impl.hh | 14 -------------- src/cpu/o3/regfile.hh | 6 ------ src/cpu/ozone/cpu.hh | 2 -- src/cpu/ozone/dyn_inst.hh | 2 -- src/cpu/ozone/dyn_inst_impl.hh | 14 -------------- src/cpu/simple/base.hh | 2 -- src/cpu/simple_thread.hh | 2 -- 15 files changed, 11 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 5bd19b677..93b941d72 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -661,12 +661,12 @@ decode OPCODE default Unknown::unknown() { #if FULL_SYSTEM format BasicOperate { 0xe000: rc({{ - Ra = xc->readIntrFlag(); - xc->setIntrFlag(0); + Ra = IntrFlag; + IntrFlag = 0; }}, IsNonSpeculative, IsUnverifiable); 0xf000: rs({{ - Ra = xc->readIntrFlag(); - xc->setIntrFlag(1); + Ra = IntrFlag; + IntrFlag = 1; }}, IsNonSpeculative, IsUnverifiable); } #else diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index 2024b1117..1df6ac603 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -183,8 +183,9 @@ def operands {{ 'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3), 'Mem': ('Mem', 'uq', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), 'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4), - 'Runiq': ('ControlReg', 'uq', 'TheISA::Uniq_DepTag', None, 1), - 'FPCR': (' ControlReg', 'uq', 'TheISA::Fpcr_DepTag', None, 1), + 'Runiq': ('ControlReg', 'uq', 'AlphaISA::Uniq_DepTag', None, 1), + 'FPCR': ('ControlReg', 'uq', 'AlphaISA::Fpcr_DepTag', None, 1), + 'IntrFlag': ('ControlReg', 'uq', 'AlphaISA::Intr_Flag_DepTag', None, 1), # The next two are hacks for non-full-system call-pal emulation 'R0': ('IntReg', 'uq', '0', None, 1), 'R16': ('IntReg', 'uq', '16', None, 1), diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh index 4f439b8df..66cb21235 100644 --- a/src/arch/alpha/isa_traits.hh +++ b/src/arch/alpha/isa_traits.hh @@ -54,7 +54,8 @@ namespace AlphaISA Uniq_DepTag = 73, Lock_Flag_DepTag = 74, Lock_Addr_DepTag = 75, - IPR_Base_DepTag = 76 + Intr_Flag_DepTag = 76, + IPR_Base_DepTag = 77 }; StaticInstPtr decodeInst(ExtMachInst); diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index 43b48a0ab..ea6fc67b2 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -109,6 +109,7 @@ namespace AlphaISA uint64_t uniq; // process-unique register bool lock_flag; // lock flag for LL/SC Addr lock_addr; // lock address for LL/SC + int intr_flag; public: MiscReg readReg(int misc_reg); @@ -131,6 +132,7 @@ namespace AlphaISA fpcr = uniq = 0; lock_flag = 0; lock_addr = 0; + intr_flag = 0; } void serialize(std::ostream &os); diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 00b01171f..7c01bdc39 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -328,8 +328,6 @@ class CheckerCPU : public BaseCPU #if FULL_SYSTEM Fault hwrei() { return thread->hwrei(); } - int readIntrFlag() { return thread->readIntrFlag(); } - void setIntrFlag(int val) { thread->setIntrFlag(val); } bool inPalMode() { return thread->inPalMode(); } void ev5_trap(Fault fault) { fault->invoke(tc); } bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh index f6e8d7c25..e28b33193 100644 --- a/src/cpu/exec_context.hh +++ b/src/cpu/exec_context.hh @@ -144,10 +144,6 @@ class ExecContext { /** Somewhat Alpha-specific function that handles returning from * an error or interrupt. */ Fault hwrei(); - /** Reads the interrupt flags. */ - int readIntrFlag(); - /** Sets the interrupt flags to a value. */ - void setIntrFlag(int val); /** * Check for special simulator handling of specific PAL calls. If diff --git a/src/cpu/o3/alpha/cpu.hh b/src/cpu/o3/alpha/cpu.hh index 9d97f9701..474fce02a 100644 --- a/src/cpu/o3/alpha/cpu.hh +++ b/src/cpu/o3/alpha/cpu.hh @@ -145,10 +145,6 @@ class AlphaO3CPU : public FullO3CPU #if FULL_SYSTEM /** Posts an interrupt. */ void post_interrupt(int int_num, int index); - /** Reads the interrupt flag. */ - int readIntrFlag(); - /** Sets the interrupt flags. */ - void setIntrFlag(int val); /** HW return from error interrupt. */ Fault hwrei(unsigned tid); /** Returns if a specific PC is a PAL mode PC. */ diff --git a/src/cpu/o3/alpha/cpu_impl.hh b/src/cpu/o3/alpha/cpu_impl.hh index b7362fad9..a57c5d9ed 100644 --- a/src/cpu/o3/alpha/cpu_impl.hh +++ b/src/cpu/o3/alpha/cpu_impl.hh @@ -241,20 +241,6 @@ AlphaO3CPU::post_interrupt(int int_num, int index) } } -template -int -AlphaO3CPU::readIntrFlag() -{ - return this->regFile.readIntrFlag(); -} - -template -void -AlphaO3CPU::setIntrFlag(int val) -{ - this->regFile.setIntrFlag(val); -} - template Fault AlphaO3CPU::hwrei(unsigned tid) diff --git a/src/cpu/o3/alpha/dyn_inst_impl.hh b/src/cpu/o3/alpha/dyn_inst_impl.hh index b273a7b9b..f27cd5961 100644 --- a/src/cpu/o3/alpha/dyn_inst_impl.hh +++ b/src/cpu/o3/alpha/dyn_inst_impl.hh @@ -127,20 +127,6 @@ AlphaDynInst::hwrei() return NoFault; } -template -int -AlphaDynInst::readIntrFlag() -{ - return this->cpu->readIntrFlag(); -} - -template -void -AlphaDynInst::setIntrFlag(int val) -{ - this->cpu->setIntrFlag(val); -} - template bool AlphaDynInst::inPalMode() diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh index 512cf0721..10f6db390 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -251,12 +251,6 @@ class PhysRegFile cpu->tcBase(thread_id)); } -#if FULL_SYSTEM - int readIntrFlag() { return intrflag; } - /** Sets an interrupt flag. */ - void setIntrFlag(int val) { intrflag = val; } -#endif - public: /** (signed) integer register file. */ IntReg *intRegFile; diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh index 70ec1d101..bd46b198b 100644 --- a/src/cpu/ozone/cpu.hh +++ b/src/cpu/ozone/cpu.hh @@ -583,8 +583,6 @@ class OzoneCPU : public BaseCPU #if FULL_SYSTEM Fault hwrei(); - int readIntrFlag() { return thread.intrflag; } - void setIntrFlag(int val) { thread.intrflag = val; } bool inPalMode() { return AlphaISA::PcPAL(thread.PC); } bool inPalMode(Addr pc) { return AlphaISA::PcPAL(pc); } bool simPalCheck(int palFunc); diff --git a/src/cpu/ozone/dyn_inst.hh b/src/cpu/ozone/dyn_inst.hh index e7390626e..d3871568a 100644 --- a/src/cpu/ozone/dyn_inst.hh +++ b/src/cpu/ozone/dyn_inst.hh @@ -238,8 +238,6 @@ class OzoneDynInst : public BaseDynInst #if FULL_SYSTEM Fault hwrei(); - int readIntrFlag(); - void setIntrFlag(int val); bool inPalMode(); void trap(Fault fault); bool simPalCheck(int palFunc); diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh index 9d42ab05b..d86f2dc8b 100644 --- a/src/cpu/ozone/dyn_inst_impl.hh +++ b/src/cpu/ozone/dyn_inst_impl.hh @@ -260,20 +260,6 @@ OzoneDynInst::hwrei() return NoFault; } -template -int -OzoneDynInst::readIntrFlag() -{ -return this->cpu->readIntrFlag(); -} - -template -void -OzoneDynInst::setIntrFlag(int val) -{ - this->cpu->setIntrFlag(val); -} - template bool OzoneDynInst::inPalMode() diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 1a9fc5127..1d208b8df 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -305,8 +305,6 @@ class BaseSimpleCPU : public BaseCPU #if FULL_SYSTEM Fault hwrei() { return thread->hwrei(); } - int readIntrFlag() { return thread->readIntrFlag(); } - void setIntrFlag(int val) { thread->setIntrFlag(val); } bool inPalMode() { return thread->inPalMode(); } void ev5_trap(Fault fault) { fault->invoke(tc); } bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 10ec8faaa..d005b2914 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -168,8 +168,6 @@ class SimpleThread : public ThreadState void dumpFuncProfile(); - int readIntrFlag() { return regs.intrflag; } - void setIntrFlag(int val) { regs.intrflag = val; } Fault hwrei(); bool simPalCheck(int palFunc); -- cgit v1.2.3 From eab445e1bc6178bdbd0f4b5fcd5746a84687de65 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 03:44:39 -0500 Subject: Get rid of old, commented out code. --HG-- extra : convert_revision : 46e9f26917efab642b80ea9e4303ec95d43d935e --- src/arch/sparc/faults.cc | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 2c8da44c5..567ca5f5c 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -359,21 +359,6 @@ void SparcFault::invoke(ThreadContext * tc) countStat()++; //Use the SPARC trap state machine - /*// exception restart address - if (setRestartAddress() || !tc->inPalMode()) - tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, tc->regs.pc); - - if (skipFaultingInstruction()) { - // traps... skip faulting instruction. - tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, - tc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); - } - - if (!tc->inPalMode()) - AlphaISA::swap_palshadow(&(tc->regs), true); - - tc->regs.pc = tc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect(); - tc->regs.npc = tc->regs.pc + sizeof(MachInst);*/ } #endif -- cgit v1.2.3 From 3c19c5f0f239b8d31a3a8acd03eff9923f19b6ee Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 04:12:52 -0500 Subject: Missed a few instances of this function. --HG-- extra : convert_revision : 581f97dafc2b30bd5067f6ff7f9cdbabc6890622 --- src/cpu/o3/alpha/dyn_inst.hh | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/cpu/o3/alpha/dyn_inst.hh b/src/cpu/o3/alpha/dyn_inst.hh index 294aadde8..31a6f7753 100644 --- a/src/cpu/o3/alpha/dyn_inst.hh +++ b/src/cpu/o3/alpha/dyn_inst.hh @@ -127,10 +127,6 @@ class AlphaDynInst : public BaseDynInst #if FULL_SYSTEM /** Calls hardware return from error interrupt. */ Fault hwrei(); - /** Reads interrupt flag. */ - int readIntrFlag(); - /** Sets interrupt flag. */ - void setIntrFlag(int val); /** Checks if system is in PAL mode. */ bool inPalMode(); /** Traps to handle specified fault. */ -- cgit v1.2.3 From b26355daa87c7a86a96a90b2002bc5684741288c Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 31 Oct 2006 13:59:30 -0500 Subject: Ports now have a pointer to the MemObject that owns it (can be NULL). src/cpu/simple/atomic.hh: Port now takes in the MemObject that owns it. src/cpu/simple/timing.hh: Port now takes in MemObject that owns it. src/dev/io_device.cc: src/mem/bus.hh: Ports now take in the MemObject that owns it. src/mem/cache/base_cache.cc: Ports now take in the MemObject that own it. src/mem/port.hh: src/mem/tport.hh: Ports now optionally take in the MemObject that owns it. --HG-- extra : convert_revision : 890a72a871795987c2236c65937e06973412d349 --- src/cpu/simple/atomic.hh | 2 +- src/cpu/simple/timing.hh | 4 +++- src/dev/io_device.cc | 6 +++--- src/mem/bus.hh | 2 +- src/mem/cache/base_cache.cc | 2 +- src/mem/port.hh | 31 ++++++++++++++++++++----------- src/mem/tport.hh | 4 ++-- 7 files changed, 31 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index 0edca9369..166a18127 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -87,7 +87,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU public: CpuPort(const std::string &_name, AtomicSimpleCPU *_cpu) - : Port(_name), cpu(_cpu) + : Port(_name, _cpu), cpu(_cpu) { } protected: diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh index 577e13e40..408fa315e 100644 --- a/src/cpu/simple/timing.hh +++ b/src/cpu/simple/timing.hh @@ -79,7 +79,7 @@ class TimingSimpleCPU : public BaseSimpleCPU public: CpuPort(const std::string &_name, TimingSimpleCPU *_cpu, Tick _lat) - : Port(_name), cpu(_cpu), lat(_lat) + : Port(_name, _cpu), cpu(_cpu), lat(_lat) { } protected: @@ -166,6 +166,8 @@ class TimingSimpleCPU : public BaseSimpleCPU PacketPtr ifetch_pkt; PacketPtr dcache_pkt; + + int cpu_id; Tick previousTick; diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index 9671d77cc..a1285fefc 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -37,7 +37,7 @@ PioPort::PioPort(PioDevice *dev, System *s, std::string pname) - : SimpleTimingPort(dev->name() + pname), device(dev) + : SimpleTimingPort(dev->name() + pname, dev), device(dev) { } @@ -92,8 +92,8 @@ BasicPioDevice::addressRanges(AddrRangeList &range_list) DmaPort::DmaPort(DmaDevice *dev, System *s) - : Port(dev->name() + "-dmaport"), device(dev), sys(s), pendingCount(0), - actionInProgress(0), drainEvent(NULL) + : Port(dev->name() + "-dmaport", dev), device(dev), sys(s), + pendingCount(0), actionInProgress(0), drainEvent(NULL) { } bool diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 9fb33b7c3..7ec7e6830 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -144,7 +144,7 @@ class Bus : public MemObject /** Constructor for the BusPort.*/ BusPort(const std::string &_name, Bus *_bus, int _id) - : Port(_name), _onRetryList(false), bus(_bus), id(_id) + : Port(_name, _bus), _onRetryList(false), bus(_bus), id(_id) { } bool onRetryList() diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 599958222..47d40a490 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -42,7 +42,7 @@ using namespace std; BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache, bool _isCpuSide) - : Port(_name), cache(_cache), isCpuSide(_isCpuSide) + : Port(_name, _cache), cache(_cache), isCpuSide(_isCpuSide) { blocked = false; waitingOnRetry = false; diff --git a/src/mem/port.hh b/src/mem/port.hh index b6eeb9db3..75afc04e6 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -58,6 +58,8 @@ typedef std::list > AddrRangeList; typedef std::list >::iterator AddrRangeIter; +class MemObject; + /** * Ports are used to interface memory objects to * each other. They will always come in pairs, and we refer to the other @@ -81,10 +83,13 @@ class Port memory objects. */ Port *peer; + /** A pointer to the MemObject that owns this port. This may not be set. */ + MemObject *owner; + public: Port() - : peer(NULL) + : peer(NULL), owner(NULL) { } /** @@ -92,9 +97,11 @@ class Port * * @param _name Port name for DPRINTF output. Should include name * of memory system object to which the port belongs. + * @param _owner Pointer to the MemObject that owns this port. + * Will not necessarily be set. */ - Port(const std::string &_name) - : portName(_name), peer(NULL) + Port(const std::string &_name, MemObject *_owner = NULL) + : portName(_name), peer(NULL), owner(_owner) { } /** Return port name (for DPRINTF). */ @@ -112,16 +119,18 @@ class Port void setName(const std::string &name) { portName = name; } - /** Function to set the pointer for the peer port. - @todo should be called by the configuration stuff (python). - */ + /** Function to set the pointer for the peer port. */ void setPeer(Port *port); - /** Function to set the pointer for the peer port. - @todo should be called by the configuration stuff (python). - */ + /** Function to get the pointer to the peer port. */ Port *getPeer() { return peer; } + /** Function to set the owner of this port. */ + void setOwner(MemObject *_owner) { owner = _owner; } + + /** Function to return the owner of this port. */ + MemObject *getOwner() { return owner; } + protected: /** These functions are protected because they should only be @@ -247,8 +256,8 @@ class Port class FunctionalPort : public Port { public: - FunctionalPort(const std::string &_name) - : Port(_name) + FunctionalPort(const std::string &_name, MemObject *_owner = NULL) + : Port(_name, _owner) {} protected: diff --git a/src/mem/tport.hh b/src/mem/tport.hh index fbe81c443..b419b7c7f 100644 --- a/src/mem/tport.hh +++ b/src/mem/tport.hh @@ -117,8 +117,8 @@ class SimpleTimingPort : public Port public: - SimpleTimingPort(std::string pname) - : Port(pname), outTiming(0), drainEvent(NULL) + SimpleTimingPort(std::string pname, MemObject *_owner = NULL) + : Port(pname, _owner), outTiming(0), drainEvent(NULL) {} /** Hook for draining timing accesses from the system. The -- cgit v1.2.3 From bfd5eb2b08dad700d085a637d5e16a61dcc530d7 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 31 Oct 2006 14:33:56 -0500 Subject: Remove mem parameter. Now the translating port asks the CPU's dcache's peer for its MemObject instead of having to have a paramter for the MemObject. configs/example/fs.py: configs/example/se.py: src/cpu/simple/base.cc: src/cpu/simple/base.hh: src/cpu/simple/timing.cc: src/cpu/simple_thread.cc: src/cpu/simple_thread.hh: src/cpu/thread_state.cc: src/cpu/thread_state.hh: tests/configs/o3-timing-mp.py: tests/configs/o3-timing.py: tests/configs/simple-atomic-mp.py: tests/configs/simple-atomic.py: tests/configs/simple-timing-mp.py: tests/configs/simple-timing.py: tests/configs/tsunami-simple-atomic-dual.py: tests/configs/tsunami-simple-atomic.py: tests/configs/tsunami-simple-timing-dual.py: tests/configs/tsunami-simple-timing.py: No need for mem parameter any more. src/cpu/checker/cpu.cc: Use new constructor for simple thread (no more MemObject parameter). src/cpu/checker/cpu.hh: Remove MemObject parameter. src/cpu/memtest/memtest.hh: Ports now take in their MemObject owner. src/cpu/o3/alpha/cpu_builder.cc: Remove mem parameter. src/cpu/o3/alpha/cpu_impl.hh: Remove memory parameter and clean up handling of TranslatingPort. src/cpu/o3/cpu.cc: src/cpu/o3/cpu.hh: src/cpu/o3/fetch.hh: src/cpu/o3/fetch_impl.hh: src/cpu/o3/mips/cpu_builder.cc: src/cpu/o3/mips/cpu_impl.hh: src/cpu/o3/params.hh: src/cpu/o3/thread_state.hh: src/cpu/ozone/cpu.hh: src/cpu/ozone/cpu_builder.cc: src/cpu/ozone/cpu_impl.hh: src/cpu/ozone/front_end.hh: src/cpu/ozone/front_end_impl.hh: src/cpu/ozone/lw_lsq.hh: src/cpu/ozone/lw_lsq_impl.hh: src/cpu/ozone/simple_params.hh: src/cpu/ozone/thread_state.hh: src/cpu/simple/atomic.cc: Remove memory parameter. --HG-- extra : convert_revision : 43cb44a33b31320d44b69679dcf646c0380d07d3 --- src/cpu/checker/cpu.cc | 20 ++++++------------- src/cpu/checker/cpu.hh | 4 ---- src/cpu/memtest/memtest.hh | 2 +- src/cpu/o3/alpha/cpu_builder.cc | 6 ------ src/cpu/o3/alpha/cpu_impl.hh | 18 ++--------------- src/cpu/o3/cpu.cc | 2 -- src/cpu/o3/cpu.hh | 3 --- src/cpu/o3/fetch.hh | 2 -- src/cpu/o3/fetch_impl.hh | 3 +-- src/cpu/o3/mips/cpu_builder.cc | 6 ------ src/cpu/o3/mips/cpu_impl.hh | 18 ++--------------- src/cpu/o3/params.hh | 2 -- src/cpu/o3/thread_state.hh | 7 +++---- src/cpu/ozone/cpu.hh | 2 -- src/cpu/ozone/cpu_builder.cc | 5 ----- src/cpu/ozone/cpu_impl.hh | 19 +++--------------- src/cpu/ozone/front_end.hh | 2 -- src/cpu/ozone/front_end_impl.hh | 1 - src/cpu/ozone/lw_lsq.hh | 2 -- src/cpu/ozone/lw_lsq_impl.hh | 2 -- src/cpu/ozone/simple_params.hh | 2 -- src/cpu/ozone/thread_state.hh | 6 +++--- src/cpu/simple/atomic.cc | 12 ------------ src/cpu/simple/base.cc | 4 ++-- src/cpu/simple/base.hh | 3 --- src/cpu/simple/timing.cc | 3 --- src/cpu/simple_thread.cc | 38 ++++++++++++++++++++++-------------- src/cpu/simple_thread.hh | 6 ++++-- src/cpu/thread_state.cc | 43 +++++++++++++++++++++++++++++++++++------ src/cpu/thread_state.hh | 14 +++++++++----- 30 files changed, 97 insertions(+), 160 deletions(-) (limited to 'src') diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc index 9cb6b032e..2e81b7b31 100644 --- a/src/cpu/checker/cpu.cc +++ b/src/cpu/checker/cpu.cc @@ -72,6 +72,12 @@ CheckerCPU::CheckerCPU(Params *p) systemPtr = NULL; #else process = p->process; + thread = new SimpleThread(this, /* thread_num */ 0, process, + /* asid */ 0); + + thread->setStatus(ThreadContext::Suspended); + tc = thread->getTC(); + threadContexts.push_back(tc); #endif result.integer = 0; @@ -81,20 +87,6 @@ CheckerCPU::~CheckerCPU() { } -void -CheckerCPU::setMemory(MemObject *mem) -{ -#if !FULL_SYSTEM - memPtr = mem; - thread = new SimpleThread(this, /* thread_num */ 0, process, - /* asid */ 0, mem); - - thread->setStatus(ThreadContext::Suspended); - tc = thread->getTC(); - threadContexts.push_back(tc); -#endif -} - void CheckerCPU::setSystem(System *system) { diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 00b01171f..336cb1714 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -112,10 +112,6 @@ class CheckerCPU : public BaseCPU Process *process; - void setMemory(MemObject *mem); - - MemObject *memPtr; - void setSystem(System *system); System *systemPtr; diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh index edde4a3b2..2694efd39 100644 --- a/src/cpu/memtest/memtest.hh +++ b/src/cpu/memtest/memtest.hh @@ -97,7 +97,7 @@ class MemTest : public MemObject public: CpuPort(const std::string &_name, MemTest *_memtest) - : Port(_name), memtest(_memtest) + : Port(_name, _memtest), memtest(_memtest) { } protected: diff --git a/src/cpu/o3/alpha/cpu_builder.cc b/src/cpu/o3/alpha/cpu_builder.cc index ff123a6f7..ca316433b 100644 --- a/src/cpu/o3/alpha/cpu_builder.cc +++ b/src/cpu/o3/alpha/cpu_builder.cc @@ -61,8 +61,6 @@ Param profile; SimObjectVectorParam workload; #endif // FULL_SYSTEM -SimObjectParam mem; - SimObjectParam checker; Param max_insts_any_thread; @@ -169,8 +167,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU) INIT_PARAM(workload, "Processes to run"), #endif // FULL_SYSTEM - INIT_PARAM(mem, "Memory"), - INIT_PARAM_DFLT(checker, "Checker CPU", NULL), INIT_PARAM_DFLT(max_insts_any_thread, @@ -314,8 +310,6 @@ CREATE_SIM_OBJECT(DerivO3CPU) params->workload = workload; #endif // FULL_SYSTEM - params->mem = mem; - params->checker = checker; params->max_insts_any_thread = max_insts_any_thread; diff --git a/src/cpu/o3/alpha/cpu_impl.hh b/src/cpu/o3/alpha/cpu_impl.hh index b7362fad9..5deee27de 100644 --- a/src/cpu/o3/alpha/cpu_impl.hh +++ b/src/cpu/o3/alpha/cpu_impl.hh @@ -77,24 +77,10 @@ AlphaO3CPU::AlphaO3CPU(Params *params) if (i < params->workload.size()) { DPRINTF(O3CPU, "Workload[%i] process is %#x", i, this->thread[i]); - this->thread[i] = new Thread(this, i, params->workload[i], - i, params->mem); + this->thread[i] = new Thread(this, i, params->workload[i], i); this->thread[i]->setStatus(ThreadContext::Suspended); -#if !FULL_SYSTEM - /* Use this port to for syscall emulation writes to memory. */ - Port *mem_port; - TranslatingPort *trans_port; - trans_port = new TranslatingPort(csprintf("%s-%d-funcport", - name(), i), - params->workload[i]->pTable, - false); - mem_port = params->mem->getPort("functional"); - mem_port->setPeer(trans_port); - trans_port->setPeer(mem_port); - this->thread[i]->setMemPort(trans_port); -#endif //usedTids[i] = true; //threadMap[i] = i; } else { @@ -102,7 +88,7 @@ AlphaO3CPU::AlphaO3CPU(Params *params) //when scheduling threads to CPU Process* dummy_proc = NULL; - this->thread[i] = new Thread(this, i, dummy_proc, i, params->mem); + this->thread[i] = new Thread(this, i, dummy_proc, i); //usedTids[i] = false; } #endif // !FULL_SYSTEM diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 367508288..dfe42d882 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -187,7 +187,6 @@ FullO3CPU::FullO3CPU(Params *params) system(params->system), physmem(system->physmem), #endif // FULL_SYSTEM - mem(params->mem), drainCount(0), deferRegistration(params->deferRegistration), numThreads(number_of_threads) @@ -204,7 +203,6 @@ FullO3CPU::FullO3CPU(Params *params) #if USE_CHECKER BaseCPU *temp_checker = params->checker; checker = dynamic_cast *>(temp_checker); - checker->setMemory(mem); #if FULL_SYSTEM checker->setSystem(params->system); #endif diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index fe510519c..2bf9cb23b 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -620,9 +620,6 @@ class FullO3CPU : public BaseO3CPU PhysicalMemory *physmem; #endif - /** Pointer to memory. */ - MemObject *mem; - /** Event to call process() on once draining has completed. */ Event *drainEvent; diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index 5555bff85..cc9a8abf5 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -329,8 +329,6 @@ class DefaultFetch /** Wire used to write any information heading to decode. */ typename TimeBuffer::wire toDecode; - MemObject *mem; - /** Icache interface. */ IcachePort *icachePort; diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index e7bf83b20..2b152e376 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -96,8 +96,7 @@ DefaultFetch::IcachePort::recvRetry() template DefaultFetch::DefaultFetch(Params *params) - : mem(params->mem), - branchPred(params), + : branchPred(params), decodeToFetchDelay(params->decodeToFetchDelay), renameToFetchDelay(params->renameToFetchDelay), iewToFetchDelay(params->iewToFetchDelay), diff --git a/src/cpu/o3/mips/cpu_builder.cc b/src/cpu/o3/mips/cpu_builder.cc index f1c3b33a5..ee9f2b48d 100644 --- a/src/cpu/o3/mips/cpu_builder.cc +++ b/src/cpu/o3/mips/cpu_builder.cc @@ -54,8 +54,6 @@ Param activity; SimObjectVectorParam workload; -SimObjectParam mem; - SimObjectParam checker; Param max_insts_any_thread; @@ -153,8 +151,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU) INIT_PARAM(workload, "Processes to run"), - INIT_PARAM(mem, "Memory"), - INIT_PARAM_DFLT(checker, "Checker CPU", NULL), INIT_PARAM_DFLT(max_insts_any_thread, @@ -284,8 +280,6 @@ CREATE_SIM_OBJECT(DerivO3CPU) params->workload = workload; - params->mem = mem; - params->checker = checker; params->max_insts_any_thread = max_insts_any_thread; diff --git a/src/cpu/o3/mips/cpu_impl.hh b/src/cpu/o3/mips/cpu_impl.hh index e08741626..97116fd3e 100644 --- a/src/cpu/o3/mips/cpu_impl.hh +++ b/src/cpu/o3/mips/cpu_impl.hh @@ -58,24 +58,10 @@ MipsO3CPU::MipsO3CPU(Params *params) if (i < params->workload.size()) { DPRINTF(O3CPU, "Workload[%i] process is %#x", i, this->thread[i]); - this->thread[i] = new Thread(this, i, params->workload[i], - i, params->mem); + this->thread[i] = new Thread(this, i, params->workload[i], i); this->thread[i]->setStatus(ThreadContext::Suspended); - - /* Use this port to for syscall emulation writes to memory. */ - Port *mem_port; - TranslatingPort *trans_port; - trans_port = new TranslatingPort(csprintf("%s-%d-funcport", - name(), i), - params->workload[i]->pTable, - false); - mem_port = params->mem->getPort("functional"); - mem_port->setPeer(trans_port); - trans_port->setPeer(mem_port); - this->thread[i]->setMemPort(trans_port); - //usedTids[i] = true; //threadMap[i] = i; } else { @@ -83,7 +69,7 @@ MipsO3CPU::MipsO3CPU(Params *params) //when scheduling threads to CPU Process* dummy_proc = NULL; - this->thread[i] = new Thread(this, i, dummy_proc, i, params->mem); + this->thread[i] = new Thread(this, i, dummy_proc, i); //usedTids[i] = false; } diff --git a/src/cpu/o3/params.hh b/src/cpu/o3/params.hh index 1c234bcd7..b487778c6 100755 --- a/src/cpu/o3/params.hh +++ b/src/cpu/o3/params.hh @@ -54,8 +54,6 @@ class O3Params : public BaseO3CPU::Params Process *process; #endif // FULL_SYSTEM - MemObject *mem; - BaseCPU *checker; // diff --git a/src/cpu/o3/thread_state.hh b/src/cpu/o3/thread_state.hh index 5fe7bb94d..d8720b3ab 100644 --- a/src/cpu/o3/thread_state.hh +++ b/src/cpu/o3/thread_state.hh @@ -77,7 +77,7 @@ struct O3ThreadState : public ThreadState { #if FULL_SYSTEM O3ThreadState(O3CPU *_cpu, int _thread_num) - : ThreadState(-1, _thread_num), + : ThreadState(_cpu, -1, _thread_num), cpu(_cpu), inSyscall(0), trapPending(0) { if (cpu->params->profile) { @@ -95,9 +95,8 @@ struct O3ThreadState : public ThreadState { profilePC = 3; } #else - O3ThreadState(O3CPU *_cpu, int _thread_num, Process *_process, int _asid, - MemObject *mem) - : ThreadState(-1, _thread_num, _process, _asid, mem), + O3ThreadState(O3CPU *_cpu, int _thread_num, Process *_process, int _asid) + : ThreadState(_cpu, -1, _thread_num, _process, _asid), cpu(_cpu), inSyscall(0), trapPending(0) { } #endif diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh index 70ec1d101..28ff8e9ba 100644 --- a/src/cpu/ozone/cpu.hh +++ b/src/cpu/ozone/cpu.hh @@ -368,8 +368,6 @@ class OzoneCPU : public BaseCPU virtual Port *getPort(const std::string &name, int idx); - MemObject *mem; - FrontEnd *frontEnd; BackEnd *backEnd; diff --git a/src/cpu/ozone/cpu_builder.cc b/src/cpu/ozone/cpu_builder.cc index 730158258..39be9fd74 100644 --- a/src/cpu/ozone/cpu_builder.cc +++ b/src/cpu/ozone/cpu_builder.cc @@ -69,8 +69,6 @@ SimObjectVectorParam workload; //SimObjectParam page_table; #endif // FULL_SYSTEM -SimObjectParam mem; - SimObjectParam checker; Param max_insts_any_thread; @@ -191,8 +189,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivOzoneCPU) // INIT_PARAM(page_table, "Page table"), #endif // FULL_SYSTEM - INIT_PARAM_DFLT(mem, "Memory", NULL), - INIT_PARAM_DFLT(checker, "Checker CPU", NULL), INIT_PARAM_DFLT(max_insts_any_thread, @@ -350,7 +346,6 @@ CREATE_SIM_OBJECT(DerivOzoneCPU) // params->pTable = page_table; #endif // FULL_SYSTEM - params->mem = mem; params->checker = checker; params->max_insts_any_thread = max_insts_any_thread; params->max_insts_all_threads = max_insts_all_threads; diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh index bf547bf94..685bf3cb4 100644 --- a/src/cpu/ozone/cpu_impl.hh +++ b/src/cpu/ozone/cpu_impl.hh @@ -93,10 +93,10 @@ OzoneCPU::OzoneCPU(Params *p) #if FULL_SYSTEM : BaseCPU(p), thread(this, 0), tickEvent(this, p->width), #else - : BaseCPU(p), thread(this, 0, p->workload[0], 0, p->mem), + : BaseCPU(p), thread(this, 0, p->workload[0], 0), tickEvent(this, p->width), #endif - mem(p->mem), comm(5, 5) + comm(5, 5) { frontEnd = new FrontEnd(p); backEnd = new BackEnd(p); @@ -107,7 +107,6 @@ OzoneCPU::OzoneCPU(Params *p) #if USE_CHECKER BaseCPU *temp_checker = p->checker; checker = dynamic_cast *>(temp_checker); - checker->setMemory(mem); #if FULL_SYSTEM checker->setSystem(p->system); #endif @@ -198,19 +197,7 @@ OzoneCPU::OzoneCPU(Params *p) frontEnd->renameTable.copyFrom(thread.renameTable); backEnd->renameTable.copyFrom(thread.renameTable); -#if !FULL_SYSTEM - /* Use this port to for syscall emulation writes to memory. */ - Port *mem_port; - TranslatingPort *trans_port; - trans_port = new TranslatingPort(csprintf("%s-%d-funcport", - name(), 0), - p->workload[0]->pTable, - false); - mem_port = p->mem->getPort("functional"); - mem_port->setPeer(trans_port); - trans_port->setPeer(mem_port); - thread.setMemPort(trans_port); -#else +#if FULL_SYSTEM Port *mem_port; FunctionalPort *phys_port; VirtualPort *virt_port; diff --git a/src/cpu/ozone/front_end.hh b/src/cpu/ozone/front_end.hh index 2bdca35b9..e09e4de9c 100644 --- a/src/cpu/ozone/front_end.hh +++ b/src/cpu/ozone/front_end.hh @@ -208,8 +208,6 @@ class FrontEnd IcachePort icachePort; - MemObject *mem; - RequestPtr memReq; /** Mask to get a cache block's address. */ diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh index 36e87ec9c..b8fce4292 100644 --- a/src/cpu/ozone/front_end_impl.hh +++ b/src/cpu/ozone/front_end_impl.hh @@ -91,7 +91,6 @@ template FrontEnd::FrontEnd(Params *params) : branchPred(params), icachePort(this), - mem(params->mem), numInstsReady(params->frontEndLatency, 0), instBufferSize(0), maxInstBufferSize(params->maxInstBufferSize), diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh index dc58a8285..7e6849668 100644 --- a/src/cpu/ozone/lw_lsq.hh +++ b/src/cpu/ozone/lw_lsq.hh @@ -239,8 +239,6 @@ class OzoneLWLSQ { /** Pointer to the back-end stage. */ BackEnd *be; - MemObject *mem; - class DcachePort : public Port { protected: diff --git a/src/cpu/ozone/lw_lsq_impl.hh b/src/cpu/ozone/lw_lsq_impl.hh index 1f3f18502..ee1968626 100644 --- a/src/cpu/ozone/lw_lsq_impl.hh +++ b/src/cpu/ozone/lw_lsq_impl.hh @@ -154,8 +154,6 @@ OzoneLWLSQ::init(Params *params, unsigned maxLQEntries, SQIndices.push(i); } - mem = params->mem; - usedPorts = 0; cachePorts = params->cachePorts; diff --git a/src/cpu/ozone/simple_params.hh b/src/cpu/ozone/simple_params.hh index 3f63d2e1d..3e554c812 100644 --- a/src/cpu/ozone/simple_params.hh +++ b/src/cpu/ozone/simple_params.hh @@ -61,8 +61,6 @@ class SimpleParams : public BaseCPU::Params //Page Table PageTable *pTable; - MemObject *mem; - // // Caches // diff --git a/src/cpu/ozone/thread_state.hh b/src/cpu/ozone/thread_state.hh index c86f3552e..c226d7502 100644 --- a/src/cpu/ozone/thread_state.hh +++ b/src/cpu/ozone/thread_state.hh @@ -67,7 +67,7 @@ struct OzoneThreadState : public ThreadState { #if FULL_SYSTEM OzoneThreadState(CPUType *_cpu, int _thread_num) - : ThreadState(-1, _thread_num), + : ThreadState(_cpu, -1, _thread_num), intrflag(0), cpu(_cpu), inSyscall(0), trapPending(0) { if (cpu->params->profile) { @@ -87,8 +87,8 @@ struct OzoneThreadState : public ThreadState { } #else OzoneThreadState(CPUType *_cpu, int _thread_num, Process *_process, - int _asid, MemObject *mem) - : ThreadState(-1, _thread_num, _process, _asid, mem), + int _asid) + : ThreadState(_cpu, -1, _thread_num, _process, _asid), cpu(_cpu), inSyscall(0), trapPending(0) { miscRegFile.clear(); diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index edba55b0d..bfb80dc0f 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -72,15 +72,6 @@ AtomicSimpleCPU::getPort(const std::string &if_name, int idx) void AtomicSimpleCPU::init() { - //Create Memory Ports (conect them up) -// Port *mem_dport = mem->getPort(""); -// dcachePort.setPeer(mem_dport); -// mem_dport->setPeer(&dcachePort); - -// Port *mem_iport = mem->getPort(""); -// icachePort.setPeer(mem_iport); -// mem_iport->setPeer(&icachePort); - BaseCPU::init(); #if FULL_SYSTEM for (int i = 0; i < threadContexts.size(); ++i) { @@ -500,7 +491,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AtomicSimpleCPU) Param max_loads_any_thread; Param max_loads_all_threads; Param progress_interval; - SimObjectParam mem; SimObjectParam system; Param cpu_id; @@ -533,7 +523,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AtomicSimpleCPU) INIT_PARAM(max_loads_all_threads, "terminate when all threads have reached this load count"), INIT_PARAM(progress_interval, "Progress interval"), - INIT_PARAM(mem, "memory"), INIT_PARAM(system, "system object"), INIT_PARAM(cpu_id, "processor ID"), @@ -571,7 +560,6 @@ CREATE_SIM_OBJECT(AtomicSimpleCPU) params->functionTraceStart = function_trace_start; params->width = width; params->simulate_stalls = simulate_stalls; - params->mem = mem; params->system = system; params->cpu_id = cpu_id; diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index cbb3980cb..dc06c17f5 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -70,13 +70,13 @@ using namespace std; using namespace TheISA; BaseSimpleCPU::BaseSimpleCPU(Params *p) - : BaseCPU(p), mem(p->mem), thread(NULL) + : BaseCPU(p), thread(NULL) { #if FULL_SYSTEM thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb); #else thread = new SimpleThread(this, /* thread_num */ 0, p->process, - /* asid */ 0, mem); + /* asid */ 0); #endif // !FULL_SYSTEM thread->setStatus(ThreadContext::Suspended); diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index af6b6f835..f382158dd 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -76,8 +76,6 @@ class BaseSimpleCPU : public BaseCPU typedef TheISA::FloatReg FloatReg; typedef TheISA::FloatRegBits FloatRegBits; - MemObject *mem; - protected: Trace::InstRecord *traceData; @@ -95,7 +93,6 @@ class BaseSimpleCPU : public BaseCPU public: struct Params : public BaseCPU::Params { - MemObject *mem; #if FULL_SYSTEM AlphaITB *itb; AlphaDTB *dtb; diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index fe6775ea4..9e1f091b5 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -660,7 +660,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(TimingSimpleCPU) Param max_loads_any_thread; Param max_loads_all_threads; Param progress_interval; - SimObjectParam mem; SimObjectParam system; Param cpu_id; @@ -693,7 +692,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(TimingSimpleCPU) INIT_PARAM(max_loads_all_threads, "terminate when all threads have reached this load count"), INIT_PARAM(progress_interval, "Progress interval"), - INIT_PARAM(mem, "memory"), INIT_PARAM(system, "system object"), INIT_PARAM(cpu_id, "processor ID"), @@ -729,7 +727,6 @@ CREATE_SIM_OBJECT(TimingSimpleCPU) params->clock = clock; params->functionTrace = function_trace; params->functionTraceStart = function_trace_start; - params->mem = mem; params->system = system; params->cpu_id = cpu_id; diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 4fc47c982..c89a13eef 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -62,7 +62,7 @@ using namespace std; SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, AlphaITB *_itb, AlphaDTB *_dtb, bool use_kernel_stats) - : ThreadState(-1, _thread_num), cpu(_cpu), system(_sys), itb(_itb), + : ThreadState(_cpu, -1, _thread_num), cpu(_cpu), system(_sys), itb(_itb), dtb(_dtb) { @@ -106,19 +106,10 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, } #else SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, - Process *_process, int _asid, MemObject* memobj) - : ThreadState(-1, _thread_num, _process, _asid, memobj), + Process *_process, int _asid) + : ThreadState(_cpu, -1, _thread_num, _process, _asid), cpu(_cpu) { - /* Use this port to for syscall emulation writes to memory. */ - Port *mem_port; - port = new TranslatingPort(csprintf("%s-%d-funcport", - cpu->name(), tid), - process->pTable, false); - mem_port = memobj->getPort("functional"); - mem_port->setPeer(port); - port->setPeer(mem_port); - regs.clear(); tc = new ProxyThreadContext(this); } @@ -127,9 +118,9 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, SimpleThread::SimpleThread() #if FULL_SYSTEM - : ThreadState(-1, -1) + : ThreadState(NULL, -1, -1) #else - : ThreadState(-1, -1, NULL, -1, NULL) + : ThreadState(NULL, -1, -1, NULL, -1) #endif { tc = new ProxyThreadContext(this); @@ -332,6 +323,25 @@ SimpleThread::delVirtPort(VirtualPort *vp) } } +#else +TranslatingPort * +SimpleThread::getMemPort() +{ + if (port != NULL) + return port; + + /* Use this port to for syscall emulation writes to memory. */ + Port *dcache_port; + port = new TranslatingPort(csprintf("%s-%d-funcport", + cpu->name(), tid), + process->pTable, false); + dcache_port = cpu->getPort("dcache_port"); + assert(dcache_port != NULL); + dcache_port = dcache_port->getPeer(); +// mem_port->setPeer(port); + port->setPeer(dcache_port); + return port; +} #endif diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index fe22e6c43..f002cbdce 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -117,8 +117,7 @@ class SimpleThread : public ThreadState AlphaITB *_itb, AlphaDTB *_dtb, bool use_kernel_stats = true); #else - SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid, - MemObject *memobj); + SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid); #endif SimpleThread(); @@ -174,6 +173,9 @@ class SimpleThread : public ThreadState bool simPalCheck(int palFunc); #else + // Override this function. + TranslatingPort *getMemPort(); + Fault translateInstReq(RequestPtr &req) { return process->pTable->translate(req); diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc index c644ae8d7..677ba6592 100644 --- a/src/cpu/thread_state.cc +++ b/src/cpu/thread_state.cc @@ -29,8 +29,11 @@ */ #include "base/output.hh" +#include "cpu/base.hh" #include "cpu/profile.hh" #include "cpu/thread_state.hh" +#include "mem/port.hh" +#include "mem/translating_port.hh" #include "sim/serialize.hh" #if FULL_SYSTEM @@ -39,15 +42,16 @@ #endif #if FULL_SYSTEM -ThreadState::ThreadState(int _cpuId, int _tid) - : cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), +ThreadState::ThreadState(BaseCPU *cpu, int _cpuId, int _tid) + : baseCpu(cpu), cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL), + physPort(NULL), virtPort(NULL), microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0) #else -ThreadState::ThreadState(int _cpuId, int _tid, Process *_process, - short _asid, MemObject *mem) - : cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), - process(_process), asid(_asid), +ThreadState::ThreadState(BaseCPU *cpu, int _cpuId, int _tid, Process *_process, + short _asid) + : baseCpu(cpu), cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0), + port(NULL), process(_process), asid(_asid), microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0) #endif { @@ -108,4 +112,31 @@ ThreadState::profileSample() profile->sample(profileNode, profilePC); } +#else +TranslatingPort * +ThreadState::getMemPort() +{ + if (port != NULL) + return port; + + /* Use this port to for syscall emulation writes to memory. */ + Port *dcache_port, *func_mem_port; + port = new TranslatingPort(csprintf("%s-%d-funcport", + baseCpu->name(), tid), + process->pTable, false); + + dcache_port = baseCpu->getPort("dcache_port"); + assert(dcache_port != NULL); + + MemObject *mem_object = dcache_port->getPeer()->getOwner(); + assert(mem_object != NULL); + + func_mem_port = mem_object->getPort("functional"); + assert(func_mem_port != NULL); + + func_mem_port->setPeer(port); + port->setPeer(func_mem_port); + + return port; +} #endif diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh index 60353760c..14673aabb 100644 --- a/src/cpu/thread_state.hh +++ b/src/cpu/thread_state.hh @@ -37,7 +37,6 @@ #if !FULL_SYSTEM #include "mem/mem_object.hh" -#include "mem/translating_port.hh" #include "sim/process.hh" #endif @@ -50,7 +49,9 @@ namespace Kernel { }; #endif +class BaseCPU; class Checkpoint; +class TranslatingPort; /** * Struct for holding general thread state that is needed across CPU @@ -62,10 +63,10 @@ struct ThreadState { typedef ThreadContext::Status Status; #if FULL_SYSTEM - ThreadState(int _cpuId, int _tid); + ThreadState(BaseCPU *cpu, int _cpuId, int _tid); #else - ThreadState(int _cpuId, int _tid, Process *_process, - short _asid, MemObject *mem); + ThreadState(BaseCPU *cpu, int _cpuId, int _tid, Process *_process, + short _asid); #endif void serialize(std::ostream &os); @@ -105,7 +106,7 @@ struct ThreadState { #else Process *getProcessPtr() { return process; } - TranslatingPort *getMemPort() { return port; } + TranslatingPort *getMemPort(); void setMemPort(TranslatingPort *_port) { port = _port; } @@ -153,6 +154,9 @@ struct ThreadState { protected: ThreadContext::Status _status; + // Pointer to the base CPU. + BaseCPU *baseCpu; + // ID of this context w.r.t. the System or Process object to which // it belongs. For full-system mode, this is the system CPU ID. int cpuId; -- cgit v1.2.3 From ece796ab8af23705f3f4d7bd12ee623f3961c99e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 16:02:28 -0500 Subject: Make the IPRs use regular miscreg indexes, and make a table or two to find the miscreg index of a specific IPR. --HG-- extra : convert_revision : dd235261e7086d6667b1b2bdc4a81b2573e21d53 --- src/arch/alpha/SConscript | 1 + src/arch/alpha/ev5.cc | 306 ++++++++++++++++++++--------------------- src/arch/alpha/ipr.cc | 140 +++++++++++++++++++ src/arch/alpha/ipr.hh | 228 ++++++++++++++++++++++++++++++ src/arch/alpha/isa/decoder.isa | 16 ++- src/arch/alpha/isa/main.isa | 1 + src/arch/alpha/isa_traits.hh | 95 +------------ src/arch/alpha/regfile.hh | 8 +- 8 files changed, 545 insertions(+), 250 deletions(-) create mode 100644 src/arch/alpha/ipr.cc create mode 100644 src/arch/alpha/ipr.hh (limited to 'src') diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript index 216c88cc7..9a5680649 100644 --- a/src/arch/alpha/SConscript +++ b/src/arch/alpha/SConscript @@ -56,6 +56,7 @@ full_system_sources = Split(''' tlb.cc arguments.cc ev5.cc + ipr.cc osfpal.cc stacktrace.cc vtophys.cc diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 7595423c3..56dadd6b1 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -62,7 +62,7 @@ AlphaISA::initCPU(ThreadContext *tc, int cpuId) AlphaFault *reset = new ResetFault; - tc->setPC(tc->readMiscReg(IPR_PAL_BASE) + reset->vect()); + tc->setPC(tc->readMiscReg(MISCREG_IPR_PAL_BASE) + reset->vect()); tc->setNextPC(tc->readPC() + sizeof(MachInst)); delete reset; @@ -79,9 +79,9 @@ AlphaISA::initIPRs(ThreadContext *tc, int cpuId) tc->setMiscReg(i, 0); } - tc->setMiscReg(IPR_PAL_BASE, PalBase); - tc->setMiscReg(IPR_MCSR, 0x6); - tc->setMiscReg(IPR_PALtemp16, cpuId); + tc->setMiscReg(MISCREG_IPR_PAL_BASE, PalBase); + tc->setMiscReg(MISCREG_IPR_MCSR, 0x6); + tc->setMiscReg(MISCREG_IPR_PALtemp16, cpuId); } @@ -96,13 +96,13 @@ AlphaISA::processInterrupts(CPU *cpu) cpu->checkInterrupts = false; - if (cpu->readMiscReg(IPR_ASTRR)) + if (cpu->readMiscReg(MISCREG_IPR_ASTRR)) panic("asynchronous traps not implemented\n"); - if (cpu->readMiscReg(IPR_SIRR)) { + if (cpu->readMiscReg(MISCREG_IPR_SIRR)) { for (int i = INTLEVEL_SOFTWARE_MIN; i < INTLEVEL_SOFTWARE_MAX; i++) { - if (cpu->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { + if (cpu->readMiscReg(MISCREG_IPR_SIRR) & (ULL(1) << i)) { // See table 4-19 of the 21164 hardware reference ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; summary |= (ULL(1) << i); @@ -123,12 +123,12 @@ AlphaISA::processInterrupts(CPU *cpu) } } - if (ipl && ipl > cpu->readMiscReg(IPR_IPLR)) { - cpu->setMiscReg(IPR_ISR, summary); - cpu->setMiscReg(IPR_INTID, ipl); + if (ipl && ipl > cpu->readMiscReg(MISCREG_IPR_IPLR)) { + cpu->setMiscReg(MISCREG_IPR_ISR, summary); + cpu->setMiscReg(MISCREG_IPR_INTID, ipl); cpu->trap(new InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - cpu->readMiscReg(IPR_IPLR), ipl, summary); + cpu->readMiscReg(MISCREG_IPR_IPLR), ipl, summary); } } @@ -150,7 +150,7 @@ SimpleThread::hwrei() if (!inPalMode()) return new UnimplementedOpcodeFault; - setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR)); + setNextPC(readMiscReg(AlphaISA::MISCREG_IPR_EXC_ADDR)); if (!misspeculating()) { if (kernelStats) @@ -166,13 +166,13 @@ SimpleThread::hwrei() int AlphaISA::MiscRegFile::getInstAsid() { - return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); + return EV5::ITB_ASN_ASN(ipr[MISCREG_IPR_ITB_ASN]); } int AlphaISA::MiscRegFile::getDataAsid() { - return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); + return EV5::DTB_ASN_ASN(ipr[MISCREG_IPR_DTB_ASN]); } AlphaISA::MiscReg @@ -181,71 +181,71 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc) uint64_t retval = 0; // return value, default 0 switch (idx) { - case AlphaISA::IPR_PALtemp0: - case AlphaISA::IPR_PALtemp1: - case AlphaISA::IPR_PALtemp2: - case AlphaISA::IPR_PALtemp3: - case AlphaISA::IPR_PALtemp4: - case AlphaISA::IPR_PALtemp5: - case AlphaISA::IPR_PALtemp6: - case AlphaISA::IPR_PALtemp7: - case AlphaISA::IPR_PALtemp8: - case AlphaISA::IPR_PALtemp9: - case AlphaISA::IPR_PALtemp10: - case AlphaISA::IPR_PALtemp11: - case AlphaISA::IPR_PALtemp12: - case AlphaISA::IPR_PALtemp13: - case AlphaISA::IPR_PALtemp14: - case AlphaISA::IPR_PALtemp15: - case AlphaISA::IPR_PALtemp16: - case AlphaISA::IPR_PALtemp17: - case AlphaISA::IPR_PALtemp18: - case AlphaISA::IPR_PALtemp19: - case AlphaISA::IPR_PALtemp20: - case AlphaISA::IPR_PALtemp21: - case AlphaISA::IPR_PALtemp22: - case AlphaISA::IPR_PALtemp23: - case AlphaISA::IPR_PAL_BASE: - - case AlphaISA::IPR_IVPTBR: - case AlphaISA::IPR_DC_MODE: - case AlphaISA::IPR_MAF_MODE: - case AlphaISA::IPR_ISR: - case AlphaISA::IPR_EXC_ADDR: - case AlphaISA::IPR_IC_PERR_STAT: - case AlphaISA::IPR_DC_PERR_STAT: - case AlphaISA::IPR_MCSR: - case AlphaISA::IPR_ASTRR: - case AlphaISA::IPR_ASTER: - case AlphaISA::IPR_SIRR: - case AlphaISA::IPR_ICSR: - case AlphaISA::IPR_ICM: - case AlphaISA::IPR_DTB_CM: - case AlphaISA::IPR_IPLR: - case AlphaISA::IPR_INTID: - case AlphaISA::IPR_PMCTR: + case AlphaISA::MISCREG_IPR_PALtemp0: + case AlphaISA::MISCREG_IPR_PALtemp1: + case AlphaISA::MISCREG_IPR_PALtemp2: + case AlphaISA::MISCREG_IPR_PALtemp3: + case AlphaISA::MISCREG_IPR_PALtemp4: + case AlphaISA::MISCREG_IPR_PALtemp5: + case AlphaISA::MISCREG_IPR_PALtemp6: + case AlphaISA::MISCREG_IPR_PALtemp7: + case AlphaISA::MISCREG_IPR_PALtemp8: + case AlphaISA::MISCREG_IPR_PALtemp9: + case AlphaISA::MISCREG_IPR_PALtemp10: + case AlphaISA::MISCREG_IPR_PALtemp11: + case AlphaISA::MISCREG_IPR_PALtemp12: + case AlphaISA::MISCREG_IPR_PALtemp13: + case AlphaISA::MISCREG_IPR_PALtemp14: + case AlphaISA::MISCREG_IPR_PALtemp15: + case AlphaISA::MISCREG_IPR_PALtemp16: + case AlphaISA::MISCREG_IPR_PALtemp17: + case AlphaISA::MISCREG_IPR_PALtemp18: + case AlphaISA::MISCREG_IPR_PALtemp19: + case AlphaISA::MISCREG_IPR_PALtemp20: + case AlphaISA::MISCREG_IPR_PALtemp21: + case AlphaISA::MISCREG_IPR_PALtemp22: + case AlphaISA::MISCREG_IPR_PALtemp23: + case AlphaISA::MISCREG_IPR_PAL_BASE: + + case AlphaISA::MISCREG_IPR_IVPTBR: + case AlphaISA::MISCREG_IPR_DC_MODE: + case AlphaISA::MISCREG_IPR_MAF_MODE: + case AlphaISA::MISCREG_IPR_ISR: + case AlphaISA::MISCREG_IPR_EXC_ADDR: + case AlphaISA::MISCREG_IPR_IC_PERR_STAT: + case AlphaISA::MISCREG_IPR_DC_PERR_STAT: + case AlphaISA::MISCREG_IPR_MCSR: + case AlphaISA::MISCREG_IPR_ASTRR: + case AlphaISA::MISCREG_IPR_ASTER: + case AlphaISA::MISCREG_IPR_SIRR: + case AlphaISA::MISCREG_IPR_ICSR: + case AlphaISA::MISCREG_IPR_ICM: + case AlphaISA::MISCREG_IPR_DTB_CM: + case AlphaISA::MISCREG_IPR_IPLR: + case AlphaISA::MISCREG_IPR_INTID: + case AlphaISA::MISCREG_IPR_PMCTR: // no side-effect retval = ipr[idx]; break; - case AlphaISA::IPR_CC: + case AlphaISA::MISCREG_IPR_CC: retval |= ipr[idx] & ULL(0xffffffff00000000); retval |= tc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff); break; - case AlphaISA::IPR_VA: + case AlphaISA::MISCREG_IPR_VA: retval = ipr[idx]; break; - case AlphaISA::IPR_VA_FORM: - case AlphaISA::IPR_MM_STAT: - case AlphaISA::IPR_IFAULT_VA_FORM: - case AlphaISA::IPR_EXC_MASK: - case AlphaISA::IPR_EXC_SUM: + case AlphaISA::MISCREG_IPR_VA_FORM: + case AlphaISA::MISCREG_IPR_MM_STAT: + case AlphaISA::MISCREG_IPR_IFAULT_VA_FORM: + case AlphaISA::MISCREG_IPR_EXC_MASK: + case AlphaISA::MISCREG_IPR_EXC_SUM: retval = ipr[idx]; break; - case AlphaISA::IPR_DTB_PTE: + case AlphaISA::MISCREG_IPR_DTB_PTE: { AlphaISA::PTE &pte = tc->getDTBPtr()->index(!tc->misspeculating()); @@ -260,15 +260,15 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc) break; // write only registers - case AlphaISA::IPR_HWINT_CLR: - case AlphaISA::IPR_SL_XMIT: - case AlphaISA::IPR_DC_FLUSH: - case AlphaISA::IPR_IC_FLUSH: - case AlphaISA::IPR_ALT_MODE: - case AlphaISA::IPR_DTB_IA: - case AlphaISA::IPR_DTB_IAP: - case AlphaISA::IPR_ITB_IA: - case AlphaISA::IPR_ITB_IAP: + case AlphaISA::MISCREG_IPR_HWINT_CLR: + case AlphaISA::MISCREG_IPR_SL_XMIT: + case AlphaISA::MISCREG_IPR_DC_FLUSH: + case AlphaISA::MISCREG_IPR_IC_FLUSH: + case AlphaISA::MISCREG_IPR_ALT_MODE: + case AlphaISA::MISCREG_IPR_DTB_IA: + case AlphaISA::MISCREG_IPR_DTB_IAP: + case AlphaISA::MISCREG_IPR_ITB_IA: + case AlphaISA::MISCREG_IPR_ITB_IAP: fault = new UnimplementedOpcodeFault; break; @@ -295,52 +295,52 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) return NoFault; switch (idx) { - case AlphaISA::IPR_PALtemp0: - case AlphaISA::IPR_PALtemp1: - case AlphaISA::IPR_PALtemp2: - case AlphaISA::IPR_PALtemp3: - case AlphaISA::IPR_PALtemp4: - case AlphaISA::IPR_PALtemp5: - case AlphaISA::IPR_PALtemp6: - case AlphaISA::IPR_PALtemp7: - case AlphaISA::IPR_PALtemp8: - case AlphaISA::IPR_PALtemp9: - case AlphaISA::IPR_PALtemp10: - case AlphaISA::IPR_PALtemp11: - case AlphaISA::IPR_PALtemp12: - case AlphaISA::IPR_PALtemp13: - case AlphaISA::IPR_PALtemp14: - case AlphaISA::IPR_PALtemp15: - case AlphaISA::IPR_PALtemp16: - case AlphaISA::IPR_PALtemp17: - case AlphaISA::IPR_PALtemp18: - case AlphaISA::IPR_PALtemp19: - case AlphaISA::IPR_PALtemp20: - case AlphaISA::IPR_PALtemp21: - case AlphaISA::IPR_PALtemp22: - case AlphaISA::IPR_PAL_BASE: - case AlphaISA::IPR_IC_PERR_STAT: - case AlphaISA::IPR_DC_PERR_STAT: - case AlphaISA::IPR_PMCTR: + case AlphaISA::MISCREG_IPR_PALtemp0: + case AlphaISA::MISCREG_IPR_PALtemp1: + case AlphaISA::MISCREG_IPR_PALtemp2: + case AlphaISA::MISCREG_IPR_PALtemp3: + case AlphaISA::MISCREG_IPR_PALtemp4: + case AlphaISA::MISCREG_IPR_PALtemp5: + case AlphaISA::MISCREG_IPR_PALtemp6: + case AlphaISA::MISCREG_IPR_PALtemp7: + case AlphaISA::MISCREG_IPR_PALtemp8: + case AlphaISA::MISCREG_IPR_PALtemp9: + case AlphaISA::MISCREG_IPR_PALtemp10: + case AlphaISA::MISCREG_IPR_PALtemp11: + case AlphaISA::MISCREG_IPR_PALtemp12: + case AlphaISA::MISCREG_IPR_PALtemp13: + case AlphaISA::MISCREG_IPR_PALtemp14: + case AlphaISA::MISCREG_IPR_PALtemp15: + case AlphaISA::MISCREG_IPR_PALtemp16: + case AlphaISA::MISCREG_IPR_PALtemp17: + case AlphaISA::MISCREG_IPR_PALtemp18: + case AlphaISA::MISCREG_IPR_PALtemp19: + case AlphaISA::MISCREG_IPR_PALtemp20: + case AlphaISA::MISCREG_IPR_PALtemp21: + case AlphaISA::MISCREG_IPR_PALtemp22: + case AlphaISA::MISCREG_IPR_PAL_BASE: + case AlphaISA::MISCREG_IPR_IC_PERR_STAT: + case AlphaISA::MISCREG_IPR_DC_PERR_STAT: + case AlphaISA::MISCREG_IPR_PMCTR: // write entire quad w/ no side-effect ipr[idx] = val; break; - case AlphaISA::IPR_CC_CTL: + case AlphaISA::MISCREG_IPR_CC_CTL: // This IPR resets the cycle counter. We assume this only // happens once... let's verify that. assert(ipr[idx] == 0); ipr[idx] = 1; break; - case AlphaISA::IPR_CC: + case AlphaISA::MISCREG_IPR_CC: // This IPR only writes the upper 64 bits. It's ok to write // all 64 here since we mask out the lower 32 in rpcc (see // isa_desc). ipr[idx] = val; break; - case AlphaISA::IPR_PALtemp23: + case AlphaISA::MISCREG_IPR_PALtemp23: // write entire quad w/ no side-effect old = ipr[idx]; ipr[idx] = val; @@ -348,23 +348,23 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) tc->getKernelStats()->context(old, val, tc); break; - case AlphaISA::IPR_DTB_PTE: + case AlphaISA::MISCREG_IPR_DTB_PTE: // write entire quad w/ no side-effect, tag is forthcoming ipr[idx] = val; break; - case AlphaISA::IPR_EXC_ADDR: + case AlphaISA::MISCREG_IPR_EXC_ADDR: // second least significant bit in PC is always zero ipr[idx] = val & ~2; break; - case AlphaISA::IPR_ASTRR: - case AlphaISA::IPR_ASTER: + case AlphaISA::MISCREG_IPR_ASTRR: + case AlphaISA::MISCREG_IPR_ASTER: // only write least significant four bits - privilege mask ipr[idx] = val & 0xf; break; - case AlphaISA::IPR_IPLR: + case AlphaISA::MISCREG_IPR_IPLR: #ifdef DEBUG if (break_ipl != -1 && break_ipl == (val & 0x1f)) debug_break(); @@ -376,7 +376,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) tc->getKernelStats()->swpipl(ipr[idx]); break; - case AlphaISA::IPR_DTB_CM: + case AlphaISA::MISCREG_IPR_DTB_CM: if (val & 0x18) { if (tc->getKernelStats()) tc->getKernelStats()->mode(Kernel::user, tc); @@ -385,121 +385,121 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) tc->getKernelStats()->mode(Kernel::kernel, tc); } - case AlphaISA::IPR_ICM: + case AlphaISA::MISCREG_IPR_ICM: // only write two mode bits - processor mode ipr[idx] = val & 0x18; break; - case AlphaISA::IPR_ALT_MODE: + case AlphaISA::MISCREG_IPR_ALT_MODE: // only write two mode bits - processor mode ipr[idx] = val & 0x18; break; - case AlphaISA::IPR_MCSR: + case AlphaISA::MISCREG_IPR_MCSR: // more here after optimization... ipr[idx] = val; break; - case AlphaISA::IPR_SIRR: + case AlphaISA::MISCREG_IPR_SIRR: // only write software interrupt mask ipr[idx] = val & 0x7fff0; break; - case AlphaISA::IPR_ICSR: + case AlphaISA::MISCREG_IPR_ICSR: ipr[idx] = val & ULL(0xffffff0300); break; - case AlphaISA::IPR_IVPTBR: - case AlphaISA::IPR_MVPTBR: + case AlphaISA::MISCREG_IPR_IVPTBR: + case AlphaISA::MISCREG_IPR_MVPTBR: ipr[idx] = val & ULL(0xffffffffc0000000); break; - case AlphaISA::IPR_DC_TEST_CTL: + case AlphaISA::MISCREG_IPR_DC_TEST_CTL: ipr[idx] = val & 0x1ffb; break; - case AlphaISA::IPR_DC_MODE: - case AlphaISA::IPR_MAF_MODE: + case AlphaISA::MISCREG_IPR_DC_MODE: + case AlphaISA::MISCREG_IPR_MAF_MODE: ipr[idx] = val & 0x3f; break; - case AlphaISA::IPR_ITB_ASN: + case AlphaISA::MISCREG_IPR_ITB_ASN: ipr[idx] = val & 0x7f0; break; - case AlphaISA::IPR_DTB_ASN: + case AlphaISA::MISCREG_IPR_DTB_ASN: ipr[idx] = val & ULL(0xfe00000000000000); break; - case AlphaISA::IPR_EXC_SUM: - case AlphaISA::IPR_EXC_MASK: + case AlphaISA::MISCREG_IPR_EXC_SUM: + case AlphaISA::MISCREG_IPR_EXC_MASK: // any write to this register clears it ipr[idx] = 0; break; - case AlphaISA::IPR_INTID: - case AlphaISA::IPR_SL_RCV: - case AlphaISA::IPR_MM_STAT: - case AlphaISA::IPR_ITB_PTE_TEMP: - case AlphaISA::IPR_DTB_PTE_TEMP: + case AlphaISA::MISCREG_IPR_INTID: + case AlphaISA::MISCREG_IPR_SL_RCV: + case AlphaISA::MISCREG_IPR_MM_STAT: + case AlphaISA::MISCREG_IPR_ITB_PTE_TEMP: + case AlphaISA::MISCREG_IPR_DTB_PTE_TEMP: // read-only registers return new UnimplementedOpcodeFault; - case AlphaISA::IPR_HWINT_CLR: - case AlphaISA::IPR_SL_XMIT: - case AlphaISA::IPR_DC_FLUSH: - case AlphaISA::IPR_IC_FLUSH: + case AlphaISA::MISCREG_IPR_HWINT_CLR: + case AlphaISA::MISCREG_IPR_SL_XMIT: + case AlphaISA::MISCREG_IPR_DC_FLUSH: + case AlphaISA::MISCREG_IPR_IC_FLUSH: // the following are write only ipr[idx] = val; break; - case AlphaISA::IPR_DTB_IA: + case AlphaISA::MISCREG_IPR_DTB_IA: // really a control write ipr[idx] = 0; tc->getDTBPtr()->flushAll(); break; - case AlphaISA::IPR_DTB_IAP: + case AlphaISA::MISCREG_IPR_DTB_IAP: // really a control write ipr[idx] = 0; tc->getDTBPtr()->flushProcesses(); break; - case AlphaISA::IPR_DTB_IS: + case AlphaISA::MISCREG_IPR_DTB_IS: // really a control write ipr[idx] = val; tc->getDTBPtr()->flushAddr(val, - DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + DTB_ASN_ASN(ipr[AlphaISA::MISCREG_IPR_DTB_ASN])); break; - case AlphaISA::IPR_DTB_TAG: { + case AlphaISA::MISCREG_IPR_DTB_TAG: { struct AlphaISA::PTE pte; // FIXME: granularity hints NYI... - if (DTB_PTE_GH(ipr[AlphaISA::IPR_DTB_PTE]) != 0) + if (DTB_PTE_GH(ipr[AlphaISA::MISCREG_IPR_DTB_PTE]) != 0) panic("PTE GH field != 0"); // write entire quad ipr[idx] = val; // construct PTE for new entry - pte.ppn = DTB_PTE_PPN(ipr[AlphaISA::IPR_DTB_PTE]); - pte.xre = DTB_PTE_XRE(ipr[AlphaISA::IPR_DTB_PTE]); - pte.xwe = DTB_PTE_XWE(ipr[AlphaISA::IPR_DTB_PTE]); - pte.fonr = DTB_PTE_FONR(ipr[AlphaISA::IPR_DTB_PTE]); - pte.fonw = DTB_PTE_FONW(ipr[AlphaISA::IPR_DTB_PTE]); - pte.asma = DTB_PTE_ASMA(ipr[AlphaISA::IPR_DTB_PTE]); - pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]); + pte.ppn = DTB_PTE_PPN(ipr[AlphaISA::MISCREG_IPR_DTB_PTE]); + pte.xre = DTB_PTE_XRE(ipr[AlphaISA::MISCREG_IPR_DTB_PTE]); + pte.xwe = DTB_PTE_XWE(ipr[AlphaISA::MISCREG_IPR_DTB_PTE]); + pte.fonr = DTB_PTE_FONR(ipr[AlphaISA::MISCREG_IPR_DTB_PTE]); + pte.fonw = DTB_PTE_FONW(ipr[AlphaISA::MISCREG_IPR_DTB_PTE]); + pte.asma = DTB_PTE_ASMA(ipr[AlphaISA::MISCREG_IPR_DTB_PTE]); + pte.asn = DTB_ASN_ASN(ipr[AlphaISA::MISCREG_IPR_DTB_ASN]); // insert new TAG/PTE value into data TLB tc->getDTBPtr()->insert(val, pte); } break; - case AlphaISA::IPR_ITB_PTE: { + case AlphaISA::MISCREG_IPR_ITB_PTE: { struct AlphaISA::PTE pte; // FIXME: granularity hints NYI... @@ -516,33 +516,33 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) pte.fonr = ITB_PTE_FONR(val); pte.fonw = ITB_PTE_FONW(val); pte.asma = ITB_PTE_ASMA(val); - pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]); + pte.asn = ITB_ASN_ASN(ipr[AlphaISA::MISCREG_IPR_ITB_ASN]); // insert new TAG/PTE value into data TLB - tc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], pte); + tc->getITBPtr()->insert(ipr[AlphaISA::MISCREG_IPR_ITB_TAG], pte); } break; - case AlphaISA::IPR_ITB_IA: + case AlphaISA::MISCREG_IPR_ITB_IA: // really a control write ipr[idx] = 0; tc->getITBPtr()->flushAll(); break; - case AlphaISA::IPR_ITB_IAP: + case AlphaISA::MISCREG_IPR_ITB_IAP: // really a control write ipr[idx] = 0; tc->getITBPtr()->flushProcesses(); break; - case AlphaISA::IPR_ITB_IS: + case AlphaISA::MISCREG_IPR_ITB_IS: // really a control write ipr[idx] = val; tc->getITBPtr()->flushAddr(val, - ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); + ITB_ASN_ASN(ipr[AlphaISA::MISCREG_IPR_ITB_ASN])); break; default: diff --git a/src/arch/alpha/ipr.cc b/src/arch/alpha/ipr.cc new file mode 100644 index 000000000..50086a845 --- /dev/null +++ b/src/arch/alpha/ipr.cc @@ -0,0 +1,140 @@ +/* + * 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: Gabe Black + */ + +#include +#include + +#include "arch/alpha/ipr.hh" + +namespace AlphaISA +{ + md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs] = + { + //Write only + IPR_HWINT_CLR, // H/W interrupt clear register + IPR_SL_XMIT, // serial line transmit register + IPR_DC_FLUSH, + IPR_IC_FLUSH, // instruction cache flush control + IPR_ALT_MODE, // alternate mode register + IPR_DTB_IA, // DTLB invalidate all register + IPR_DTB_IAP, // DTLB invalidate all process register + IPR_ITB_IA, // ITLB invalidate all register + IPR_ITB_IAP, // ITLB invalidate all process register + + //Read only + IPR_INTID, // interrupt ID register + IPR_SL_RCV, // serial line receive register + IPR_MM_STAT, // data MMU fault status register + IPR_ITB_PTE_TEMP, // ITLB page table entry temp register + IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register + + IPR_ISR, // interrupt summary register + IPR_ITB_TAG, // ITLB tag register + IPR_ITB_PTE, // ITLB page table entry register + IPR_ITB_ASN, // ITLB address space register + IPR_ITB_IS, // ITLB invalidate select register + IPR_SIRR, // software interrupt request register + IPR_ASTRR, // asynchronous system trap request register + IPR_ASTER, // asynchronous system trap enable register + IPR_EXC_ADDR, // exception address register + IPR_EXC_SUM, // exception summary register + IPR_EXC_MASK, // exception mask register + IPR_PAL_BASE, // PAL base address register + IPR_ICM, // instruction current mode + IPR_IPLR, // interrupt priority level register + IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register + IPR_IVPTBR, // virtual page table base register + IPR_ICSR, // instruction control and status register + IPR_IC_PERR_STAT, // inst cache parity error status register + IPR_PMCTR, // performance counter register + + // PAL temporary registers... + // register meanings gleaned from osfpal.s source code + IPR_PALtemp0, // local scratch + IPR_PALtemp1, // local scratch + IPR_PALtemp2, // entUna + IPR_PALtemp3, // CPU specific impure area pointer + IPR_PALtemp4, // memory management temp + IPR_PALtemp5, // memory management temp + IPR_PALtemp6, // memory management temp + IPR_PALtemp7, // entIF + IPR_PALtemp8, // intmask + IPR_PALtemp9, // entSys + IPR_PALtemp10, // ?? + IPR_PALtemp11, // entInt + IPR_PALtemp12, // entArith + IPR_PALtemp13, // reserved for platform specific PAL + IPR_PALtemp14, // reserved for platform specific PAL + IPR_PALtemp15, // reserved for platform specific PAL + IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0> + IPR_PALtemp17, // sysval + IPR_PALtemp18, // usp + IPR_PALtemp19, // ksp + IPR_PALtemp20, // PTBR + IPR_PALtemp21, // entMM + IPR_PALtemp22, // kgp + IPR_PALtemp23, // PCBB + + IPR_DTB_ASN, // DTLB address space number register + IPR_DTB_CM, // DTLB current mode register + IPR_DTB_TAG, // DTLB tag register + IPR_DTB_PTE, // DTLB page table entry register + + IPR_VA, // fault virtual address register + IPR_VA_FORM, // formatted virtual address register + IPR_MVPTBR, // MTU virtual page table base register + IPR_DTB_IS, // DTLB invalidate single register + IPR_CC, // cycle counter register + IPR_CC_CTL, // cycle counter control register + IPR_MCSR, // MTU control register + + IPR_DC_PERR_STAT, // Dcache parity error status register + IPR_DC_TEST_CTL, // Dcache test tag control register + IPR_DC_TEST_TAG, // Dcache test tag register + IPR_DC_TEST_TAG_TEMP, // Dcache test tag temporary register + IPR_DC_MODE, // Dcache mode register + IPR_MAF_MODE // miss address file mode register + }; + + int IprToMiscRegIndex[MaxInternalProcRegs]; + + void initializeIprTable() + { + static bool initialized = false; + if(initialized) + return; + + memset(IprToMiscRegIndex, -1, MaxInternalProcRegs * sizeof(int)); + + for(int x = 0; x < NumInternalProcRegs; x++) + IprToMiscRegIndex[MiscRegIndexToIpr[x]] = x; + } +} + diff --git a/src/arch/alpha/ipr.hh b/src/arch/alpha/ipr.hh new file mode 100644 index 000000000..dba0733ba --- /dev/null +++ b/src/arch/alpha/ipr.hh @@ -0,0 +1,228 @@ +/* + * 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: Steve Reinhardt + * Gabe Black + */ + +#ifndef __ARCH_ALPHA_IPR_HH__ +#define __ARCH_ALPHA_IPR_HH__ + +namespace AlphaISA +{ + //////////////////////////////////////////////////////////////////////// + // + // Internal Processor Reigsters + // + enum md_ipr_names + { + IPR_ISR = 0x100, // interrupt summary register + IPR_ITB_TAG = 0x101, // ITLB tag register + IPR_ITB_PTE = 0x102, // ITLB page table entry register + IPR_ITB_ASN = 0x103, // ITLB address space register + IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register + IPR_ITB_IA = 0x105, // ITLB invalidate all register + IPR_ITB_IAP = 0x106, // ITLB invalidate all process register + IPR_ITB_IS = 0x107, // ITLB invalidate select register + IPR_SIRR = 0x108, // software interrupt request register + IPR_ASTRR = 0x109, // asynchronous system trap request register + IPR_ASTER = 0x10a, // asynchronous system trap enable register + IPR_EXC_ADDR = 0x10b, // exception address register + IPR_EXC_SUM = 0x10c, // exception summary register + IPR_EXC_MASK = 0x10d, // exception mask register + IPR_PAL_BASE = 0x10e, // PAL base address register + IPR_ICM = 0x10f, // instruction current mode + IPR_IPLR = 0x110, // interrupt priority level register + IPR_INTID = 0x111, // interrupt ID register + IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register + IPR_IVPTBR = 0x113, // virtual page table base register + IPR_HWINT_CLR = 0x115, // H/W interrupt clear register + IPR_SL_XMIT = 0x116, // serial line transmit register + IPR_SL_RCV = 0x117, // serial line receive register + IPR_ICSR = 0x118, // instruction control and status register + IPR_IC_FLUSH = 0x119, // instruction cache flush control + IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register + IPR_PMCTR = 0x11c, // performance counter register + + // PAL temporary registers... + // register meanings gleaned from osfpal.s source code + IPR_PALtemp0 = 0x140, // local scratch + IPR_PALtemp1 = 0x141, // local scratch + IPR_PALtemp2 = 0x142, // entUna + IPR_PALtemp3 = 0x143, // CPU specific impure area pointer + IPR_PALtemp4 = 0x144, // memory management temp + IPR_PALtemp5 = 0x145, // memory management temp + IPR_PALtemp6 = 0x146, // memory management temp + IPR_PALtemp7 = 0x147, // entIF + IPR_PALtemp8 = 0x148, // intmask + IPR_PALtemp9 = 0x149, // entSys + IPR_PALtemp10 = 0x14a, // ?? + IPR_PALtemp11 = 0x14b, // entInt + IPR_PALtemp12 = 0x14c, // entArith + IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL + IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL + IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL + IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0> + IPR_PALtemp17 = 0x151, // sysval + IPR_PALtemp18 = 0x152, // usp + IPR_PALtemp19 = 0x153, // ksp + IPR_PALtemp20 = 0x154, // PTBR + IPR_PALtemp21 = 0x155, // entMM + IPR_PALtemp22 = 0x156, // kgp + IPR_PALtemp23 = 0x157, // PCBB + + IPR_DTB_ASN = 0x200, // DTLB address space number register + IPR_DTB_CM = 0x201, // DTLB current mode register + IPR_DTB_TAG = 0x202, // DTLB tag register + IPR_DTB_PTE = 0x203, // DTLB page table entry register + IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register + + IPR_MM_STAT = 0x205, // data MMU fault status register + IPR_VA = 0x206, // fault virtual address register + IPR_VA_FORM = 0x207, // formatted virtual address register + IPR_MVPTBR = 0x208, // MTU virtual page table base register + IPR_DTB_IAP = 0x209, // DTLB invalidate all process register + IPR_DTB_IA = 0x20a, // DTLB invalidate all register + IPR_DTB_IS = 0x20b, // DTLB invalidate single register + IPR_ALT_MODE = 0x20c, // alternate mode register + IPR_CC = 0x20d, // cycle counter register + IPR_CC_CTL = 0x20e, // cycle counter control register + IPR_MCSR = 0x20f, // MTU control register + + IPR_DC_FLUSH = 0x210, + IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register + IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register + IPR_DC_TEST_TAG = 0x214, // Dcache test tag register + IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register + IPR_DC_MODE = 0x216, // Dcache mode register + IPR_MAF_MODE = 0x217, // miss address file mode register + + MaxInternalProcRegs // number of IPR registers + }; + + enum MiscRegIpr + { + //Write only + MinWriteOnlyIpr, + MISCREG_IPR_HWINT_CLR = MinWriteOnlyIpr, + MISCREG_IPR_SL_XMIT, + MISCREG_IPR_DC_FLUSH, + MISCREG_IPR_IC_FLUSH, + MISCREG_IPR_ALT_MODE, + MISCREG_IPR_DTB_IA, + MISCREG_IPR_DTB_IAP, + MISCREG_IPR_ITB_IA, + MaxWriteOnlyIpr, + MISCREG_IPR_ITB_IAP = MaxWriteOnlyIpr, + + //Read only + MinReadOnlyIpr, + MISCREG_IPR_INTID = MinReadOnlyIpr, + MISCREG_IPR_SL_RCV, + MISCREG_IPR_MM_STAT, + MISCREG_IPR_ITB_PTE_TEMP, + MaxReadOnlyIpr, + MISCREG_IPR_DTB_PTE_TEMP = MaxReadOnlyIpr, + + MISCREG_IPR_ISR, + MISCREG_IPR_ITB_TAG, + MISCREG_IPR_ITB_PTE, + MISCREG_IPR_ITB_ASN, + MISCREG_IPR_ITB_IS, + MISCREG_IPR_SIRR, + MISCREG_IPR_ASTRR, + MISCREG_IPR_ASTER, + MISCREG_IPR_EXC_ADDR, + MISCREG_IPR_EXC_SUM, + MISCREG_IPR_EXC_MASK, + MISCREG_IPR_PAL_BASE, + MISCREG_IPR_ICM, + MISCREG_IPR_IPLR, + MISCREG_IPR_IFAULT_VA_FORM, + MISCREG_IPR_IVPTBR, + MISCREG_IPR_ICSR, + MISCREG_IPR_IC_PERR_STAT, + MISCREG_IPR_PMCTR, + + // PAL temporary registers... + // register meanings gleaned from osfpal.s source code + MISCREG_IPR_PALtemp0, + MISCREG_IPR_PALtemp1, + MISCREG_IPR_PALtemp2, + MISCREG_IPR_PALtemp3, + MISCREG_IPR_PALtemp4, + MISCREG_IPR_PALtemp5, + MISCREG_IPR_PALtemp6, + MISCREG_IPR_PALtemp7, + MISCREG_IPR_PALtemp8, + MISCREG_IPR_PALtemp9, + MISCREG_IPR_PALtemp10, + MISCREG_IPR_PALtemp11, + MISCREG_IPR_PALtemp12, + MISCREG_IPR_PALtemp13, + MISCREG_IPR_PALtemp14, + MISCREG_IPR_PALtemp15, + MISCREG_IPR_PALtemp16, + MISCREG_IPR_PALtemp17, + MISCREG_IPR_PALtemp18, + MISCREG_IPR_PALtemp19, + MISCREG_IPR_PALtemp20, + MISCREG_IPR_PALtemp21, + MISCREG_IPR_PALtemp22, + MISCREG_IPR_PALtemp23, + + MISCREG_IPR_DTB_ASN, + MISCREG_IPR_DTB_CM, + MISCREG_IPR_DTB_TAG, + MISCREG_IPR_DTB_PTE, + + MISCREG_IPR_VA, + MISCREG_IPR_VA_FORM, + MISCREG_IPR_MVPTBR, + MISCREG_IPR_DTB_IS, + MISCREG_IPR_CC, + MISCREG_IPR_CC_CTL, + MISCREG_IPR_MCSR, + + MISCREG_IPR_DC_PERR_STAT, + MISCREG_IPR_DC_TEST_CTL, + MISCREG_IPR_DC_TEST_TAG, + MISCREG_IPR_DC_TEST_TAG_TEMP, + MISCREG_IPR_DC_MODE, + MISCREG_IPR_MAF_MODE, + + NumInternalProcRegs // number of IPR registers + }; + + + extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs]; + extern int IprToMiscRegIndex[MaxInternalProcRegs]; + + void initializeIprTable(); +} + +#endif diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 93b941d72..852f483e0 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -745,7 +745,13 @@ decode OPCODE default Unknown::unknown() { 0: OpcdecFault::hw_mfpr(); format HwMoveIPR { 1: hw_mfpr({{ - Ra = xc->readMiscRegWithEffect(ipr_index, fault); + int miscRegIndex = IprToMiscRegIndex[ipr_index]; + if(miscRegIndex < 0 || + (miscRegIndex >= MinWriteOnlyIpr && + miscRegIndex <= MaxWriteOnlyIpr)) + fault = new UnimplementedOpcodeFault; + else + Ra = xc->readMiscRegWithEffect(ipr_index, fault); }}, IsIprAccess); } } @@ -754,7 +760,13 @@ decode OPCODE default Unknown::unknown() { 0: OpcdecFault::hw_mtpr(); format HwMoveIPR { 1: hw_mtpr({{ - xc->setMiscRegWithEffect(ipr_index, Ra); + int miscRegIndex = IprToMiscRegIndex[ipr_index]; + if(miscRegIndex < 0 || + (miscRegIndex >= MinReadOnlyIpr && + miscRegIndex <= MaxWriteOnlyIpr)) + fault = new UnimplementedOpcodeFault; + else + xc->setMiscRegWithEffect(ipr_index, Ra); if (traceData) { traceData->setData(Ra); } }}, IsIprAccess); } diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index 1df6ac603..06d3e8243 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -71,6 +71,7 @@ output exec {{ #if FULL_SYSTEM #include "sim/pseudo_inst.hh" #endif +#include "arch/alpha/ipr.hh" #include "base/fenv.hh" #include "config/ss_compatible_fp.hh" #include "cpu/base.hh" diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh index 66cb21235..a919a4a1f 100644 --- a/src/arch/alpha/isa_traits.hh +++ b/src/arch/alpha/isa_traits.hh @@ -34,6 +34,7 @@ namespace LittleEndianGuest {} +#include "arch/alpha/ipr.hh" #include "arch/alpha/types.hh" #include "config/full_system.hh" #include "sim/host.hh" @@ -132,100 +133,6 @@ namespace AlphaISA #endif -#if FULL_SYSTEM - //////////////////////////////////////////////////////////////////////// - // - // Internal Processor Reigsters - // - enum md_ipr_names - { - IPR_ISR = 0x100, // interrupt summary register - IPR_ITB_TAG = 0x101, // ITLB tag register - IPR_ITB_PTE = 0x102, // ITLB page table entry register - IPR_ITB_ASN = 0x103, // ITLB address space register - IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register - IPR_ITB_IA = 0x105, // ITLB invalidate all register - IPR_ITB_IAP = 0x106, // ITLB invalidate all process register - IPR_ITB_IS = 0x107, // ITLB invalidate select register - IPR_SIRR = 0x108, // software interrupt request register - IPR_ASTRR = 0x109, // asynchronous system trap request register - IPR_ASTER = 0x10a, // asynchronous system trap enable register - IPR_EXC_ADDR = 0x10b, // exception address register - IPR_EXC_SUM = 0x10c, // exception summary register - IPR_EXC_MASK = 0x10d, // exception mask register - IPR_PAL_BASE = 0x10e, // PAL base address register - IPR_ICM = 0x10f, // instruction current mode - IPR_IPLR = 0x110, // interrupt priority level register - IPR_INTID = 0x111, // interrupt ID register - IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register - IPR_IVPTBR = 0x113, // virtual page table base register - IPR_HWINT_CLR = 0x115, // H/W interrupt clear register - IPR_SL_XMIT = 0x116, // serial line transmit register - IPR_SL_RCV = 0x117, // serial line receive register - IPR_ICSR = 0x118, // instruction control and status register - IPR_IC_FLUSH = 0x119, // instruction cache flush control - IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register - IPR_PMCTR = 0x11c, // performance counter register - - // PAL temporary registers... - // register meanings gleaned from osfpal.s source code - IPR_PALtemp0 = 0x140, // local scratch - IPR_PALtemp1 = 0x141, // local scratch - IPR_PALtemp2 = 0x142, // entUna - IPR_PALtemp3 = 0x143, // CPU specific impure area pointer - IPR_PALtemp4 = 0x144, // memory management temp - IPR_PALtemp5 = 0x145, // memory management temp - IPR_PALtemp6 = 0x146, // memory management temp - IPR_PALtemp7 = 0x147, // entIF - IPR_PALtemp8 = 0x148, // intmask - IPR_PALtemp9 = 0x149, // entSys - IPR_PALtemp10 = 0x14a, // ?? - IPR_PALtemp11 = 0x14b, // entInt - IPR_PALtemp12 = 0x14c, // entArith - IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL - IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL - IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL - IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0> - IPR_PALtemp17 = 0x151, // sysval - IPR_PALtemp18 = 0x152, // usp - IPR_PALtemp19 = 0x153, // ksp - IPR_PALtemp20 = 0x154, // PTBR - IPR_PALtemp21 = 0x155, // entMM - IPR_PALtemp22 = 0x156, // kgp - IPR_PALtemp23 = 0x157, // PCBB - - IPR_DTB_ASN = 0x200, // DTLB address space number register - IPR_DTB_CM = 0x201, // DTLB current mode register - IPR_DTB_TAG = 0x202, // DTLB tag register - IPR_DTB_PTE = 0x203, // DTLB page table entry register - IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register - - IPR_MM_STAT = 0x205, // data MMU fault status register - IPR_VA = 0x206, // fault virtual address register - IPR_VA_FORM = 0x207, // formatted virtual address register - IPR_MVPTBR = 0x208, // MTU virtual page table base register - IPR_DTB_IAP = 0x209, // DTLB invalidate all process register - IPR_DTB_IA = 0x20a, // DTLB invalidate all register - IPR_DTB_IS = 0x20b, // DTLB invalidate single register - IPR_ALT_MODE = 0x20c, // alternate mode register - IPR_CC = 0x20d, // cycle counter register - IPR_CC_CTL = 0x20e, // cycle counter control register - IPR_MCSR = 0x20f, // MTU control register - - IPR_DC_FLUSH = 0x210, - IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register - IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register - IPR_DC_TEST_TAG = 0x214, // Dcache test tag register - IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register - IPR_DC_MODE = 0x216, // Dcache mode register - IPR_MAF_MODE = 0x217, // miss address file mode register - - NumInternalProcRegs // number of IPR registers - }; -#else - const int NumInternalProcRegs = 0; -#endif - // Constants Related to the number of registers const int NumIntArchRegs = 32; diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index ea6fc67b2..31472ec0e 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -31,8 +31,9 @@ #ifndef __ARCH_ALPHA_REGFILE_HH__ #define __ARCH_ALPHA_REGFILE_HH__ -#include "arch/alpha/types.hh" #include "arch/alpha/isa_traits.hh" +#include "arch/alpha/ipr.hh" +#include "arch/alpha/types.hh" #include "sim/faults.hh" #include @@ -112,6 +113,11 @@ namespace AlphaISA int intr_flag; public: + MiscRegFile() + { + initializeIprTable(); + } + MiscReg readReg(int misc_reg); MiscReg readRegWithEffect(int misc_reg, Fault &fault, -- cgit v1.2.3 From 44f2c05118f46b996d13d7c3eac3227a8141e3fe Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 16:18:54 -0500 Subject: Forgot to change the index. --HG-- extra : convert_revision : 5a444e635d20bcca445a10e43592b6c10d25e879 --- src/arch/alpha/isa/decoder.isa | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 852f483e0..0cbe38ceb 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -751,7 +751,7 @@ decode OPCODE default Unknown::unknown() { miscRegIndex <= MaxWriteOnlyIpr)) fault = new UnimplementedOpcodeFault; else - Ra = xc->readMiscRegWithEffect(ipr_index, fault); + Ra = xc->readMiscRegWithEffect(miscRegIndex, fault); }}, IsIprAccess); } } @@ -766,7 +766,7 @@ decode OPCODE default Unknown::unknown() { miscRegIndex <= MaxWriteOnlyIpr)) fault = new UnimplementedOpcodeFault; else - xc->setMiscRegWithEffect(ipr_index, Ra); + xc->setMiscRegWithEffect(miscRegIndex, Ra); if (traceData) { traceData->setData(Ra); } }}, IsIprAccess); } -- cgit v1.2.3 From ace4f0c188f3bbc921d003750dad1410877680d1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 16:36:45 -0500 Subject: Made the old name refer to the miscreg index to prevent having to change code all over the place. --HG-- extra : convert_revision : e890a3ce420336acdb220396dcbf66d4b9974c76 --- src/arch/alpha/ev5.cc | 306 ++++++++++++++++++++++++------------------------- src/arch/alpha/ipr.cc | 148 ++++++++++++------------ src/arch/alpha/ipr.hh | 310 +++++++++++++++++++++++++------------------------- 3 files changed, 382 insertions(+), 382 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 56dadd6b1..7595423c3 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -62,7 +62,7 @@ AlphaISA::initCPU(ThreadContext *tc, int cpuId) AlphaFault *reset = new ResetFault; - tc->setPC(tc->readMiscReg(MISCREG_IPR_PAL_BASE) + reset->vect()); + tc->setPC(tc->readMiscReg(IPR_PAL_BASE) + reset->vect()); tc->setNextPC(tc->readPC() + sizeof(MachInst)); delete reset; @@ -79,9 +79,9 @@ AlphaISA::initIPRs(ThreadContext *tc, int cpuId) tc->setMiscReg(i, 0); } - tc->setMiscReg(MISCREG_IPR_PAL_BASE, PalBase); - tc->setMiscReg(MISCREG_IPR_MCSR, 0x6); - tc->setMiscReg(MISCREG_IPR_PALtemp16, cpuId); + tc->setMiscReg(IPR_PAL_BASE, PalBase); + tc->setMiscReg(IPR_MCSR, 0x6); + tc->setMiscReg(IPR_PALtemp16, cpuId); } @@ -96,13 +96,13 @@ AlphaISA::processInterrupts(CPU *cpu) cpu->checkInterrupts = false; - if (cpu->readMiscReg(MISCREG_IPR_ASTRR)) + if (cpu->readMiscReg(IPR_ASTRR)) panic("asynchronous traps not implemented\n"); - if (cpu->readMiscReg(MISCREG_IPR_SIRR)) { + if (cpu->readMiscReg(IPR_SIRR)) { for (int i = INTLEVEL_SOFTWARE_MIN; i < INTLEVEL_SOFTWARE_MAX; i++) { - if (cpu->readMiscReg(MISCREG_IPR_SIRR) & (ULL(1) << i)) { + if (cpu->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { // See table 4-19 of the 21164 hardware reference ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; summary |= (ULL(1) << i); @@ -123,12 +123,12 @@ AlphaISA::processInterrupts(CPU *cpu) } } - if (ipl && ipl > cpu->readMiscReg(MISCREG_IPR_IPLR)) { - cpu->setMiscReg(MISCREG_IPR_ISR, summary); - cpu->setMiscReg(MISCREG_IPR_INTID, ipl); + if (ipl && ipl > cpu->readMiscReg(IPR_IPLR)) { + cpu->setMiscReg(IPR_ISR, summary); + cpu->setMiscReg(IPR_INTID, ipl); cpu->trap(new InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - cpu->readMiscReg(MISCREG_IPR_IPLR), ipl, summary); + cpu->readMiscReg(IPR_IPLR), ipl, summary); } } @@ -150,7 +150,7 @@ SimpleThread::hwrei() if (!inPalMode()) return new UnimplementedOpcodeFault; - setNextPC(readMiscReg(AlphaISA::MISCREG_IPR_EXC_ADDR)); + setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR)); if (!misspeculating()) { if (kernelStats) @@ -166,13 +166,13 @@ SimpleThread::hwrei() int AlphaISA::MiscRegFile::getInstAsid() { - return EV5::ITB_ASN_ASN(ipr[MISCREG_IPR_ITB_ASN]); + return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); } int AlphaISA::MiscRegFile::getDataAsid() { - return EV5::DTB_ASN_ASN(ipr[MISCREG_IPR_DTB_ASN]); + return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); } AlphaISA::MiscReg @@ -181,71 +181,71 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc) uint64_t retval = 0; // return value, default 0 switch (idx) { - case AlphaISA::MISCREG_IPR_PALtemp0: - case AlphaISA::MISCREG_IPR_PALtemp1: - case AlphaISA::MISCREG_IPR_PALtemp2: - case AlphaISA::MISCREG_IPR_PALtemp3: - case AlphaISA::MISCREG_IPR_PALtemp4: - case AlphaISA::MISCREG_IPR_PALtemp5: - case AlphaISA::MISCREG_IPR_PALtemp6: - case AlphaISA::MISCREG_IPR_PALtemp7: - case AlphaISA::MISCREG_IPR_PALtemp8: - case AlphaISA::MISCREG_IPR_PALtemp9: - case AlphaISA::MISCREG_IPR_PALtemp10: - case AlphaISA::MISCREG_IPR_PALtemp11: - case AlphaISA::MISCREG_IPR_PALtemp12: - case AlphaISA::MISCREG_IPR_PALtemp13: - case AlphaISA::MISCREG_IPR_PALtemp14: - case AlphaISA::MISCREG_IPR_PALtemp15: - case AlphaISA::MISCREG_IPR_PALtemp16: - case AlphaISA::MISCREG_IPR_PALtemp17: - case AlphaISA::MISCREG_IPR_PALtemp18: - case AlphaISA::MISCREG_IPR_PALtemp19: - case AlphaISA::MISCREG_IPR_PALtemp20: - case AlphaISA::MISCREG_IPR_PALtemp21: - case AlphaISA::MISCREG_IPR_PALtemp22: - case AlphaISA::MISCREG_IPR_PALtemp23: - case AlphaISA::MISCREG_IPR_PAL_BASE: - - case AlphaISA::MISCREG_IPR_IVPTBR: - case AlphaISA::MISCREG_IPR_DC_MODE: - case AlphaISA::MISCREG_IPR_MAF_MODE: - case AlphaISA::MISCREG_IPR_ISR: - case AlphaISA::MISCREG_IPR_EXC_ADDR: - case AlphaISA::MISCREG_IPR_IC_PERR_STAT: - case AlphaISA::MISCREG_IPR_DC_PERR_STAT: - case AlphaISA::MISCREG_IPR_MCSR: - case AlphaISA::MISCREG_IPR_ASTRR: - case AlphaISA::MISCREG_IPR_ASTER: - case AlphaISA::MISCREG_IPR_SIRR: - case AlphaISA::MISCREG_IPR_ICSR: - case AlphaISA::MISCREG_IPR_ICM: - case AlphaISA::MISCREG_IPR_DTB_CM: - case AlphaISA::MISCREG_IPR_IPLR: - case AlphaISA::MISCREG_IPR_INTID: - case AlphaISA::MISCREG_IPR_PMCTR: + case AlphaISA::IPR_PALtemp0: + case AlphaISA::IPR_PALtemp1: + case AlphaISA::IPR_PALtemp2: + case AlphaISA::IPR_PALtemp3: + case AlphaISA::IPR_PALtemp4: + case AlphaISA::IPR_PALtemp5: + case AlphaISA::IPR_PALtemp6: + case AlphaISA::IPR_PALtemp7: + case AlphaISA::IPR_PALtemp8: + case AlphaISA::IPR_PALtemp9: + case AlphaISA::IPR_PALtemp10: + case AlphaISA::IPR_PALtemp11: + case AlphaISA::IPR_PALtemp12: + case AlphaISA::IPR_PALtemp13: + case AlphaISA::IPR_PALtemp14: + case AlphaISA::IPR_PALtemp15: + case AlphaISA::IPR_PALtemp16: + case AlphaISA::IPR_PALtemp17: + case AlphaISA::IPR_PALtemp18: + case AlphaISA::IPR_PALtemp19: + case AlphaISA::IPR_PALtemp20: + case AlphaISA::IPR_PALtemp21: + case AlphaISA::IPR_PALtemp22: + case AlphaISA::IPR_PALtemp23: + case AlphaISA::IPR_PAL_BASE: + + case AlphaISA::IPR_IVPTBR: + case AlphaISA::IPR_DC_MODE: + case AlphaISA::IPR_MAF_MODE: + case AlphaISA::IPR_ISR: + case AlphaISA::IPR_EXC_ADDR: + case AlphaISA::IPR_IC_PERR_STAT: + case AlphaISA::IPR_DC_PERR_STAT: + case AlphaISA::IPR_MCSR: + case AlphaISA::IPR_ASTRR: + case AlphaISA::IPR_ASTER: + case AlphaISA::IPR_SIRR: + case AlphaISA::IPR_ICSR: + case AlphaISA::IPR_ICM: + case AlphaISA::IPR_DTB_CM: + case AlphaISA::IPR_IPLR: + case AlphaISA::IPR_INTID: + case AlphaISA::IPR_PMCTR: // no side-effect retval = ipr[idx]; break; - case AlphaISA::MISCREG_IPR_CC: + case AlphaISA::IPR_CC: retval |= ipr[idx] & ULL(0xffffffff00000000); retval |= tc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff); break; - case AlphaISA::MISCREG_IPR_VA: + case AlphaISA::IPR_VA: retval = ipr[idx]; break; - case AlphaISA::MISCREG_IPR_VA_FORM: - case AlphaISA::MISCREG_IPR_MM_STAT: - case AlphaISA::MISCREG_IPR_IFAULT_VA_FORM: - case AlphaISA::MISCREG_IPR_EXC_MASK: - case AlphaISA::MISCREG_IPR_EXC_SUM: + case AlphaISA::IPR_VA_FORM: + case AlphaISA::IPR_MM_STAT: + case AlphaISA::IPR_IFAULT_VA_FORM: + case AlphaISA::IPR_EXC_MASK: + case AlphaISA::IPR_EXC_SUM: retval = ipr[idx]; break; - case AlphaISA::MISCREG_IPR_DTB_PTE: + case AlphaISA::IPR_DTB_PTE: { AlphaISA::PTE &pte = tc->getDTBPtr()->index(!tc->misspeculating()); @@ -260,15 +260,15 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc) break; // write only registers - case AlphaISA::MISCREG_IPR_HWINT_CLR: - case AlphaISA::MISCREG_IPR_SL_XMIT: - case AlphaISA::MISCREG_IPR_DC_FLUSH: - case AlphaISA::MISCREG_IPR_IC_FLUSH: - case AlphaISA::MISCREG_IPR_ALT_MODE: - case AlphaISA::MISCREG_IPR_DTB_IA: - case AlphaISA::MISCREG_IPR_DTB_IAP: - case AlphaISA::MISCREG_IPR_ITB_IA: - case AlphaISA::MISCREG_IPR_ITB_IAP: + case AlphaISA::IPR_HWINT_CLR: + case AlphaISA::IPR_SL_XMIT: + case AlphaISA::IPR_DC_FLUSH: + case AlphaISA::IPR_IC_FLUSH: + case AlphaISA::IPR_ALT_MODE: + case AlphaISA::IPR_DTB_IA: + case AlphaISA::IPR_DTB_IAP: + case AlphaISA::IPR_ITB_IA: + case AlphaISA::IPR_ITB_IAP: fault = new UnimplementedOpcodeFault; break; @@ -295,52 +295,52 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) return NoFault; switch (idx) { - case AlphaISA::MISCREG_IPR_PALtemp0: - case AlphaISA::MISCREG_IPR_PALtemp1: - case AlphaISA::MISCREG_IPR_PALtemp2: - case AlphaISA::MISCREG_IPR_PALtemp3: - case AlphaISA::MISCREG_IPR_PALtemp4: - case AlphaISA::MISCREG_IPR_PALtemp5: - case AlphaISA::MISCREG_IPR_PALtemp6: - case AlphaISA::MISCREG_IPR_PALtemp7: - case AlphaISA::MISCREG_IPR_PALtemp8: - case AlphaISA::MISCREG_IPR_PALtemp9: - case AlphaISA::MISCREG_IPR_PALtemp10: - case AlphaISA::MISCREG_IPR_PALtemp11: - case AlphaISA::MISCREG_IPR_PALtemp12: - case AlphaISA::MISCREG_IPR_PALtemp13: - case AlphaISA::MISCREG_IPR_PALtemp14: - case AlphaISA::MISCREG_IPR_PALtemp15: - case AlphaISA::MISCREG_IPR_PALtemp16: - case AlphaISA::MISCREG_IPR_PALtemp17: - case AlphaISA::MISCREG_IPR_PALtemp18: - case AlphaISA::MISCREG_IPR_PALtemp19: - case AlphaISA::MISCREG_IPR_PALtemp20: - case AlphaISA::MISCREG_IPR_PALtemp21: - case AlphaISA::MISCREG_IPR_PALtemp22: - case AlphaISA::MISCREG_IPR_PAL_BASE: - case AlphaISA::MISCREG_IPR_IC_PERR_STAT: - case AlphaISA::MISCREG_IPR_DC_PERR_STAT: - case AlphaISA::MISCREG_IPR_PMCTR: + case AlphaISA::IPR_PALtemp0: + case AlphaISA::IPR_PALtemp1: + case AlphaISA::IPR_PALtemp2: + case AlphaISA::IPR_PALtemp3: + case AlphaISA::IPR_PALtemp4: + case AlphaISA::IPR_PALtemp5: + case AlphaISA::IPR_PALtemp6: + case AlphaISA::IPR_PALtemp7: + case AlphaISA::IPR_PALtemp8: + case AlphaISA::IPR_PALtemp9: + case AlphaISA::IPR_PALtemp10: + case AlphaISA::IPR_PALtemp11: + case AlphaISA::IPR_PALtemp12: + case AlphaISA::IPR_PALtemp13: + case AlphaISA::IPR_PALtemp14: + case AlphaISA::IPR_PALtemp15: + case AlphaISA::IPR_PALtemp16: + case AlphaISA::IPR_PALtemp17: + case AlphaISA::IPR_PALtemp18: + case AlphaISA::IPR_PALtemp19: + case AlphaISA::IPR_PALtemp20: + case AlphaISA::IPR_PALtemp21: + case AlphaISA::IPR_PALtemp22: + case AlphaISA::IPR_PAL_BASE: + case AlphaISA::IPR_IC_PERR_STAT: + case AlphaISA::IPR_DC_PERR_STAT: + case AlphaISA::IPR_PMCTR: // write entire quad w/ no side-effect ipr[idx] = val; break; - case AlphaISA::MISCREG_IPR_CC_CTL: + case AlphaISA::IPR_CC_CTL: // This IPR resets the cycle counter. We assume this only // happens once... let's verify that. assert(ipr[idx] == 0); ipr[idx] = 1; break; - case AlphaISA::MISCREG_IPR_CC: + case AlphaISA::IPR_CC: // This IPR only writes the upper 64 bits. It's ok to write // all 64 here since we mask out the lower 32 in rpcc (see // isa_desc). ipr[idx] = val; break; - case AlphaISA::MISCREG_IPR_PALtemp23: + case AlphaISA::IPR_PALtemp23: // write entire quad w/ no side-effect old = ipr[idx]; ipr[idx] = val; @@ -348,23 +348,23 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) tc->getKernelStats()->context(old, val, tc); break; - case AlphaISA::MISCREG_IPR_DTB_PTE: + case AlphaISA::IPR_DTB_PTE: // write entire quad w/ no side-effect, tag is forthcoming ipr[idx] = val; break; - case AlphaISA::MISCREG_IPR_EXC_ADDR: + case AlphaISA::IPR_EXC_ADDR: // second least significant bit in PC is always zero ipr[idx] = val & ~2; break; - case AlphaISA::MISCREG_IPR_ASTRR: - case AlphaISA::MISCREG_IPR_ASTER: + case AlphaISA::IPR_ASTRR: + case AlphaISA::IPR_ASTER: // only write least significant four bits - privilege mask ipr[idx] = val & 0xf; break; - case AlphaISA::MISCREG_IPR_IPLR: + case AlphaISA::IPR_IPLR: #ifdef DEBUG if (break_ipl != -1 && break_ipl == (val & 0x1f)) debug_break(); @@ -376,7 +376,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) tc->getKernelStats()->swpipl(ipr[idx]); break; - case AlphaISA::MISCREG_IPR_DTB_CM: + case AlphaISA::IPR_DTB_CM: if (val & 0x18) { if (tc->getKernelStats()) tc->getKernelStats()->mode(Kernel::user, tc); @@ -385,121 +385,121 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) tc->getKernelStats()->mode(Kernel::kernel, tc); } - case AlphaISA::MISCREG_IPR_ICM: + case AlphaISA::IPR_ICM: // only write two mode bits - processor mode ipr[idx] = val & 0x18; break; - case AlphaISA::MISCREG_IPR_ALT_MODE: + case AlphaISA::IPR_ALT_MODE: // only write two mode bits - processor mode ipr[idx] = val & 0x18; break; - case AlphaISA::MISCREG_IPR_MCSR: + case AlphaISA::IPR_MCSR: // more here after optimization... ipr[idx] = val; break; - case AlphaISA::MISCREG_IPR_SIRR: + case AlphaISA::IPR_SIRR: // only write software interrupt mask ipr[idx] = val & 0x7fff0; break; - case AlphaISA::MISCREG_IPR_ICSR: + case AlphaISA::IPR_ICSR: ipr[idx] = val & ULL(0xffffff0300); break; - case AlphaISA::MISCREG_IPR_IVPTBR: - case AlphaISA::MISCREG_IPR_MVPTBR: + case AlphaISA::IPR_IVPTBR: + case AlphaISA::IPR_MVPTBR: ipr[idx] = val & ULL(0xffffffffc0000000); break; - case AlphaISA::MISCREG_IPR_DC_TEST_CTL: + case AlphaISA::IPR_DC_TEST_CTL: ipr[idx] = val & 0x1ffb; break; - case AlphaISA::MISCREG_IPR_DC_MODE: - case AlphaISA::MISCREG_IPR_MAF_MODE: + case AlphaISA::IPR_DC_MODE: + case AlphaISA::IPR_MAF_MODE: ipr[idx] = val & 0x3f; break; - case AlphaISA::MISCREG_IPR_ITB_ASN: + case AlphaISA::IPR_ITB_ASN: ipr[idx] = val & 0x7f0; break; - case AlphaISA::MISCREG_IPR_DTB_ASN: + case AlphaISA::IPR_DTB_ASN: ipr[idx] = val & ULL(0xfe00000000000000); break; - case AlphaISA::MISCREG_IPR_EXC_SUM: - case AlphaISA::MISCREG_IPR_EXC_MASK: + case AlphaISA::IPR_EXC_SUM: + case AlphaISA::IPR_EXC_MASK: // any write to this register clears it ipr[idx] = 0; break; - case AlphaISA::MISCREG_IPR_INTID: - case AlphaISA::MISCREG_IPR_SL_RCV: - case AlphaISA::MISCREG_IPR_MM_STAT: - case AlphaISA::MISCREG_IPR_ITB_PTE_TEMP: - case AlphaISA::MISCREG_IPR_DTB_PTE_TEMP: + case AlphaISA::IPR_INTID: + case AlphaISA::IPR_SL_RCV: + case AlphaISA::IPR_MM_STAT: + case AlphaISA::IPR_ITB_PTE_TEMP: + case AlphaISA::IPR_DTB_PTE_TEMP: // read-only registers return new UnimplementedOpcodeFault; - case AlphaISA::MISCREG_IPR_HWINT_CLR: - case AlphaISA::MISCREG_IPR_SL_XMIT: - case AlphaISA::MISCREG_IPR_DC_FLUSH: - case AlphaISA::MISCREG_IPR_IC_FLUSH: + case AlphaISA::IPR_HWINT_CLR: + case AlphaISA::IPR_SL_XMIT: + case AlphaISA::IPR_DC_FLUSH: + case AlphaISA::IPR_IC_FLUSH: // the following are write only ipr[idx] = val; break; - case AlphaISA::MISCREG_IPR_DTB_IA: + case AlphaISA::IPR_DTB_IA: // really a control write ipr[idx] = 0; tc->getDTBPtr()->flushAll(); break; - case AlphaISA::MISCREG_IPR_DTB_IAP: + case AlphaISA::IPR_DTB_IAP: // really a control write ipr[idx] = 0; tc->getDTBPtr()->flushProcesses(); break; - case AlphaISA::MISCREG_IPR_DTB_IS: + case AlphaISA::IPR_DTB_IS: // really a control write ipr[idx] = val; tc->getDTBPtr()->flushAddr(val, - DTB_ASN_ASN(ipr[AlphaISA::MISCREG_IPR_DTB_ASN])); + DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); break; - case AlphaISA::MISCREG_IPR_DTB_TAG: { + case AlphaISA::IPR_DTB_TAG: { struct AlphaISA::PTE pte; // FIXME: granularity hints NYI... - if (DTB_PTE_GH(ipr[AlphaISA::MISCREG_IPR_DTB_PTE]) != 0) + if (DTB_PTE_GH(ipr[AlphaISA::IPR_DTB_PTE]) != 0) panic("PTE GH field != 0"); // write entire quad ipr[idx] = val; // construct PTE for new entry - pte.ppn = DTB_PTE_PPN(ipr[AlphaISA::MISCREG_IPR_DTB_PTE]); - pte.xre = DTB_PTE_XRE(ipr[AlphaISA::MISCREG_IPR_DTB_PTE]); - pte.xwe = DTB_PTE_XWE(ipr[AlphaISA::MISCREG_IPR_DTB_PTE]); - pte.fonr = DTB_PTE_FONR(ipr[AlphaISA::MISCREG_IPR_DTB_PTE]); - pte.fonw = DTB_PTE_FONW(ipr[AlphaISA::MISCREG_IPR_DTB_PTE]); - pte.asma = DTB_PTE_ASMA(ipr[AlphaISA::MISCREG_IPR_DTB_PTE]); - pte.asn = DTB_ASN_ASN(ipr[AlphaISA::MISCREG_IPR_DTB_ASN]); + pte.ppn = DTB_PTE_PPN(ipr[AlphaISA::IPR_DTB_PTE]); + pte.xre = DTB_PTE_XRE(ipr[AlphaISA::IPR_DTB_PTE]); + pte.xwe = DTB_PTE_XWE(ipr[AlphaISA::IPR_DTB_PTE]); + pte.fonr = DTB_PTE_FONR(ipr[AlphaISA::IPR_DTB_PTE]); + pte.fonw = DTB_PTE_FONW(ipr[AlphaISA::IPR_DTB_PTE]); + pte.asma = DTB_PTE_ASMA(ipr[AlphaISA::IPR_DTB_PTE]); + pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]); // insert new TAG/PTE value into data TLB tc->getDTBPtr()->insert(val, pte); } break; - case AlphaISA::MISCREG_IPR_ITB_PTE: { + case AlphaISA::IPR_ITB_PTE: { struct AlphaISA::PTE pte; // FIXME: granularity hints NYI... @@ -516,33 +516,33 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) pte.fonr = ITB_PTE_FONR(val); pte.fonw = ITB_PTE_FONW(val); pte.asma = ITB_PTE_ASMA(val); - pte.asn = ITB_ASN_ASN(ipr[AlphaISA::MISCREG_IPR_ITB_ASN]); + pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]); // insert new TAG/PTE value into data TLB - tc->getITBPtr()->insert(ipr[AlphaISA::MISCREG_IPR_ITB_TAG], pte); + tc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], pte); } break; - case AlphaISA::MISCREG_IPR_ITB_IA: + case AlphaISA::IPR_ITB_IA: // really a control write ipr[idx] = 0; tc->getITBPtr()->flushAll(); break; - case AlphaISA::MISCREG_IPR_ITB_IAP: + case AlphaISA::IPR_ITB_IAP: // really a control write ipr[idx] = 0; tc->getITBPtr()->flushProcesses(); break; - case AlphaISA::MISCREG_IPR_ITB_IS: + case AlphaISA::IPR_ITB_IS: // really a control write ipr[idx] = val; tc->getITBPtr()->flushAddr(val, - ITB_ASN_ASN(ipr[AlphaISA::MISCREG_IPR_ITB_ASN])); + ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); break; default: diff --git a/src/arch/alpha/ipr.cc b/src/arch/alpha/ipr.cc index 50086a845..8e83102eb 100644 --- a/src/arch/alpha/ipr.cc +++ b/src/arch/alpha/ipr.cc @@ -38,89 +38,89 @@ namespace AlphaISA md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs] = { //Write only - IPR_HWINT_CLR, // H/W interrupt clear register - IPR_SL_XMIT, // serial line transmit register - IPR_DC_FLUSH, - IPR_IC_FLUSH, // instruction cache flush control - IPR_ALT_MODE, // alternate mode register - IPR_DTB_IA, // DTLB invalidate all register - IPR_DTB_IAP, // DTLB invalidate all process register - IPR_ITB_IA, // ITLB invalidate all register - IPR_ITB_IAP, // ITLB invalidate all process register + RAW_IPR_HWINT_CLR, // H/W interrupt clear register + RAW_IPR_SL_XMIT, // serial line transmit register + RAW_IPR_DC_FLUSH, + RAW_IPR_IC_FLUSH, // instruction cache flush control + RAW_IPR_ALT_MODE, // alternate mode register + RAW_IPR_DTB_IA, // DTLB invalidate all register + RAW_IPR_DTB_IAP, // DTLB invalidate all process register + RAW_IPR_ITB_IA, // ITLB invalidate all register + RAW_IPR_ITB_IAP, // ITLB invalidate all process register //Read only - IPR_INTID, // interrupt ID register - IPR_SL_RCV, // serial line receive register - IPR_MM_STAT, // data MMU fault status register - IPR_ITB_PTE_TEMP, // ITLB page table entry temp register - IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register + RAW_IPR_INTID, // interrupt ID register + RAW_IPR_SL_RCV, // serial line receive register + RAW_IPR_MM_STAT, // data MMU fault status register + RAW_IPR_ITB_PTE_TEMP, // ITLB page table entry temp register + RAW_IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register - IPR_ISR, // interrupt summary register - IPR_ITB_TAG, // ITLB tag register - IPR_ITB_PTE, // ITLB page table entry register - IPR_ITB_ASN, // ITLB address space register - IPR_ITB_IS, // ITLB invalidate select register - IPR_SIRR, // software interrupt request register - IPR_ASTRR, // asynchronous system trap request register - IPR_ASTER, // asynchronous system trap enable register - IPR_EXC_ADDR, // exception address register - IPR_EXC_SUM, // exception summary register - IPR_EXC_MASK, // exception mask register - IPR_PAL_BASE, // PAL base address register - IPR_ICM, // instruction current mode - IPR_IPLR, // interrupt priority level register - IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register - IPR_IVPTBR, // virtual page table base register - IPR_ICSR, // instruction control and status register - IPR_IC_PERR_STAT, // inst cache parity error status register - IPR_PMCTR, // performance counter register + RAW_IPR_ISR, // interrupt summary register + RAW_IPR_ITB_TAG, // ITLB tag register + RAW_IPR_ITB_PTE, // ITLB page table entry register + RAW_IPR_ITB_ASN, // ITLB address space register + RAW_IPR_ITB_IS, // ITLB invalidate select register + RAW_IPR_SIRR, // software interrupt request register + RAW_IPR_ASTRR, // asynchronous system trap request register + RAW_IPR_ASTER, // asynchronous system trap enable register + RAW_IPR_EXC_ADDR, // exception address register + RAW_IPR_EXC_SUM, // exception summary register + RAW_IPR_EXC_MASK, // exception mask register + RAW_IPR_PAL_BASE, // PAL base address register + RAW_IPR_ICM, // instruction current mode + RAW_IPR_IPLR, // interrupt priority level register + RAW_IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register + RAW_IPR_IVPTBR, // virtual page table base register + RAW_IPR_ICSR, // instruction control and status register + RAW_IPR_IC_PERR_STAT, // inst cache parity error status register + RAW_IPR_PMCTR, // performance counter register // PAL temporary registers... // register meanings gleaned from osfpal.s source code - IPR_PALtemp0, // local scratch - IPR_PALtemp1, // local scratch - IPR_PALtemp2, // entUna - IPR_PALtemp3, // CPU specific impure area pointer - IPR_PALtemp4, // memory management temp - IPR_PALtemp5, // memory management temp - IPR_PALtemp6, // memory management temp - IPR_PALtemp7, // entIF - IPR_PALtemp8, // intmask - IPR_PALtemp9, // entSys - IPR_PALtemp10, // ?? - IPR_PALtemp11, // entInt - IPR_PALtemp12, // entArith - IPR_PALtemp13, // reserved for platform specific PAL - IPR_PALtemp14, // reserved for platform specific PAL - IPR_PALtemp15, // reserved for platform specific PAL - IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0> - IPR_PALtemp17, // sysval - IPR_PALtemp18, // usp - IPR_PALtemp19, // ksp - IPR_PALtemp20, // PTBR - IPR_PALtemp21, // entMM - IPR_PALtemp22, // kgp - IPR_PALtemp23, // PCBB + RAW_IPR_PALtemp0, // local scratch + RAW_IPR_PALtemp1, // local scratch + RAW_IPR_PALtemp2, // entUna + RAW_IPR_PALtemp3, // CPU specific impure area pointer + RAW_IPR_PALtemp4, // memory management temp + RAW_IPR_PALtemp5, // memory management temp + RAW_IPR_PALtemp6, // memory management temp + RAW_IPR_PALtemp7, // entIF + RAW_IPR_PALtemp8, // intmask + RAW_IPR_PALtemp9, // entSys + RAW_IPR_PALtemp10, // ?? + RAW_IPR_PALtemp11, // entInt + RAW_IPR_PALtemp12, // entArith + RAW_IPR_PALtemp13, // reserved for platform specific PAL + RAW_IPR_PALtemp14, // reserved for platform specific PAL + RAW_IPR_PALtemp15, // reserved for platform specific PAL + RAW_IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0> + RAW_IPR_PALtemp17, // sysval + RAW_IPR_PALtemp18, // usp + RAW_IPR_PALtemp19, // ksp + RAW_IPR_PALtemp20, // PTBR + RAW_IPR_PALtemp21, // entMM + RAW_IPR_PALtemp22, // kgp + RAW_IPR_PALtemp23, // PCBB - IPR_DTB_ASN, // DTLB address space number register - IPR_DTB_CM, // DTLB current mode register - IPR_DTB_TAG, // DTLB tag register - IPR_DTB_PTE, // DTLB page table entry register + RAW_IPR_DTB_ASN, // DTLB address space number register + RAW_IPR_DTB_CM, // DTLB current mode register + RAW_IPR_DTB_TAG, // DTLB tag register + RAW_IPR_DTB_PTE, // DTLB page table entry register - IPR_VA, // fault virtual address register - IPR_VA_FORM, // formatted virtual address register - IPR_MVPTBR, // MTU virtual page table base register - IPR_DTB_IS, // DTLB invalidate single register - IPR_CC, // cycle counter register - IPR_CC_CTL, // cycle counter control register - IPR_MCSR, // MTU control register + RAW_IPR_VA, // fault virtual address register + RAW_IPR_VA_FORM, // formatted virtual address register + RAW_IPR_MVPTBR, // MTU virtual page table base register + RAW_IPR_DTB_IS, // DTLB invalidate single register + RAW_IPR_CC, // cycle counter register + RAW_IPR_CC_CTL, // cycle counter control register + RAW_IPR_MCSR, // MTU control register - IPR_DC_PERR_STAT, // Dcache parity error status register - IPR_DC_TEST_CTL, // Dcache test tag control register - IPR_DC_TEST_TAG, // Dcache test tag register - IPR_DC_TEST_TAG_TEMP, // Dcache test tag temporary register - IPR_DC_MODE, // Dcache mode register - IPR_MAF_MODE // miss address file mode register + RAW_IPR_DC_PERR_STAT, // Dcache parity error status register + RAW_IPR_DC_TEST_CTL, // Dcache test tag control register + RAW_IPR_DC_TEST_TAG, // Dcache test tag register + RAW_IPR_DC_TEST_TAG_TEMP, // Dcache test tag temporary register + RAW_IPR_DC_MODE, // Dcache mode register + RAW_IPR_MAF_MODE // miss address file mode register }; int IprToMiscRegIndex[MaxInternalProcRegs]; diff --git a/src/arch/alpha/ipr.hh b/src/arch/alpha/ipr.hh index dba0733ba..17518c0fe 100644 --- a/src/arch/alpha/ipr.hh +++ b/src/arch/alpha/ipr.hh @@ -40,86 +40,86 @@ namespace AlphaISA // enum md_ipr_names { - IPR_ISR = 0x100, // interrupt summary register - IPR_ITB_TAG = 0x101, // ITLB tag register - IPR_ITB_PTE = 0x102, // ITLB page table entry register - IPR_ITB_ASN = 0x103, // ITLB address space register - IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register - IPR_ITB_IA = 0x105, // ITLB invalidate all register - IPR_ITB_IAP = 0x106, // ITLB invalidate all process register - IPR_ITB_IS = 0x107, // ITLB invalidate select register - IPR_SIRR = 0x108, // software interrupt request register - IPR_ASTRR = 0x109, // asynchronous system trap request register - IPR_ASTER = 0x10a, // asynchronous system trap enable register - IPR_EXC_ADDR = 0x10b, // exception address register - IPR_EXC_SUM = 0x10c, // exception summary register - IPR_EXC_MASK = 0x10d, // exception mask register - IPR_PAL_BASE = 0x10e, // PAL base address register - IPR_ICM = 0x10f, // instruction current mode - IPR_IPLR = 0x110, // interrupt priority level register - IPR_INTID = 0x111, // interrupt ID register - IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register - IPR_IVPTBR = 0x113, // virtual page table base register - IPR_HWINT_CLR = 0x115, // H/W interrupt clear register - IPR_SL_XMIT = 0x116, // serial line transmit register - IPR_SL_RCV = 0x117, // serial line receive register - IPR_ICSR = 0x118, // instruction control and status register - IPR_IC_FLUSH = 0x119, // instruction cache flush control - IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register - IPR_PMCTR = 0x11c, // performance counter register + RAW_IPR_ISR = 0x100, // interrupt summary register + RAW_IPR_ITB_TAG = 0x101, // ITLB tag register + RAW_IPR_ITB_PTE = 0x102, // ITLB page table entry register + RAW_IPR_ITB_ASN = 0x103, // ITLB address space register + RAW_IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register + RAW_IPR_ITB_IA = 0x105, // ITLB invalidate all register + RAW_IPR_ITB_IAP = 0x106, // ITLB invalidate all process register + RAW_IPR_ITB_IS = 0x107, // ITLB invalidate select register + RAW_IPR_SIRR = 0x108, // software interrupt request register + RAW_IPR_ASTRR = 0x109, // asynchronous system trap request register + RAW_IPR_ASTER = 0x10a, // asynchronous system trap enable register + RAW_IPR_EXC_ADDR = 0x10b, // exception address register + RAW_IPR_EXC_SUM = 0x10c, // exception summary register + RAW_IPR_EXC_MASK = 0x10d, // exception mask register + RAW_IPR_PAL_BASE = 0x10e, // PAL base address register + RAW_IPR_ICM = 0x10f, // instruction current mode + RAW_IPR_IPLR = 0x110, // interrupt priority level register + RAW_IPR_INTID = 0x111, // interrupt ID register + RAW_IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register + RAW_IPR_IVPTBR = 0x113, // virtual page table base register + RAW_IPR_HWINT_CLR = 0x115, // H/W interrupt clear register + RAW_IPR_SL_XMIT = 0x116, // serial line transmit register + RAW_IPR_SL_RCV = 0x117, // serial line receive register + RAW_IPR_ICSR = 0x118, // instruction control and status register + RAW_IPR_IC_FLUSH = 0x119, // instruction cache flush control + RAW_IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register + RAW_IPR_PMCTR = 0x11c, // performance counter register // PAL temporary registers... // register meanings gleaned from osfpal.s source code - IPR_PALtemp0 = 0x140, // local scratch - IPR_PALtemp1 = 0x141, // local scratch - IPR_PALtemp2 = 0x142, // entUna - IPR_PALtemp3 = 0x143, // CPU specific impure area pointer - IPR_PALtemp4 = 0x144, // memory management temp - IPR_PALtemp5 = 0x145, // memory management temp - IPR_PALtemp6 = 0x146, // memory management temp - IPR_PALtemp7 = 0x147, // entIF - IPR_PALtemp8 = 0x148, // intmask - IPR_PALtemp9 = 0x149, // entSys - IPR_PALtemp10 = 0x14a, // ?? - IPR_PALtemp11 = 0x14b, // entInt - IPR_PALtemp12 = 0x14c, // entArith - IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL - IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL - IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL - IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0> - IPR_PALtemp17 = 0x151, // sysval - IPR_PALtemp18 = 0x152, // usp - IPR_PALtemp19 = 0x153, // ksp - IPR_PALtemp20 = 0x154, // PTBR - IPR_PALtemp21 = 0x155, // entMM - IPR_PALtemp22 = 0x156, // kgp - IPR_PALtemp23 = 0x157, // PCBB - - IPR_DTB_ASN = 0x200, // DTLB address space number register - IPR_DTB_CM = 0x201, // DTLB current mode register - IPR_DTB_TAG = 0x202, // DTLB tag register - IPR_DTB_PTE = 0x203, // DTLB page table entry register - IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register - - IPR_MM_STAT = 0x205, // data MMU fault status register - IPR_VA = 0x206, // fault virtual address register - IPR_VA_FORM = 0x207, // formatted virtual address register - IPR_MVPTBR = 0x208, // MTU virtual page table base register - IPR_DTB_IAP = 0x209, // DTLB invalidate all process register - IPR_DTB_IA = 0x20a, // DTLB invalidate all register - IPR_DTB_IS = 0x20b, // DTLB invalidate single register - IPR_ALT_MODE = 0x20c, // alternate mode register - IPR_CC = 0x20d, // cycle counter register - IPR_CC_CTL = 0x20e, // cycle counter control register - IPR_MCSR = 0x20f, // MTU control register - - IPR_DC_FLUSH = 0x210, - IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register - IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register - IPR_DC_TEST_TAG = 0x214, // Dcache test tag register - IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register - IPR_DC_MODE = 0x216, // Dcache mode register - IPR_MAF_MODE = 0x217, // miss address file mode register + RAW_IPR_PALtemp0 = 0x140, // local scratch + RAW_IPR_PALtemp1 = 0x141, // local scratch + RAW_IPR_PALtemp2 = 0x142, // entUna + RAW_IPR_PALtemp3 = 0x143, // CPU specific impure area pointer + RAW_IPR_PALtemp4 = 0x144, // memory management temp + RAW_IPR_PALtemp5 = 0x145, // memory management temp + RAW_IPR_PALtemp6 = 0x146, // memory management temp + RAW_IPR_PALtemp7 = 0x147, // entIF + RAW_IPR_PALtemp8 = 0x148, // intmask + RAW_IPR_PALtemp9 = 0x149, // entSys + RAW_IPR_PALtemp10 = 0x14a, // ?? + RAW_IPR_PALtemp11 = 0x14b, // entInt + RAW_IPR_PALtemp12 = 0x14c, // entArith + RAW_IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL + RAW_IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL + RAW_IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL + RAW_IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0> + RAW_IPR_PALtemp17 = 0x151, // sysval + RAW_IPR_PALtemp18 = 0x152, // usp + RAW_IPR_PALtemp19 = 0x153, // ksp + RAW_IPR_PALtemp20 = 0x154, // PTBR + RAW_IPR_PALtemp21 = 0x155, // entMM + RAW_IPR_PALtemp22 = 0x156, // kgp + RAW_IPR_PALtemp23 = 0x157, // PCBB + + RAW_IPR_DTB_ASN = 0x200, // DTLB address space number register + RAW_IPR_DTB_CM = 0x201, // DTLB current mode register + RAW_IPR_DTB_TAG = 0x202, // DTLB tag register + RAW_IPR_DTB_PTE = 0x203, // DTLB page table entry register + RAW_IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register + + RAW_IPR_MM_STAT = 0x205, // data MMU fault status register + RAW_IPR_VA = 0x206, // fault virtual address register + RAW_IPR_VA_FORM = 0x207, // formatted virtual address register + RAW_IPR_MVPTBR = 0x208, // MTU virtual page table base register + RAW_IPR_DTB_IAP = 0x209, // DTLB invalidate all process register + RAW_IPR_DTB_IA = 0x20a, // DTLB invalidate all register + RAW_IPR_DTB_IS = 0x20b, // DTLB invalidate single register + RAW_IPR_ALT_MODE = 0x20c, // alternate mode register + RAW_IPR_CC = 0x20d, // cycle counter register + RAW_IPR_CC_CTL = 0x20e, // cycle counter control register + RAW_IPR_MCSR = 0x20f, // MTU control register + + RAW_IPR_DC_FLUSH = 0x210, + RAW_IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register + RAW_IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register + RAW_IPR_DC_TEST_TAG = 0x214, // Dcache test tag register + RAW_IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register + RAW_IPR_DC_MODE = 0x216, // Dcache mode register + RAW_IPR_MAF_MODE = 0x217, // miss address file mode register MaxInternalProcRegs // number of IPR registers }; @@ -128,92 +128,92 @@ namespace AlphaISA { //Write only MinWriteOnlyIpr, - MISCREG_IPR_HWINT_CLR = MinWriteOnlyIpr, - MISCREG_IPR_SL_XMIT, - MISCREG_IPR_DC_FLUSH, - MISCREG_IPR_IC_FLUSH, - MISCREG_IPR_ALT_MODE, - MISCREG_IPR_DTB_IA, - MISCREG_IPR_DTB_IAP, - MISCREG_IPR_ITB_IA, + IPR_HWINT_CLR = MinWriteOnlyIpr, + IPR_SL_XMIT, + IPR_DC_FLUSH, + IPR_IC_FLUSH, + IPR_ALT_MODE, + IPR_DTB_IA, + IPR_DTB_IAP, + IPR_ITB_IA, MaxWriteOnlyIpr, - MISCREG_IPR_ITB_IAP = MaxWriteOnlyIpr, + IPR_ITB_IAP = MaxWriteOnlyIpr, //Read only MinReadOnlyIpr, - MISCREG_IPR_INTID = MinReadOnlyIpr, - MISCREG_IPR_SL_RCV, - MISCREG_IPR_MM_STAT, - MISCREG_IPR_ITB_PTE_TEMP, + IPR_INTID = MinReadOnlyIpr, + IPR_SL_RCV, + IPR_MM_STAT, + IPR_ITB_PTE_TEMP, MaxReadOnlyIpr, - MISCREG_IPR_DTB_PTE_TEMP = MaxReadOnlyIpr, - - MISCREG_IPR_ISR, - MISCREG_IPR_ITB_TAG, - MISCREG_IPR_ITB_PTE, - MISCREG_IPR_ITB_ASN, - MISCREG_IPR_ITB_IS, - MISCREG_IPR_SIRR, - MISCREG_IPR_ASTRR, - MISCREG_IPR_ASTER, - MISCREG_IPR_EXC_ADDR, - MISCREG_IPR_EXC_SUM, - MISCREG_IPR_EXC_MASK, - MISCREG_IPR_PAL_BASE, - MISCREG_IPR_ICM, - MISCREG_IPR_IPLR, - MISCREG_IPR_IFAULT_VA_FORM, - MISCREG_IPR_IVPTBR, - MISCREG_IPR_ICSR, - MISCREG_IPR_IC_PERR_STAT, - MISCREG_IPR_PMCTR, + IPR_DTB_PTE_TEMP = MaxReadOnlyIpr, + + IPR_ISR, + IPR_ITB_TAG, + IPR_ITB_PTE, + IPR_ITB_ASN, + IPR_ITB_IS, + IPR_SIRR, + IPR_ASTRR, + IPR_ASTER, + IPR_EXC_ADDR, + IPR_EXC_SUM, + IPR_EXC_MASK, + IPR_PAL_BASE, + IPR_ICM, + IPR_IPLR, + IPR_IFAULT_VA_FORM, + IPR_IVPTBR, + IPR_ICSR, + IPR_IC_PERR_STAT, + IPR_PMCTR, // PAL temporary registers... // register meanings gleaned from osfpal.s source code - MISCREG_IPR_PALtemp0, - MISCREG_IPR_PALtemp1, - MISCREG_IPR_PALtemp2, - MISCREG_IPR_PALtemp3, - MISCREG_IPR_PALtemp4, - MISCREG_IPR_PALtemp5, - MISCREG_IPR_PALtemp6, - MISCREG_IPR_PALtemp7, - MISCREG_IPR_PALtemp8, - MISCREG_IPR_PALtemp9, - MISCREG_IPR_PALtemp10, - MISCREG_IPR_PALtemp11, - MISCREG_IPR_PALtemp12, - MISCREG_IPR_PALtemp13, - MISCREG_IPR_PALtemp14, - MISCREG_IPR_PALtemp15, - MISCREG_IPR_PALtemp16, - MISCREG_IPR_PALtemp17, - MISCREG_IPR_PALtemp18, - MISCREG_IPR_PALtemp19, - MISCREG_IPR_PALtemp20, - MISCREG_IPR_PALtemp21, - MISCREG_IPR_PALtemp22, - MISCREG_IPR_PALtemp23, - - MISCREG_IPR_DTB_ASN, - MISCREG_IPR_DTB_CM, - MISCREG_IPR_DTB_TAG, - MISCREG_IPR_DTB_PTE, - - MISCREG_IPR_VA, - MISCREG_IPR_VA_FORM, - MISCREG_IPR_MVPTBR, - MISCREG_IPR_DTB_IS, - MISCREG_IPR_CC, - MISCREG_IPR_CC_CTL, - MISCREG_IPR_MCSR, - - MISCREG_IPR_DC_PERR_STAT, - MISCREG_IPR_DC_TEST_CTL, - MISCREG_IPR_DC_TEST_TAG, - MISCREG_IPR_DC_TEST_TAG_TEMP, - MISCREG_IPR_DC_MODE, - MISCREG_IPR_MAF_MODE, + IPR_PALtemp0, + IPR_PALtemp1, + IPR_PALtemp2, + IPR_PALtemp3, + IPR_PALtemp4, + IPR_PALtemp5, + IPR_PALtemp6, + IPR_PALtemp7, + IPR_PALtemp8, + IPR_PALtemp9, + IPR_PALtemp10, + IPR_PALtemp11, + IPR_PALtemp12, + IPR_PALtemp13, + IPR_PALtemp14, + IPR_PALtemp15, + IPR_PALtemp16, + IPR_PALtemp17, + IPR_PALtemp18, + IPR_PALtemp19, + IPR_PALtemp20, + IPR_PALtemp21, + IPR_PALtemp22, + IPR_PALtemp23, + + IPR_DTB_ASN, + IPR_DTB_CM, + IPR_DTB_TAG, + IPR_DTB_PTE, + + IPR_VA, + IPR_VA_FORM, + IPR_MVPTBR, + IPR_DTB_IS, + IPR_CC, + IPR_CC_CTL, + IPR_MCSR, + + IPR_DC_PERR_STAT, + IPR_DC_TEST_CTL, + IPR_DC_TEST_TAG, + IPR_DC_TEST_TAG_TEMP, + IPR_DC_MODE, + IPR_MAF_MODE, NumInternalProcRegs // number of IPR registers }; -- cgit v1.2.3 From ad201172c957665b65222aae45b2b19f3ac53fab Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 16:59:41 -0500 Subject: We don't include ipr.cc in SE builds, so don't call it. --HG-- extra : convert_revision : 45e52d7afbf74e0ddde11f58aeb084186389fc06 --- src/arch/alpha/regfile.hh | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index 31472ec0e..8980fcb40 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -115,7 +115,9 @@ namespace AlphaISA public: MiscRegFile() { +#if FULL_SYSTEM initializeIprTable(); +#endif } MiscReg readReg(int misc_reg); -- cgit v1.2.3 From fb5ba85abbf3791498faab3328a73b3725dfc839 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 17:50:57 -0500 Subject: Make two simple utility functions to determine if a MiscReg index corresponding to an IPR is readable or writable. --HG-- extra : convert_revision : 89eebba5eec01e629213997d24c734a6acad0ecb --- src/arch/alpha/ipr.hh | 9 +++++++++ src/arch/alpha/isa/decoder.isa | 8 ++------ 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/ipr.hh b/src/arch/alpha/ipr.hh index 17518c0fe..51c1489b8 100644 --- a/src/arch/alpha/ipr.hh +++ b/src/arch/alpha/ipr.hh @@ -218,6 +218,15 @@ namespace AlphaISA NumInternalProcRegs // number of IPR registers }; + inline bool IprIsWritable(int index) + { + return index < minReadOnlyIpr || index > maxReadOnlyIpr; + } + + inline bool IprIsReadable(int index) + { + return index < minWriteOnlyIpr || index > maxWriteOnlyIpr; + } extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs]; extern int IprToMiscRegIndex[MaxInternalProcRegs]; diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 0cbe38ceb..550aa62a3 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -746,9 +746,7 @@ decode OPCODE default Unknown::unknown() { format HwMoveIPR { 1: hw_mfpr({{ int miscRegIndex = IprToMiscRegIndex[ipr_index]; - if(miscRegIndex < 0 || - (miscRegIndex >= MinWriteOnlyIpr && - miscRegIndex <= MaxWriteOnlyIpr)) + if(miscRegIndex < 0 || !IprIsReadable(miscRegIndex)) fault = new UnimplementedOpcodeFault; else Ra = xc->readMiscRegWithEffect(miscRegIndex, fault); @@ -761,9 +759,7 @@ decode OPCODE default Unknown::unknown() { format HwMoveIPR { 1: hw_mtpr({{ int miscRegIndex = IprToMiscRegIndex[ipr_index]; - if(miscRegIndex < 0 || - (miscRegIndex >= MinReadOnlyIpr && - miscRegIndex <= MaxWriteOnlyIpr)) + if(miscRegIndex < 0 || !IprIsWritable(miscRegIndex)) fault = new UnimplementedOpcodeFault; else xc->setMiscRegWithEffect(miscRegIndex, Ra); -- cgit v1.2.3 From 45368c03001690aa7ea697afdbfaca01477fbdb2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 18:01:31 -0500 Subject: Fix stupid typo --HG-- extra : convert_revision : fbfc82974e89b2c726b689674c9f5d957682b280 --- src/arch/alpha/ipr.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/ipr.hh b/src/arch/alpha/ipr.hh index 51c1489b8..b55154764 100644 --- a/src/arch/alpha/ipr.hh +++ b/src/arch/alpha/ipr.hh @@ -220,12 +220,12 @@ namespace AlphaISA inline bool IprIsWritable(int index) { - return index < minReadOnlyIpr || index > maxReadOnlyIpr; + return index < MinReadOnlyIpr || index > MaxReadOnlyIpr; } inline bool IprIsReadable(int index) { - return index < minWriteOnlyIpr || index > maxWriteOnlyIpr; + return index < MinWriteOnlyIpr || index > MaxWriteOnlyIpr; } extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs]; -- cgit v1.2.3 From 39de635fbfa281c2fa70b65833825e2559d029b9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 18:19:45 -0500 Subject: Check for out of range IPR values as well. --HG-- extra : convert_revision : 9ca241bb71d8a1d022e54485383a88d2abece663 --- src/arch/alpha/isa/decoder.isa | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 550aa62a3..e4cf96767 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -745,8 +745,10 @@ decode OPCODE default Unknown::unknown() { 0: OpcdecFault::hw_mfpr(); format HwMoveIPR { 1: hw_mfpr({{ - int miscRegIndex = IprToMiscRegIndex[ipr_index]; - if(miscRegIndex < 0 || !IprIsReadable(miscRegIndex)) + miscRegIndex >= NumInternalProcRegs) + int miscRegIndex = (ipr_index < NumInternalProcRegs) ? + IprToMiscRegIndex[ipr_index] : -1; + if(miscRegIndex < 0 || !IprIsReadable(miscRegIndex) || fault = new UnimplementedOpcodeFault; else Ra = xc->readMiscRegWithEffect(miscRegIndex, fault); @@ -758,7 +760,8 @@ decode OPCODE default Unknown::unknown() { 0: OpcdecFault::hw_mtpr(); format HwMoveIPR { 1: hw_mtpr({{ - int miscRegIndex = IprToMiscRegIndex[ipr_index]; + int miscRegIndex = (ipr_index < NumInternalProcRegs) ? + IprToMiscRegIndex[ipr_index] : -1; if(miscRegIndex < 0 || !IprIsWritable(miscRegIndex)) fault = new UnimplementedOpcodeFault; else -- cgit v1.2.3 From 1dd903e856e2e9995a85ac79e6519ff2d1f4d790 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 18:39:17 -0500 Subject: Fix another typo --HG-- extra : convert_revision : ad7058babf2a13bfe543e05f2662dc49a18a8b8b --- src/arch/alpha/isa/decoder.isa | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index e4cf96767..c5f47aaa2 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -745,7 +745,6 @@ decode OPCODE default Unknown::unknown() { 0: OpcdecFault::hw_mfpr(); format HwMoveIPR { 1: hw_mfpr({{ - miscRegIndex >= NumInternalProcRegs) int miscRegIndex = (ipr_index < NumInternalProcRegs) ? IprToMiscRegIndex[ipr_index] : -1; if(miscRegIndex < 0 || !IprIsReadable(miscRegIndex) || -- cgit v1.2.3 From 1543c3d0a11d77ac82658fdace755a0967d32cbb Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 18:51:26 -0500 Subject: More typos! I need to get nfs to work. --HG-- extra : convert_revision : f5693e96d376254f777fb0cce7b5be3d36efbea9 --- src/arch/alpha/isa/decoder.isa | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index c5f47aaa2..584d64a3d 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -748,6 +748,7 @@ decode OPCODE default Unknown::unknown() { int miscRegIndex = (ipr_index < NumInternalProcRegs) ? IprToMiscRegIndex[ipr_index] : -1; if(miscRegIndex < 0 || !IprIsReadable(miscRegIndex) || + miscRegIndex >= NumInternalProcRegs) fault = new UnimplementedOpcodeFault; else Ra = xc->readMiscRegWithEffect(miscRegIndex, fault); @@ -761,7 +762,8 @@ decode OPCODE default Unknown::unknown() { 1: hw_mtpr({{ int miscRegIndex = (ipr_index < NumInternalProcRegs) ? IprToMiscRegIndex[ipr_index] : -1; - if(miscRegIndex < 0 || !IprIsWritable(miscRegIndex)) + if(miscRegIndex < 0 || !IprIsWritable(miscRegIndex) + miscRegIndex >= NumInternalProcRegs) fault = new UnimplementedOpcodeFault; else xc->setMiscRegWithEffect(miscRegIndex, Ra); -- cgit v1.2.3 From f3ba6d20f6070c30418866e627e2418f39b433dd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 31 Oct 2006 18:59:50 -0500 Subject: Arg! --HG-- extra : convert_revision : 8328d002780c0291e7eb264076a62084de88b7a5 --- src/arch/alpha/isa/decoder.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 584d64a3d..f5483d9c0 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -762,7 +762,7 @@ decode OPCODE default Unknown::unknown() { 1: hw_mtpr({{ int miscRegIndex = (ipr_index < NumInternalProcRegs) ? IprToMiscRegIndex[ipr_index] : -1; - if(miscRegIndex < 0 || !IprIsWritable(miscRegIndex) + if(miscRegIndex < 0 || !IprIsWritable(miscRegIndex) || miscRegIndex >= NumInternalProcRegs) fault = new UnimplementedOpcodeFault; else -- cgit v1.2.3 From 2b11b4735761cdb5fcf32bbe0fb1cd96b7498db0 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 1 Nov 2006 16:44:45 -0500 Subject: Adjustments for the AlphaTLB changing to AlphaISA::TLB and changing register file functions to not take faults --HG-- extra : convert_revision : 1cef0734462ee2e4db12482462c2ab3c134d3675 --- src/arch/alpha/ev5.cc | 17 +++++----- src/arch/alpha/isa/decoder.isa | 8 ++--- src/arch/alpha/isa/fp.isa | 2 +- src/arch/alpha/regfile.hh | 43 +++++++++++------------- src/arch/mips/regfile/misc_regfile.hh | 10 +++--- src/arch/mips/regfile/regfile.hh | 34 +++++++++---------- src/arch/sparc/isa/decoder.isa | 6 ++-- src/arch/sparc/miscregfile.cc | 62 ++++++++++++++++++++++++----------- src/arch/sparc/miscregfile.hh | 16 +++++++++ src/arch/sparc/regfile.cc | 31 ++++++++---------- src/arch/sparc/regfile.hh | 28 ++++++++++------ src/arch/sparc/tlb.hh | 28 ++++++++++++++++ src/cpu/checker/cpu.hh | 23 +++++++------ src/cpu/checker/thread_context.hh | 16 ++++----- src/cpu/exec_context.hh | 6 ++-- src/cpu/o3/alpha/cpu.hh | 16 ++++++--- src/cpu/o3/alpha/cpu_builder.cc | 4 +-- src/cpu/o3/alpha/cpu_impl.hh | 13 ++++---- src/cpu/o3/alpha/dyn_inst.hh | 9 +++-- src/cpu/o3/alpha/params.hh | 11 ++++--- src/cpu/o3/alpha/thread_context.hh | 4 +-- src/cpu/o3/checker_builder.cc | 4 +-- src/cpu/o3/mips/cpu.hh | 7 ++-- src/cpu/o3/mips/cpu_impl.hh | 13 ++++---- src/cpu/o3/mips/dyn_inst.hh | 11 +++---- src/cpu/o3/regfile.hh | 14 ++++---- src/cpu/o3/thread_context.hh | 8 ++--- src/cpu/o3/thread_context_impl.hh | 13 +++----- src/cpu/ozone/checker_builder.cc | 4 +-- src/cpu/ozone/cpu.hh | 17 ++++++---- src/cpu/ozone/cpu_builder.cc | 4 +-- src/cpu/ozone/cpu_impl.hh | 18 ++++------ src/cpu/ozone/dyn_inst.hh | 6 ++-- src/cpu/ozone/dyn_inst_impl.hh | 12 +++---- src/cpu/ozone/simple_cpu_builder.cc | 4 +-- src/cpu/ozone/simple_params.hh | 9 +++-- src/cpu/ozone/thread_state.hh | 10 +++--- src/cpu/simple/base.hh | 8 ++--- src/cpu/simple_thread.hh | 8 ++--- src/cpu/thread_context.hh | 14 ++++---- 40 files changed, 317 insertions(+), 254 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 7595423c3..314b445e0 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -60,7 +60,7 @@ AlphaISA::initCPU(ThreadContext *tc, int cpuId) tc->setIntReg(16, cpuId); tc->setIntReg(0, cpuId); - AlphaFault *reset = new ResetFault; + AlphaISA::AlphaFault *reset = new AlphaISA::ResetFault; tc->setPC(tc->readMiscReg(IPR_PAL_BASE) + reset->vect()); tc->setNextPC(tc->readPC() + sizeof(MachInst)); @@ -176,7 +176,7 @@ AlphaISA::MiscRegFile::getDataAsid() } AlphaISA::MiscReg -AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc) +AlphaISA::MiscRegFile::readIpr(int idx, ThreadContext *tc) { uint64_t retval = 0; // return value, default 0 @@ -269,12 +269,12 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc) case AlphaISA::IPR_DTB_IAP: case AlphaISA::IPR_ITB_IA: case AlphaISA::IPR_ITB_IAP: - fault = new UnimplementedOpcodeFault; + panic("Tried to read write only register %d\n", idx); break; default: // invalid IPR - fault = new UnimplementedOpcodeFault; + panic("Tried to read from invalid ipr %d\n", idx); break; } @@ -286,13 +286,13 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc) int break_ipl = -1; #endif -Fault +void AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) { uint64_t old; if (tc->misspeculating()) - return NoFault; + return; switch (idx) { case AlphaISA::IPR_PALtemp0: @@ -443,7 +443,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) case AlphaISA::IPR_ITB_PTE_TEMP: case AlphaISA::IPR_DTB_PTE_TEMP: // read-only registers - return new UnimplementedOpcodeFault; + panic("Tried to write read only ipr %d\n", idx); case AlphaISA::IPR_HWINT_CLR: case AlphaISA::IPR_SL_XMIT: @@ -547,11 +547,10 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) default: // invalid IPR - return new UnimplementedOpcodeFault; + panic("Tried to write to invalid ipr %d\n", idx); } // no error... - return NoFault; } diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index f5483d9c0..fcf022ce1 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -629,7 +629,7 @@ decode OPCODE default Unknown::unknown() { /* Rb is a fake dependency so here is a fun way to get * the parser to understand that. */ - Ra = xc->readMiscRegWithEffect(AlphaISA::IPR_CC, fault) + (Rb & 0); + Ra = xc->readMiscRegWithEffect(AlphaISA::IPR_CC) + (Rb & 0); #else Ra = curTick; @@ -681,7 +681,7 @@ decode OPCODE default Unknown::unknown() { 0x00: CallPal::call_pal({{ if (!palValid || (palPriv - && xc->readMiscRegWithEffect(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { + && xc->readMiscRegWithEffect(AlphaISA::IPR_ICM) != AlphaISA::mode_kernel)) { // invalid pal function code, or attempt to do privileged // PAL call in non-kernel mode fault = new UnimplementedOpcodeFault; @@ -693,7 +693,7 @@ decode OPCODE default Unknown::unknown() { if (dopal) { xc->setMiscRegWithEffect(AlphaISA::IPR_EXC_ADDR, NPC); - NPC = xc->readMiscRegWithEffect(AlphaISA::IPR_PAL_BASE, fault) + palOffset; + NPC = xc->readMiscRegWithEffect(AlphaISA::IPR_PAL_BASE) + palOffset; } } }}, IsNonSpeculative); @@ -751,7 +751,7 @@ decode OPCODE default Unknown::unknown() { miscRegIndex >= NumInternalProcRegs) fault = new UnimplementedOpcodeFault; else - Ra = xc->readMiscRegWithEffect(miscRegIndex, fault); + Ra = xc->readMiscRegWithEffect(miscRegIndex); }}, IsIprAccess); } } diff --git a/src/arch/alpha/isa/fp.isa b/src/arch/alpha/isa/fp.isa index b4339a1b7..103f85775 100644 --- a/src/arch/alpha/isa/fp.isa +++ b/src/arch/alpha/isa/fp.isa @@ -46,7 +46,7 @@ output exec {{ inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) { Fault fault = NoFault; // dummy... this ipr access should not fault - if (!EV5::ICSR_FPE(xc->readMiscRegWithEffect(AlphaISA::IPR_ICSR, fault))) { + if (!EV5::ICSR_FPE(xc->readMiscRegWithEffect(AlphaISA::IPR_ICSR))) { fault = new FloatEnableFault; } return fault; diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index 8980fcb40..e806adbcb 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -122,17 +122,16 @@ namespace AlphaISA MiscReg readReg(int misc_reg); - MiscReg readRegWithEffect(int misc_reg, Fault &fault, - ThreadContext *tc); + MiscReg readRegWithEffect(int misc_reg, ThreadContext *tc); //These functions should be removed once the simplescalar cpu model //has been replaced. int getInstAsid(); int getDataAsid(); - Fault setReg(int misc_reg, const MiscReg &val); + void setReg(int misc_reg, const MiscReg &val); - Fault setRegWithEffect(int misc_reg, const MiscReg &val, + void setRegWithEffect(int misc_reg, const MiscReg &val, ThreadContext *tc); void clear() @@ -153,9 +152,9 @@ namespace AlphaISA InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs private: - InternalProcReg readIpr(int idx, Fault &fault, ThreadContext *tc); + InternalProcReg readIpr(int idx, ThreadContext *tc); - Fault setIpr(int idx, InternalProcReg val, ThreadContext *tc); + void setIpr(int idx, InternalProcReg val, ThreadContext *tc); #endif friend class RegFile; }; @@ -225,22 +224,20 @@ namespace AlphaISA return miscRegFile.readReg(miscReg); } - MiscReg readMiscRegWithEffect(int miscReg, - Fault &fault, ThreadContext *tc) + MiscReg readMiscRegWithEffect(int miscReg, ThreadContext *tc) { - fault = NoFault; - return miscRegFile.readRegWithEffect(miscReg, fault, tc); + return miscRegFile.readRegWithEffect(miscReg, tc); } - Fault setMiscReg(int miscReg, const MiscReg &val) + void setMiscReg(int miscReg, const MiscReg &val) { - return miscRegFile.setReg(miscReg, val); + miscRegFile.setReg(miscReg, val); } - Fault setMiscRegWithEffect(int miscReg, const MiscReg &val, + void setMiscRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc) { - return miscRegFile.setRegWithEffect(miscReg, val, tc); + miscRegFile.setRegWithEffect(miscReg, val, tc); } FloatReg readFloatReg(int floatReg) @@ -263,26 +260,24 @@ namespace AlphaISA return readFloatRegBits(floatReg); } - Fault setFloatReg(int floatReg, const FloatReg &val) + void setFloatReg(int floatReg, const FloatReg &val) { floatRegFile.d[floatReg] = val; - return NoFault; } - Fault setFloatReg(int floatReg, const FloatReg &val, int width) + void setFloatReg(int floatReg, const FloatReg &val, int width) { - return setFloatReg(floatReg, val); + setFloatReg(floatReg, val); } - Fault setFloatRegBits(int floatReg, const FloatRegBits &val) + void setFloatRegBits(int floatReg, const FloatRegBits &val) { floatRegFile.q[floatReg] = val; - return NoFault; } - Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width) + void setFloatRegBits(int floatReg, const FloatRegBits &val, int width) { - return setFloatRegBits(floatReg, val); + setFloatRegBits(floatReg, val); } IntReg readIntReg(int intReg) @@ -290,9 +285,9 @@ namespace AlphaISA return intRegFile.readReg(intReg); } - Fault setIntReg(int intReg, const IntReg &val) + void setIntReg(int intReg, const IntReg &val) { - return intRegFile.setReg(intReg, val); + intRegFile.setReg(intReg, val); } void serialize(std::ostream &os); diff --git a/src/arch/mips/regfile/misc_regfile.hh b/src/arch/mips/regfile/misc_regfile.hh index a4527a203..368925e00 100644 --- a/src/arch/mips/regfile/misc_regfile.hh +++ b/src/arch/mips/regfile/misc_regfile.hh @@ -220,20 +220,20 @@ namespace MipsISA return miscRegFile[misc_reg]; } - MiscReg readRegWithEffect(int misc_reg, Fault &fault, ThreadContext *tc) + MiscReg readRegWithEffect(int misc_reg, ThreadContext *tc) { return miscRegFile[misc_reg]; } - Fault setReg(int misc_reg, const MiscReg &val) + void setReg(int misc_reg, const MiscReg &val) { - miscRegFile[misc_reg] = val; return NoFault; + miscRegFile[misc_reg] = val; } - Fault setRegWithEffect(int misc_reg, const MiscReg &val, + void setRegWithEffect(int misc_reg, const MiscReg &val, ThreadContext *tc) { - miscRegFile[misc_reg] = val; return NoFault; + miscRegFile[misc_reg] = val; } friend class RegFile; diff --git a/src/arch/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh index 3a18c681b..dee883c4a 100644 --- a/src/arch/mips/regfile/regfile.hh +++ b/src/arch/mips/regfile/regfile.hh @@ -62,22 +62,20 @@ namespace MipsISA return miscRegFile.readReg(miscReg); } - MiscReg readMiscRegWithEffect(int miscReg, - Fault &fault, ThreadContext *tc) + MiscReg readMiscRegWithEffect(int miscReg, ThreadContext *tc) { - fault = NoFault; - return miscRegFile.readRegWithEffect(miscReg, fault, tc); + return miscRegFile.readRegWithEffect(miscReg, tc); } - Fault setMiscReg(int miscReg, const MiscReg &val) + void setMiscReg(int miscReg, const MiscReg &val) { - return miscRegFile.setReg(miscReg, val); + miscRegFile.setReg(miscReg, val); } - Fault setMiscRegWithEffect(int miscReg, const MiscReg &val, + void setMiscRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc) { - return miscRegFile.setRegWithEffect(miscReg, val, tc); + miscRegFile.setRegWithEffect(miscReg, val, tc); } FloatRegVal readFloatReg(int floatReg) @@ -100,24 +98,24 @@ namespace MipsISA return floatRegFile.readRegBits(floatReg,width); } - Fault setFloatReg(int floatReg, const FloatRegVal &val) + void setFloatReg(int floatReg, const FloatRegVal &val) { - return floatRegFile.setReg(floatReg, val, SingleWidth); + floatRegFile.setReg(floatReg, val, SingleWidth); } - Fault setFloatReg(int floatReg, const FloatRegVal &val, int width) + void setFloatReg(int floatReg, const FloatRegVal &val, int width) { - return floatRegFile.setReg(floatReg, val, width); + floatRegFile.setReg(floatReg, val, width); } - Fault setFloatRegBits(int floatReg, const FloatRegBits &val) + void setFloatRegBits(int floatReg, const FloatRegBits &val) { - return floatRegFile.setRegBits(floatReg, val, SingleWidth); + floatRegFile.setRegBits(floatReg, val, SingleWidth); } - Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width) + void setFloatRegBits(int floatReg, const FloatRegBits &val, int width) { - return floatRegFile.setRegBits(floatReg, val, width); + floatRegFile.setRegBits(floatReg, val, width); } IntReg readIntReg(int intReg) @@ -125,9 +123,9 @@ namespace MipsISA return intRegFile.readReg(intReg); } - Fault setIntReg(int intReg, const IntReg &val) + void setIntReg(int intReg, const IntReg &val) { - return intRegFile.setReg(intReg, val); + intRegFile.setReg(intReg, val); } protected: diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index a64ff09bb..a5f43367d 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -353,14 +353,14 @@ decode OP default Unknown::unknown() 0x1: Nop::membar({{/*stuff*/}}); } default: rdasr({{ - Rd = xc->readMiscRegWithEffect(RS1 + AsrStart, fault); + Rd = xc->readMiscRegWithEffect(RS1 + AsrStart); }}); } 0x29: HPriv::rdhpr({{ - Rd = xc->readMiscRegWithEffect(RS1 + HprStart, fault); + Rd = xc->readMiscRegWithEffect(RS1 + HprStart); }}); 0x2A: Priv::rdpr({{ - Rd = xc->readMiscRegWithEffect(RS1 + PrStart, fault); + Rd = xc->readMiscRegWithEffect(RS1 + PrStart); }}); 0x2B: BasicOperate::flushw({{ if(NWindows - 2 - Cansave == 0) diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index bf4572878..2f3cfb417 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -59,20 +59,21 @@ string SparcISA::getMiscRegName(RegIndex index) //XXX These need an implementation someplace /** Fullsystem only register version of ReadRegWithEffect() */ -MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc); +MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext *tc); /** Fullsystem only register version of SetRegWithEffect() */ -Fault MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, +void MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc); #endif void MiscRegFile::reset() { - pstateFields.pef = 0; //No FPU + //pstateFields.pef = 0; //No FPU //pstateFields.pef = 1; //FPU #if FULL_SYSTEM //For SPARC, when a system is first started, there is a power //on reset Trap which sets the processor into the following state. //Bits that aren't set aren't defined on startup. + //XXX this code should be moved into the POR fault. tl = MaxTL; gl = MaxGL; @@ -98,22 +99,6 @@ void MiscRegFile::reset() hintp = 0; // no interrupts pending hstick_cmprFields.int_dis = 1; // disable timer compare interrupts hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing -#else -/* //This sets up the initial state of the processor for usermode processes - pstateFields.priv = 0; //Process runs in user mode - pstateFields.ie = 1; //Interrupts are enabled - fsrFields.rd = 0; //Round to nearest - fsrFields.tem = 0; //Floating point traps not enabled - fsrFields.ns = 0; //Non standard mode off - fsrFields.qne = 0; //Floating point queue is empty - fsrFields.aexc = 0; //No accrued exceptions - fsrFields.cexc = 0; //No current exceptions - - //Register window management registers - otherwin = 0; //No windows contain info from other programs - canrestore = 0; //There are no windows to pop - cansave = MaxTL - 2; //All windows are available to save into - cleanwin = MaxTL;*/ #endif } @@ -337,6 +322,30 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val) } } +inline void MiscRegFile::setImplicitAsis() +{ + //The spec seems to use trap level to indicate the privilege level of the + //processor. It's unclear whether the implicit ASIs should directly depend + //on the trap level, or if they should really be based on the privelege + //bits + if(tl == 0) + { + implicitInstAsi = implicitDataAsi = + pstateFields.cle ? ASI_PRIMARY_LITTLE : ASI_PRIMARY; + } + else if(tl <= MaxPTL) + { + implicitInstAsi = ASI_NUCLEUS; + implicitDataAsi = pstateFields.cle ? ASI_NUCLEUS_LITTLE : ASI_NUCLEUS; + } + else + { + //This is supposed to force physical addresses to match the spec. + //It might not because of context values and partition values. + implicitInstAsi = implicitDataAsi = ASI_REAL; + } +} + void MiscRegFile::setRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc) { @@ -352,6 +361,14 @@ void MiscRegFile::setRegWithEffect(int miscReg, case MISCREG_PCR: //Set up performance counting based on pcr value break; + case MISCREG_PSTATE: + pstate = val; + setImplicitAsis(); + return; + case MISCREG_TL: + tl = val; + setImplicitAsis(); + return; case MISCREG_CWP: tc->changeRegFileContext(CONTEXT_CWP, val); break; @@ -389,6 +406,8 @@ void MiscRegFile::serialize(std::ostream & os) SERIALIZE_ARRAY(htstate, MaxTL); SERIALIZE_SCALAR(htba); SERIALIZE_SCALAR(hstick_cmpr); + SERIALIZE_SCALAR((int)implicitInstAsi); + SERIALIZE_SCALAR((int)implicitDataAsi); } void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) @@ -418,5 +437,10 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) UNSERIALIZE_ARRAY(htstate, MaxTL); UNSERIALIZE_SCALAR(htba); UNSERIALIZE_SCALAR(hstick_cmpr); + int temp; + UNSERIALIZE_SCALAR(temp); + implicitInstAsi = (ASI)temp; + UNSERIALIZE_SCALAR(temp); + implicitDataAsi = (ASI)temp; } diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index 771cb1ed6..ac1ad90b9 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -32,9 +32,11 @@ #ifndef __ARCH_SPARC_MISCREGFILE_HH__ #define __ARCH_SPARC_MISCREGFILE_HH__ +#include "arch/sparc/asi.hh" #include "arch/sparc/faults.hh" #include "arch/sparc/isa_traits.hh" #include "arch/sparc/types.hh" +#include "cpu/cpuevent.hh" #include @@ -329,6 +331,9 @@ namespace SparcISA } fsrFields; }; + ASI implicitInstAsi; + ASI implicitDataAsi; + // These need to check the int_dis field and if 0 then // set appropriate bit in softint and checkinterrutps on the cpu #if FULL_SYSTEM @@ -374,6 +379,16 @@ namespace SparcISA void setRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc); + ASI getInstAsid() + { + return implicitInstAsi; + } + + ASI getDataAsid() + { + return implicitDataAsi; + } + void serialize(std::ostream & os); void unserialize(Checkpoint * cp, const std::string & section); @@ -385,6 +400,7 @@ namespace SparcISA bool isHyperPriv() { return hpstateFields.hpriv; } bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; } bool isNonPriv() { return !isPriv(); } + inline void setImplicitAsis(); }; } diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index 5eb874d39..65e6017da 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -79,24 +79,20 @@ MiscReg RegFile::readMiscReg(int miscReg) return miscRegFile.readReg(miscReg); } -MiscReg RegFile::readMiscRegWithEffect(int miscReg, - Fault &fault, ThreadContext *tc) +MiscReg RegFile::readMiscRegWithEffect(int miscReg, ThreadContext *tc) { - fault = NoFault; return miscRegFile.readRegWithEffect(miscReg, tc); } -Fault RegFile::setMiscReg(int miscReg, const MiscReg &val) +void RegFile::setMiscReg(int miscReg, const MiscReg &val) { miscRegFile.setReg(miscReg, val); - return NoFault; } -Fault RegFile::setMiscRegWithEffect(int miscReg, const MiscReg &val, +void RegFile::setMiscRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc) { miscRegFile.setRegWithEffect(miscReg, val, tc); - return NoFault; } FloatReg RegFile::readFloatReg(int floatReg, int width) @@ -122,27 +118,26 @@ FloatRegBits RegFile::readFloatRegBits(int floatReg) FloatRegFile::SingleWidth); } -Fault RegFile::setFloatReg(int floatReg, const FloatReg &val, int width) +void RegFile::setFloatReg(int floatReg, const FloatReg &val, int width) { - return floatRegFile.setReg(floatReg, val, width); + floatRegFile.setReg(floatReg, val, width); } -Fault RegFile::setFloatReg(int floatReg, const FloatReg &val) +void RegFile::setFloatReg(int floatReg, const FloatReg &val) { //Use the "natural" width of a single float - return setFloatReg(floatReg, val, FloatRegFile::SingleWidth); + setFloatReg(floatReg, val, FloatRegFile::SingleWidth); } -Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val, int width) +void RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val, int width) { - return floatRegFile.setRegBits(floatReg, val, width); + floatRegFile.setRegBits(floatReg, val, width); } -Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val) +void RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val) { //Use the "natural" width of a single float - return floatRegFile.setRegBits(floatReg, val, - FloatRegFile::SingleWidth); + floatRegFile.setRegBits(floatReg, val, FloatRegFile::SingleWidth); } IntReg RegFile::readIntReg(int intReg) @@ -150,9 +145,9 @@ IntReg RegFile::readIntReg(int intReg) return intRegFile.readReg(intReg); } -Fault RegFile::setIntReg(int intReg, const IntReg &val) +void RegFile::setIntReg(int intReg, const IntReg &val) { - return intRegFile.setReg(intReg, val); + intRegFile.setReg(intReg, val); } void RegFile::serialize(std::ostream &os) diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index 500fbbba4..9f33435f6 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -32,7 +32,6 @@ #ifndef __ARCH_SPARC_REGFILE_HH__ #define __ARCH_SPARC_REGFILE_HH__ -#include "arch/sparc/faults.hh" #include "arch/sparc/floatregfile.hh" #include "arch/sparc/intregfile.hh" #include "arch/sparc/isa_traits.hh" @@ -76,14 +75,23 @@ namespace SparcISA MiscReg readMiscReg(int miscReg); - MiscReg readMiscRegWithEffect(int miscReg, - Fault &fault, ThreadContext *tc); + MiscReg readMiscRegWithEffect(int miscReg, ThreadContext *tc); - Fault setMiscReg(int miscReg, const MiscReg &val); + void setMiscReg(int miscReg, const MiscReg &val); - Fault setMiscRegWithEffect(int miscReg, const MiscReg &val, + void setMiscRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc); + ASI instAsid() + { + return miscRegFile.getInstAsid(); + } + + ASI dataAsid() + { + return miscRegFile.getDataAsid(); + } + FloatReg readFloatReg(int floatReg, int width); FloatReg readFloatReg(int floatReg); @@ -92,17 +100,17 @@ namespace SparcISA FloatRegBits readFloatRegBits(int floatReg); - Fault setFloatReg(int floatReg, const FloatReg &val, int width); + void setFloatReg(int floatReg, const FloatReg &val, int width); - Fault setFloatReg(int floatReg, const FloatReg &val); + void setFloatReg(int floatReg, const FloatReg &val); - Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width); + void setFloatRegBits(int floatReg, const FloatRegBits &val, int width); - Fault setFloatRegBits(int floatReg, const FloatRegBits &val); + void setFloatRegBits(int floatReg, const FloatRegBits &val); IntReg readIntReg(int intReg); - Fault setIntReg(int intReg, const IntReg &val); + void setIntReg(int intReg, const IntReg &val); void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh index 35ff08b43..0d42e2c97 100644 --- a/src/arch/sparc/tlb.hh +++ b/src/arch/sparc/tlb.hh @@ -31,5 +31,33 @@ #ifndef __ARCH_SPARC_TLB_HH__ #define __ARCH_SPARC_TLB_HH__ +#include "sim/faults.hh" + +class ThreadContext; + +namespace SparcISA +{ + class TLB + { + }; + + class ITB : public TLB + { + public: + Fault translate(RequestPtr &req, ThreadContext *tc) const + { + return NoFault; + } + }; + + class DTB : public TLB + { + public: + Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const + { + return NoFault; + } + }; +} #endif // __ARCH_SPARC_TLB_HH__ diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 7c01bdc39..0df0147ae 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -47,9 +47,12 @@ // forward declarations #if FULL_SYSTEM +namespace TheISA +{ + class ITB; + class DTB; +} class Processor; -class AlphaITB; -class AlphaDTB; class PhysicalMemory; class RemoteGDB; @@ -96,8 +99,8 @@ class CheckerCPU : public BaseCPU struct Params : public BaseCPU::Params { #if FULL_SYSTEM - AlphaITB *itb; - AlphaDTB *dtb; + TheISA::ITB *itb; + TheISA::DTB *dtb; #else Process *process; #endif @@ -140,8 +143,8 @@ class CheckerCPU : public BaseCPU ThreadContext *tc; - AlphaITB *itb; - AlphaDTB *dtb; + TheISA::ITB *itb; + TheISA::DTB *dtb; #if FULL_SYSTEM Addr dbg_vtophys(Addr addr); @@ -301,19 +304,19 @@ class CheckerCPU : public BaseCPU return thread->readMiscReg(misc_reg); } - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + MiscReg readMiscRegWithEffect(int misc_reg) { - return thread->readMiscRegWithEffect(misc_reg, fault); + return thread->readMiscRegWithEffect(misc_reg); } - Fault setMiscReg(int misc_reg, const MiscReg &val) + void setMiscReg(int misc_reg, const MiscReg &val) { result.integer = val; miscRegIdxs.push(misc_reg); return thread->setMiscReg(misc_reg, val); } - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + void setMiscRegWithEffect(int misc_reg, const MiscReg &val) { miscRegIdxs.push(misc_reg); return thread->setMiscRegWithEffect(misc_reg, val); diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh index b2806d40b..cd399dd22 100644 --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@ -87,9 +87,9 @@ class CheckerThreadContext : public ThreadContext PhysicalMemory *getPhysMemPtr() { return actualTC->getPhysMemPtr(); } - AlphaITB *getITBPtr() { return actualTC->getITBPtr(); } + TheISA::ITB *getITBPtr() { return actualTC->getITBPtr(); } - AlphaDTB *getDTBPtr() { return actualTC->getDTBPtr(); } + TheISA::DTB *getDTBPtr() { return actualTC->getDTBPtr(); } Kernel::Statistics *getKernelStats() { return actualTC->getKernelStats(); } @@ -248,19 +248,19 @@ class CheckerThreadContext : public ThreadContext MiscReg readMiscReg(int misc_reg) { return actualTC->readMiscReg(misc_reg); } - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) - { return actualTC->readMiscRegWithEffect(misc_reg, fault); } + MiscReg readMiscRegWithEffect(int misc_reg) + { return actualTC->readMiscRegWithEffect(misc_reg); } - Fault setMiscReg(int misc_reg, const MiscReg &val) + void setMiscReg(int misc_reg, const MiscReg &val) { checkerTC->setMiscReg(misc_reg, val); - return actualTC->setMiscReg(misc_reg, val); + actualTC->setMiscReg(misc_reg, val); } - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + void setMiscRegWithEffect(int misc_reg, const MiscReg &val) { checkerTC->setMiscRegWithEffect(misc_reg, val); - return actualTC->setMiscRegWithEffect(misc_reg, val); + actualTC->setMiscRegWithEffect(misc_reg, val); } unsigned readStCondFailures() diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh index e28b33193..13f70fa79 100644 --- a/src/cpu/exec_context.hh +++ b/src/cpu/exec_context.hh @@ -101,14 +101,14 @@ class ExecContext { /** Reads a miscellaneous register, handling any architectural * side effects due to reading that register. */ - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault); + MiscReg readMiscRegWithEffect(int misc_reg); /** Sets a miscellaneous register. */ - Fault setMiscReg(int misc_reg, const MiscReg &val); + void setMiscReg(int misc_reg, const MiscReg &val); /** Sets a miscellaneous register, handling any architectural * side effects due to writing that register. */ - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val); + void setMiscRegWithEffect(int misc_reg, const MiscReg &val); /** Records the effective address of the instruction. Only valid * for memory ops. */ diff --git a/src/cpu/o3/alpha/cpu.hh b/src/cpu/o3/alpha/cpu.hh index 474fce02a..01749a2a2 100644 --- a/src/cpu/o3/alpha/cpu.hh +++ b/src/cpu/o3/alpha/cpu.hh @@ -37,6 +37,12 @@ #include "cpu/o3/cpu.hh" #include "sim/byteswap.hh" +namespace TheISA +{ + class ITB; + class DTB; +} + class EndQuiesceEvent; namespace Kernel { class Statistics; @@ -73,9 +79,9 @@ class AlphaO3CPU : public FullO3CPU #if FULL_SYSTEM /** ITB pointer. */ - AlphaITB *itb; + AlphaISA::ITB *itb; /** DTB pointer. */ - AlphaDTB *dtb; + AlphaISA::DTB *dtb; #endif /** Registers statistics. */ @@ -126,15 +132,15 @@ class AlphaO3CPU : public FullO3CPU /** Reads a misc. register, including any side effects the read * might have as defined by the architecture. */ - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault, unsigned tid); + MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid); /** Sets a miscellaneous register. */ - Fault setMiscReg(int misc_reg, const MiscReg &val, unsigned tid); + void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid); /** Sets a misc. register, including any side effects the write * might have as defined by the architecture. */ - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val, unsigned tid); + void setMiscRegWithEffect(int misc_reg, const MiscReg &val, unsigned tid); /** Initiates a squash of all in-flight instructions for a given * thread. The source of the squash is an external update of diff --git a/src/cpu/o3/alpha/cpu_builder.cc b/src/cpu/o3/alpha/cpu_builder.cc index ff123a6f7..a00dd5005 100644 --- a/src/cpu/o3/alpha/cpu_builder.cc +++ b/src/cpu/o3/alpha/cpu_builder.cc @@ -54,8 +54,8 @@ Param activity; #if FULL_SYSTEM SimObjectParam system; Param cpu_id; -SimObjectParam itb; -SimObjectParam dtb; +SimObjectParam itb; +SimObjectParam dtb; Param profile; #else SimObjectVectorParam workload; diff --git a/src/cpu/o3/alpha/cpu_impl.hh b/src/cpu/o3/alpha/cpu_impl.hh index a57c5d9ed..7f10e43c2 100644 --- a/src/cpu/o3/alpha/cpu_impl.hh +++ b/src/cpu/o3/alpha/cpu_impl.hh @@ -198,25 +198,24 @@ AlphaO3CPU::readMiscReg(int misc_reg, unsigned tid) template TheISA::MiscReg -AlphaO3CPU::readMiscRegWithEffect(int misc_reg, Fault &fault, - unsigned tid) +AlphaO3CPU::readMiscRegWithEffect(int misc_reg, unsigned tid) { - return this->regFile.readMiscRegWithEffect(misc_reg, fault, tid); + return this->regFile.readMiscRegWithEffect(misc_reg, tid); } template -Fault +void AlphaO3CPU::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid) { - return this->regFile.setMiscReg(misc_reg, val, tid); + this->regFile.setMiscReg(misc_reg, val, tid); } template -Fault +void AlphaO3CPU::setMiscRegWithEffect(int misc_reg, const MiscReg &val, unsigned tid) { - return this->regFile.setMiscRegWithEffect(misc_reg, val, tid); + this->regFile.setMiscRegWithEffect(misc_reg, val, tid); } template diff --git a/src/cpu/o3/alpha/dyn_inst.hh b/src/cpu/o3/alpha/dyn_inst.hh index 31a6f7753..e711de510 100644 --- a/src/cpu/o3/alpha/dyn_inst.hh +++ b/src/cpu/o3/alpha/dyn_inst.hh @@ -102,14 +102,13 @@ class AlphaDynInst : public BaseDynInst /** Reads a misc. register, including any side-effects the read * might have as defined by the architecture. */ - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + MiscReg readMiscRegWithEffect(int misc_reg) { - return this->cpu->readMiscRegWithEffect(misc_reg, fault, - this->threadNumber); + return this->cpu->readMiscRegWithEffect(misc_reg, this->threadNumber); } /** Sets a misc. register. */ - Fault setMiscReg(int misc_reg, const MiscReg &val) + void setMiscReg(int misc_reg, const MiscReg &val) { this->instResult.integer = val; return this->cpu->setMiscReg(misc_reg, val, this->threadNumber); @@ -118,7 +117,7 @@ class AlphaDynInst : public BaseDynInst /** Sets a misc. register, including any side-effects the write * might have as defined by the architecture. */ - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + void setMiscRegWithEffect(int misc_reg, const MiscReg &val) { return this->cpu->setMiscRegWithEffect(misc_reg, val, this->threadNumber); diff --git a/src/cpu/o3/alpha/params.hh b/src/cpu/o3/alpha/params.hh index c618cee08..b6b84b2a1 100644 --- a/src/cpu/o3/alpha/params.hh +++ b/src/cpu/o3/alpha/params.hh @@ -35,8 +35,11 @@ #include "cpu/o3/params.hh" //Forward declarations -class AlphaDTB; -class AlphaITB; +namespace AlphaISA +{ + class DTB; + class ITB; +} class MemObject; class Process; class System; @@ -52,8 +55,8 @@ class AlphaSimpleParams : public O3Params public: #if FULL_SYSTEM - AlphaITB *itb; - AlphaDTB *dtb; + AlphaISA::ITB *itb; + AlphaISA::DTB *dtb; #endif }; diff --git a/src/cpu/o3/alpha/thread_context.hh b/src/cpu/o3/alpha/thread_context.hh index 70a09940f..f0cecee35 100644 --- a/src/cpu/o3/alpha/thread_context.hh +++ b/src/cpu/o3/alpha/thread_context.hh @@ -37,10 +37,10 @@ class AlphaTC : public O3ThreadContext public: #if FULL_SYSTEM /** Returns a pointer to the ITB. */ - virtual AlphaITB *getITBPtr() { return this->cpu->itb; } + virtual AlphaISA::ITB *getITBPtr() { return this->cpu->itb; } /** Returns a pointer to the DTB. */ - virtual AlphaDTB *getDTBPtr() { return this->cpu->dtb; } + virtual AlphaISA::DTB *getDTBPtr() { return this->cpu->dtb; } /** Returns pointer to the quiesce event. */ virtual EndQuiesceEvent *getQuiesceEvent() diff --git a/src/cpu/o3/checker_builder.cc b/src/cpu/o3/checker_builder.cc index 02c817499..8b028e3a0 100644 --- a/src/cpu/o3/checker_builder.cc +++ b/src/cpu/o3/checker_builder.cc @@ -67,8 +67,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker) Param progress_interval; #if FULL_SYSTEM - SimObjectParam itb; - SimObjectParam dtb; + SimObjectParam itb; + SimObjectParam dtb; SimObjectParam system; Param cpu_id; Param profile; diff --git a/src/cpu/o3/mips/cpu.hh b/src/cpu/o3/mips/cpu.hh index bf04b9f69..7e6268cdf 100755 --- a/src/cpu/o3/mips/cpu.hh +++ b/src/cpu/o3/mips/cpu.hh @@ -92,16 +92,15 @@ class MipsO3CPU : public FullO3CPU /** Reads a misc. register, including any side effects the read * might have as defined by the architecture. */ - TheISA::MiscReg readMiscRegWithEffect(int misc_reg, - Fault &fault, unsigned tid); + TheISA::MiscReg readMiscRegWithEffect(int misc_reg, unsigned tid); /** Sets a miscellaneous register. */ - Fault setMiscReg(int misc_reg, const TheISA::MiscReg &val, unsigned tid); + void setMiscReg(int misc_reg, const TheISA::MiscReg &val, unsigned tid); /** Sets a misc. register, including any side effects the write * might have as defined by the architecture. */ - Fault setMiscRegWithEffect(int misc_reg, + void setMiscRegWithEffect(int misc_reg, const TheISA::MiscReg &val, unsigned tid); /** Initiates a squash of all in-flight instructions for a given diff --git a/src/cpu/o3/mips/cpu_impl.hh b/src/cpu/o3/mips/cpu_impl.hh index e08741626..5633acee1 100644 --- a/src/cpu/o3/mips/cpu_impl.hh +++ b/src/cpu/o3/mips/cpu_impl.hh @@ -156,25 +156,24 @@ MipsO3CPU::readMiscReg(int misc_reg, unsigned tid) template MiscReg -MipsO3CPU::readMiscRegWithEffect(int misc_reg, Fault &fault, - unsigned tid) +MipsO3CPU::readMiscRegWithEffect(int misc_reg, unsigned tid) { - return this->regFile.readMiscRegWithEffect(misc_reg, fault, tid); + return this->regFile.readMiscRegWithEffect(misc_reg, tid); } template -Fault +void MipsO3CPU::setMiscReg(int misc_reg, const MiscReg &val, unsigned tid) { - return this->regFile.setMiscReg(misc_reg, val, tid); + this->regFile.setMiscReg(misc_reg, val, tid); } template -Fault +void MipsO3CPU::setMiscRegWithEffect(int misc_reg, const MiscReg &val, unsigned tid) { - return this->regFile.setMiscRegWithEffect(misc_reg, val, tid); + this->regFile.setMiscRegWithEffect(misc_reg, val, tid); } template diff --git a/src/cpu/o3/mips/dyn_inst.hh b/src/cpu/o3/mips/dyn_inst.hh index aa30bfa1e..9e95b2bfb 100755 --- a/src/cpu/o3/mips/dyn_inst.hh +++ b/src/cpu/o3/mips/dyn_inst.hh @@ -103,23 +103,22 @@ class MipsDynInst : public BaseDynInst /** Reads a misc. register, including any side-effects the read * might have as defined by the architecture. */ - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + MiscReg readMiscRegWithEffect(int misc_reg) { - return this->cpu->readMiscRegWithEffect(misc_reg, fault, - this->threadNumber); + return this->cpu->readMiscRegWithEffect(misc_reg, this->threadNumber); } /** Sets a misc. register. */ - Fault setMiscReg(int misc_reg, const MiscReg &val) + void setMiscReg(int misc_reg, const MiscReg &val) { this->instResult.integer = val; - return this->cpu->setMiscReg(misc_reg, val, this->threadNumber); + this->cpu->setMiscReg(misc_reg, val, this->threadNumber); } /** Sets a misc. register, including any side-effects the write * might have as defined by the architecture. */ - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + void setMiscRegWithEffect(int misc_reg, const MiscReg &val) { return this->cpu->setMiscRegWithEffect(misc_reg, val, this->threadNumber); diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh index 10f6db390..29ee19e49 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -37,7 +37,6 @@ #include "base/trace.hh" #include "config/full_system.hh" #include "cpu/o3/comm.hh" -#include "sim/faults.hh" #if FULL_SYSTEM #include "kern/kernel_stats.hh" @@ -232,22 +231,21 @@ class PhysRegFile return miscRegs[thread_id].readReg(misc_reg); } - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault, - unsigned thread_id) + MiscReg readMiscRegWithEffect(int misc_reg, unsigned thread_id) { - return miscRegs[thread_id].readRegWithEffect(misc_reg, fault, + return miscRegs[thread_id].readRegWithEffect(misc_reg, cpu->tcBase(thread_id)); } - Fault setMiscReg(int misc_reg, const MiscReg &val, unsigned thread_id) + void setMiscReg(int misc_reg, const MiscReg &val, unsigned thread_id) { - return miscRegs[thread_id].setReg(misc_reg, val); + miscRegs[thread_id].setReg(misc_reg, val); } - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val, + void setMiscRegWithEffect(int misc_reg, const MiscReg &val, unsigned thread_id) { - return miscRegs[thread_id].setRegWithEffect(misc_reg, val, + miscRegs[thread_id].setRegWithEffect(misc_reg, val, cpu->tcBase(thread_id)); } diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index 9ca02b9f3..4556c5e22 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -201,15 +201,15 @@ class O3ThreadContext : public ThreadContext /** Reads a misc. register, including any side-effects the * read might have as defined by the architecture. */ - virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) - { return cpu->readMiscRegWithEffect(misc_reg, fault, thread->readTid()); } + virtual MiscReg readMiscRegWithEffect(int misc_reg) + { return cpu->readMiscRegWithEffect(misc_reg, thread->readTid()); } /** Sets a misc. register. */ - virtual Fault setMiscReg(int misc_reg, const MiscReg &val); + virtual void setMiscReg(int misc_reg, const MiscReg &val); /** Sets a misc. register, including any side-effects the * write might have as defined by the architecture. */ - virtual Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val); + virtual void setMiscRegWithEffect(int misc_reg, const MiscReg &val); /** Returns the number of consecutive store conditional failures. */ // @todo: Figure out where these store cond failures should go. diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index 2bc194d53..81750ada7 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -439,33 +439,28 @@ O3ThreadContext::setNextPC(uint64_t val) } template -Fault +void O3ThreadContext::setMiscReg(int misc_reg, const MiscReg &val) { - Fault ret_fault = cpu->setMiscReg(misc_reg, val, thread->readTid()); + cpu->setMiscReg(misc_reg, val, thread->readTid()); // Squash if we're not already in a state update mode. if (!thread->trapPending && !thread->inSyscall) { cpu->squashFromTC(thread->readTid()); } - - return ret_fault; } template -Fault +void O3ThreadContext::setMiscRegWithEffect(int misc_reg, const MiscReg &val) { - Fault ret_fault = cpu->setMiscRegWithEffect(misc_reg, val, - thread->readTid()); + cpu->setMiscRegWithEffect(misc_reg, val, thread->readTid()); // Squash if we're not already in a state update mode. if (!thread->trapPending && !thread->inSyscall) { cpu->squashFromTC(thread->readTid()); } - - return ret_fault; } #if !FULL_SYSTEM diff --git a/src/cpu/ozone/checker_builder.cc b/src/cpu/ozone/checker_builder.cc index b4c4686b7..9ad1e639f 100644 --- a/src/cpu/ozone/checker_builder.cc +++ b/src/cpu/ozone/checker_builder.cc @@ -68,8 +68,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(OzoneChecker) Param progress_interval; #if FULL_SYSTEM - SimObjectParam itb; - SimObjectParam dtb; + SimObjectParam itb; + SimObjectParam dtb; SimObjectParam system; Param cpu_id; Param profile; diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh index bd46b198b..14c32620b 100644 --- a/src/cpu/ozone/cpu.hh +++ b/src/cpu/ozone/cpu.hh @@ -51,8 +51,11 @@ #if FULL_SYSTEM #include "arch/alpha/tlb.hh" -class AlphaITB; -class AlphaDTB; +namespace TheISA +{ + class ITB; + class DTB; +} class PhysicalMemory; class MemoryController; @@ -120,9 +123,9 @@ class OzoneCPU : public BaseCPU PhysicalMemory *getPhysMemPtr() { return cpu->physmem; } - AlphaITB *getITBPtr() { return cpu->itb; } + TheISA::ITB *getITBPtr() { return cpu->itb; } - AlphaDTB * getDTBPtr() { return cpu->dtb; } + TheISA::DTB * getDTBPtr() { return cpu->dtb; } Kernel::Statistics *getKernelStats() { return thread->getKernelStats(); } @@ -224,11 +227,11 @@ class OzoneCPU : public BaseCPU // ISA stuff: MiscReg readMiscReg(int misc_reg); - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault); + MiscReg readMiscRegWithEffect(int misc_reg); - Fault setMiscReg(int misc_reg, const MiscReg &val); + void setMiscReg(int misc_reg, const MiscReg &val); - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val); + void setMiscRegWithEffect(int misc_reg, const MiscReg &val); unsigned readStCondFailures() { return thread->storeCondFailures; } diff --git a/src/cpu/ozone/cpu_builder.cc b/src/cpu/ozone/cpu_builder.cc index 730158258..8a572ba38 100644 --- a/src/cpu/ozone/cpu_builder.cc +++ b/src/cpu/ozone/cpu_builder.cc @@ -61,8 +61,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(DerivOzoneCPU) #if FULL_SYSTEM SimObjectParam system; Param cpu_id; -SimObjectParam itb; -SimObjectParam dtb; +SimObjectParam itb; +SimObjectParam dtb; Param profile; #else SimObjectVectorParam workload; diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh index bf547bf94..b34b061d9 100644 --- a/src/cpu/ozone/cpu_impl.hh +++ b/src/cpu/ozone/cpu_impl.hh @@ -1156,37 +1156,31 @@ OzoneCPU::OzoneTC::readMiscReg(int misc_reg) template TheISA::MiscReg -OzoneCPU::OzoneTC::readMiscRegWithEffect(int misc_reg, Fault &fault) +OzoneCPU::OzoneTC::readMiscRegWithEffect(int misc_reg) { - return thread->miscRegFile.readRegWithEffect(misc_reg, - fault, this); + return thread->miscRegFile.readRegWithEffect(misc_reg, this); } template -Fault +void OzoneCPU::OzoneTC::setMiscReg(int misc_reg, const MiscReg &val) { // Needs to setup a squash event unless we're in syscall mode - Fault ret_fault = thread->miscRegFile.setReg(misc_reg, val); + thread->miscRegFile.setReg(misc_reg, val); if (!thread->inSyscall) { cpu->squashFromTC(); } - - return ret_fault; } template -Fault +void OzoneCPU::OzoneTC::setMiscRegWithEffect(int misc_reg, const MiscReg &val) { // Needs to setup a squash event unless we're in syscall mode - Fault ret_fault = thread->miscRegFile.setRegWithEffect(misc_reg, val, - this); + thread->miscRegFile.setRegWithEffect(misc_reg, val, this); if (!thread->inSyscall) { cpu->squashFromTC(); } - - return ret_fault; } diff --git a/src/cpu/ozone/dyn_inst.hh b/src/cpu/ozone/dyn_inst.hh index d3871568a..532317b08 100644 --- a/src/cpu/ozone/dyn_inst.hh +++ b/src/cpu/ozone/dyn_inst.hh @@ -230,11 +230,11 @@ class OzoneDynInst : public BaseDynInst // ISA stuff MiscReg readMiscReg(int misc_reg); - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault); + MiscReg readMiscRegWithEffect(int misc_reg); - Fault setMiscReg(int misc_reg, const MiscReg &val); + void setMiscReg(int misc_reg, const MiscReg &val); - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val); + void setMiscRegWithEffect(int misc_reg, const MiscReg &val); #if FULL_SYSTEM Fault hwrei(); diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh index d86f2dc8b..68736ae61 100644 --- a/src/cpu/ozone/dyn_inst_impl.hh +++ b/src/cpu/ozone/dyn_inst_impl.hh @@ -223,24 +223,24 @@ OzoneDynInst::readMiscReg(int misc_reg) template TheISA::MiscReg -OzoneDynInst::readMiscRegWithEffect(int misc_reg, Fault &fault) +OzoneDynInst::readMiscRegWithEffect(int misc_reg) { - return this->thread->readMiscRegWithEffect(misc_reg, fault); + return this->thread->readMiscRegWithEffect(misc_reg); } template -Fault +void OzoneDynInst::setMiscReg(int misc_reg, const MiscReg &val) { this->setIntResult(val); - return this->thread->setMiscReg(misc_reg, val); + this->thread->setMiscReg(misc_reg, val); } template -Fault +void OzoneDynInst::setMiscRegWithEffect(int misc_reg, const MiscReg &val) { - return this->thread->setMiscRegWithEffect(misc_reg, val); + this->thread->setMiscRegWithEffect(misc_reg, val); } #if FULL_SYSTEM diff --git a/src/cpu/ozone/simple_cpu_builder.cc b/src/cpu/ozone/simple_cpu_builder.cc index baaf7c708..e7214d2ba 100644 --- a/src/cpu/ozone/simple_cpu_builder.cc +++ b/src/cpu/ozone/simple_cpu_builder.cc @@ -64,8 +64,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleOzoneCPU) #if FULL_SYSTEM SimObjectParam system; Param cpu_id; -SimObjectParam itb; -SimObjectParam dtb; +SimObjectParam itb; +SimObjectParam dtb; #else SimObjectVectorParam workload; //SimObjectParam page_table; diff --git a/src/cpu/ozone/simple_params.hh b/src/cpu/ozone/simple_params.hh index 3f63d2e1d..3473b088c 100644 --- a/src/cpu/ozone/simple_params.hh +++ b/src/cpu/ozone/simple_params.hh @@ -34,8 +34,11 @@ #include "cpu/ozone/cpu.hh" //Forward declarations -class AlphaDTB; -class AlphaITB; +namespace TheISA +{ + class DTB; + class ITB; +} class FUPool; class MemObject; class PageTable; @@ -53,7 +56,7 @@ class SimpleParams : public BaseCPU::Params public: #if FULL_SYSTEM - AlphaITB *itb; AlphaDTB *dtb; + TheISA::ITB *itb; TheISA::DTB *dtb; #else std::vector workload; #endif // FULL_SYSTEM diff --git a/src/cpu/ozone/thread_state.hh b/src/cpu/ozone/thread_state.hh index 985e09b52..ec51251b7 100644 --- a/src/cpu/ozone/thread_state.hh +++ b/src/cpu/ozone/thread_state.hh @@ -120,19 +120,19 @@ struct OzoneThreadState : public ThreadState { return miscRegFile.readReg(misc_reg); } - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + MiscReg readMiscRegWithEffect(int misc_reg) { return miscRegFile.readRegWithEffect(misc_reg, fault, tc); } - Fault setMiscReg(int misc_reg, const MiscReg &val) + void setMiscReg(int misc_reg, const MiscReg &val) { - return miscRegFile.setReg(misc_reg, val); + miscRegFile.setReg(misc_reg, val); } - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + void setMiscRegWithEffect(int misc_reg, const MiscReg &val) { - return miscRegFile.setRegWithEffect(misc_reg, val, tc); + miscRegFile.setRegWithEffect(misc_reg, val, tc); } uint64_t readPC() diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 1d208b8df..5c8d569bb 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -288,17 +288,17 @@ class BaseSimpleCPU : public BaseCPU return thread->readMiscReg(misc_reg); } - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + MiscReg readMiscRegWithEffect(int misc_reg) { - return thread->readMiscRegWithEffect(misc_reg, fault); + return thread->readMiscRegWithEffect(misc_reg); } - Fault setMiscReg(int misc_reg, const MiscReg &val) + void setMiscReg(int misc_reg, const MiscReg &val) { return thread->setMiscReg(misc_reg, val); } - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + void setMiscRegWithEffect(int misc_reg, const MiscReg &val) { return thread->setMiscRegWithEffect(misc_reg, val); } diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index d005b2914..20f7f0d1c 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -420,17 +420,17 @@ class SimpleThread : public ThreadState return regs.readMiscReg(misc_reg); } - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + MiscReg readMiscRegWithEffect(int misc_reg) { - return regs.readMiscRegWithEffect(misc_reg, fault, tc); + return regs.readMiscRegWithEffect(misc_reg, tc); } - Fault setMiscReg(int misc_reg, const MiscReg &val) + void setMiscReg(int misc_reg, const MiscReg &val) { return regs.setMiscReg(misc_reg, val); } - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + void setMiscRegWithEffect(int misc_reg, const MiscReg &val) { return regs.setMiscRegWithEffect(misc_reg, val, tc); } diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index 448d67d02..dfc6fbc2a 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -224,11 +224,11 @@ class ThreadContext virtual MiscReg readMiscReg(int misc_reg) = 0; - virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) = 0; + virtual MiscReg readMiscRegWithEffect(int misc_reg) = 0; - virtual Fault setMiscReg(int misc_reg, const MiscReg &val) = 0; + virtual void setMiscReg(int misc_reg, const MiscReg &val) = 0; - virtual Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) = 0; + virtual void setMiscRegWithEffect(int misc_reg, const MiscReg &val) = 0; // Also not necessarily the best location for these two. Hopefully will go // away once we decide upon where st cond failures goes. @@ -410,13 +410,13 @@ class ProxyThreadContext : public ThreadContext MiscReg readMiscReg(int misc_reg) { return actualTC->readMiscReg(misc_reg); } - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) - { return actualTC->readMiscRegWithEffect(misc_reg, fault); } + MiscReg readMiscRegWithEffect(int misc_reg) + { return actualTC->readMiscRegWithEffect(misc_reg); } - Fault setMiscReg(int misc_reg, const MiscReg &val) + void setMiscReg(int misc_reg, const MiscReg &val) { return actualTC->setMiscReg(misc_reg, val); } - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + void setMiscRegWithEffect(int misc_reg, const MiscReg &val) { return actualTC->setMiscRegWithEffect(misc_reg, val); } unsigned readStCondFailures() -- cgit v1.2.3 From 6f78d494101e0ebd542d8fe836df21d104374c33 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 1 Nov 2006 18:46:18 -0500 Subject: Fix a range check on the ipr_index. --HG-- extra : convert_revision : 84e25abd4bb2de0c877c883804d39feb019c7030 --- src/arch/alpha/isa/decoder.isa | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index fcf022ce1..be6f574a9 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -745,7 +745,7 @@ decode OPCODE default Unknown::unknown() { 0: OpcdecFault::hw_mfpr(); format HwMoveIPR { 1: hw_mfpr({{ - int miscRegIndex = (ipr_index < NumInternalProcRegs) ? + int miscRegIndex = (ipr_index < MaxInternalProcRegs) ? IprToMiscRegIndex[ipr_index] : -1; if(miscRegIndex < 0 || !IprIsReadable(miscRegIndex) || miscRegIndex >= NumInternalProcRegs) @@ -760,7 +760,7 @@ decode OPCODE default Unknown::unknown() { 0: OpcdecFault::hw_mtpr(); format HwMoveIPR { 1: hw_mtpr({{ - int miscRegIndex = (ipr_index < NumInternalProcRegs) ? + int miscRegIndex = (ipr_index < MaxInternalProcRegs) ? IprToMiscRegIndex[ipr_index] : -1; if(miscRegIndex < 0 || !IprIsWritable(miscRegIndex) || miscRegIndex >= NumInternalProcRegs) -- cgit v1.2.3 From 8dbab9f701150cf93d33f2a21d6b556507f3d617 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 1 Nov 2006 19:00:49 -0500 Subject: Added code to handle draining. --HG-- extra : convert_revision : 3861f553bde5865cd21a8a58a4c410896726f0a3 --- src/mem/bus.cc | 17 +++++++++++++++++ src/mem/bus.hh | 4 ++++ 2 files changed, 21 insertions(+) (limited to 'src') diff --git a/src/mem/bus.cc b/src/mem/bus.cc index 86a148f87..41dc9acbf 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -239,6 +239,9 @@ Bus::recvRetry(int id) busIdle.reschedule(tickNextIdle); } } + //If we weren't able to drain before, we might be able to now. + if (drainEvent && retryList.size() == 0 && curTick >= tickNextIdle) + drainEvent->process(); } } @@ -498,6 +501,20 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id) } } +unsigned int +Bus::drain(Event * de) +{ + //We should check that we're not "doing" anything, and that noone is + //waiting. We might be idle but have someone waiting if the device we + //contacted for a retry didn't actually retry. + if (curTick >= tickNextIdle && retryList.size() == 0) { + drainEvent = de; + return 1; + } else { + return 0; + } +} + BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bus) Param bus_id; diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 9fb33b7c3..71067032d 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -59,6 +59,8 @@ class Bus : public MemObject /** the next tick at which the bus will be idle */ Tick tickNextIdle; + Event * drainEvent; + static const int defaultId = -3; //Make it unique from Broadcast struct DevMap { @@ -247,6 +249,8 @@ class Bus : public MemObject virtual void init(); + unsigned int drain(Event *de); + Bus(const std::string &n, int bus_id, int _clock, int _width) : MemObject(n), busId(bus_id), clock(_clock), width(_width), tickNextIdle(0), busIdle(this), inRetry(false), defaultPort(NULL) -- cgit v1.2.3 From ccaf80cc46fb86639ab5ee166baca08277f5450f Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 2 Nov 2006 13:11:38 -0500 Subject: Use ISA specific makeExtMI. src/arch/alpha/utility.hh: For now makeExtMI will be specific to the ISA. --HG-- extra : convert_revision : 89959c6499efcc3df9301ad8ea039580764a1496 --- src/arch/alpha/utility.hh | 6 +++--- src/cpu/checker/cpu_impl.hh | 5 +++++ src/cpu/o3/fetch_impl.hh | 6 +++++- src/cpu/ozone/front_end_impl.hh | 4 ++++ src/cpu/simple/base.cc | 4 ++++ 5 files changed, 21 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh index 0304d1c3a..cb86c7e9e 100644 --- a/src/arch/alpha/utility.hh +++ b/src/arch/alpha/utility.hh @@ -43,11 +43,11 @@ namespace AlphaISA { static inline ExtMachInst - makeExtMI(MachInst inst, ThreadContext * xc) { + makeExtMI(MachInst inst, Addr pc) { #if FULL_SYSTEM ExtMachInst ext_inst = inst; - if (xc->readPC() && 0x1) - return ext_inst|=(static_cast(xc->readPC() & 0x1) << 32); + if (pc && 0x1) + return ext_inst|=(static_cast(pc & 0x1) << 32); else return ext_inst; #else diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh index 36c7349e6..56e13dd1e 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -199,8 +199,13 @@ Checker::verify(DynInstPtr &completed_inst) // Checks both the machine instruction and the PC. validateInst(inst); +#if THE_ISA == ALPHA_ISA + curStaticInst = StaticInst::decode(makeExtMI(machInst, + thread->readPC())); +#elif THE_ISA == SPARC_ISA curStaticInst = StaticInst::decode(makeExtMI(machInst, thread->getTC())); +#endif #if FULL_SYSTEM thread->setInst(machInst); diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 2b152e376..31f3b96d6 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -1117,7 +1117,11 @@ DefaultFetch::fetch(bool &status_change) inst = TheISA::gtoh(*reinterpret_cast (&cacheData[tid][offset])); - ext_inst = TheISA::makeExtMI(inst, cpu->tcBase(tid)); +#if THE_ISA == ALPHA_ISA + ext_inst = TheISA::makeExtMI(inst, fetch_PC); +#elif THE_ISA == SPARC_ISA + ext_inst = TheISA::makeExtMI(inst, cpu->thread[tid]->getTC()); +#endif // Create a new DynInst from the instruction fetched. DynInstPtr instruction = new DynInst(ext_inst, fetch_PC, diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh index 63cf0a952..6d02c58cb 100644 --- a/src/cpu/ozone/front_end_impl.hh +++ b/src/cpu/ozone/front_end_impl.hh @@ -882,7 +882,11 @@ FrontEnd::getInstFromCacheline() // Get the instruction from the array of the cache line. inst = htog(*reinterpret_cast(&cacheData[offset])); +#if THE_ISA == ALPHA_ISA + ExtMachInst decode_inst = TheISA::makeExtMI(inst, PC); +#elif THE_ISA == SPARC_ISA ExtMachInst decode_inst = TheISA::makeExtMI(inst, tc); +#endif // Create a new DynInst from the instruction fetched. DynInstPtr instruction = new DynInst(decode_inst, PC, PC+sizeof(MachInst), diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 47b3b938f..6a2c0bbe9 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -398,7 +398,11 @@ BaseSimpleCPU::preExecute() inst = gtoh(inst); //If we're not in the middle of a macro instruction if (!curMacroStaticInst) { +#if THE_ISA == ALPHA_ISA + StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->readPC())); +#elif THE_ISA == SPARC_ISA StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC())); +#endif if (instPtr->isMacroOp()) { curMacroStaticInst = instPtr; curStaticInst = curMacroStaticInst-> -- cgit v1.2.3 From 64f8cd12c6a613205196bbe9dbc0fab98c4ca735 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 2 Nov 2006 13:12:36 -0500 Subject: Remove function that should have been deleted. src/cpu/simple_thread.cc: This function should have been deleted from an earlier push. src/cpu/simple_thread.hh: Delete this function; it's now in thread_state.hh/.cc. --HG-- extra : convert_revision : f78dcf9c2b388418030d48d0ea4911c8b8b1f5ff --- src/cpu/simple_thread.cc | 20 -------------------- src/cpu/simple_thread.hh | 2 -- 2 files changed, 22 deletions(-) (limited to 'src') diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index c89a13eef..28d8bdf62 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -323,25 +323,5 @@ SimpleThread::delVirtPort(VirtualPort *vp) } } -#else -TranslatingPort * -SimpleThread::getMemPort() -{ - if (port != NULL) - return port; - - /* Use this port to for syscall emulation writes to memory. */ - Port *dcache_port; - port = new TranslatingPort(csprintf("%s-%d-funcport", - cpu->name(), tid), - process->pTable, false); - dcache_port = cpu->getPort("dcache_port"); - assert(dcache_port != NULL); - dcache_port = dcache_port->getPeer(); -// mem_port->setPeer(port); - port->setPeer(dcache_port); - return port; -} - #endif diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index f002cbdce..20001063a 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -173,8 +173,6 @@ class SimpleThread : public ThreadState bool simPalCheck(int palFunc); #else - // Override this function. - TranslatingPort *getMemPort(); Fault translateInstReq(RequestPtr &req) { -- cgit v1.2.3 From dd5e2cd959e61b8af094137f337e999048317ec3 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 2 Nov 2006 14:58:31 -0500 Subject: More proper handling of the ports. src/cpu/simple_thread.cc: Fix up port handling to share code. src/cpu/thread_state.cc: Separate code off into a function. src/cpu/thread_state.hh: Make a separate function that will get the CPU's memory's functional port. --HG-- extra : convert_revision : 96a9bb3c5e4b9ba5511678c0fd17f0017c8cd312 --- src/cpu/simple_thread.cc | 10 ++++++---- src/cpu/thread_state.cc | 31 +++++++++++++++++++++++++------ src/cpu/thread_state.hh | 9 +++++++++ 3 files changed, 40 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 28d8bdf62..f5fa68529 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -129,6 +129,10 @@ SimpleThread::SimpleThread() SimpleThread::~SimpleThread() { +#if FULL_SYSTEM + delete physPort; + delete virtPort; +#endif delete tc; } @@ -304,11 +308,9 @@ SimpleThread::getVirtPort(ThreadContext *src_tc) if (!src_tc) return virtPort; - VirtualPort *vp; - Port *mem_port; + VirtualPort *vp = new VirtualPort("tc-vport", src_tc); + Port *mem_port = getMemFuncPort(); - vp = new VirtualPort("tc-vport", src_tc); - mem_port = system->physmem->getPort("functional"); mem_port->setPeer(vp); vp->setPeer(mem_port); return vp; diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc index f81b78147..a6fff5fc3 100644 --- a/src/cpu/thread_state.cc +++ b/src/cpu/thread_state.cc @@ -59,6 +59,16 @@ ThreadState::ThreadState(BaseCPU *cpu, int _cpuId, int _tid, Process *_process, numLoad = 0; } +ThreadState::~ThreadState() +{ +#if !FULL_SYSTEM + if (port) { + delete port->getPeer(); + delete port; + } +#endif +} + void ThreadState::serialize(std::ostream &os) { @@ -124,11 +134,24 @@ ThreadState::getMemPort() return port; /* Use this port to for syscall emulation writes to memory. */ - Port *dcache_port, *func_mem_port; port = new TranslatingPort(csprintf("%s-%d-funcport", baseCpu->name(), tid), process->pTable, false); + Port *func_port = getMemFuncPort(); + + func_port->setPeer(port); + port->setPeer(func_port); + + return port; +} +#endif + +Port * +ThreadState::getMemFuncPort() +{ + Port *dcache_port, *func_mem_port; + dcache_port = baseCpu->getPort("dcache_port"); assert(dcache_port != NULL); @@ -138,9 +161,5 @@ ThreadState::getMemPort() func_mem_port = mem_object->getPort("functional"); assert(func_mem_port != NULL); - func_mem_port->setPeer(port); - port->setPeer(func_mem_port); - - return port; + return func_mem_port; } -#endif diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh index 14673aabb..862d671f2 100644 --- a/src/cpu/thread_state.hh +++ b/src/cpu/thread_state.hh @@ -51,6 +51,7 @@ namespace Kernel { class BaseCPU; class Checkpoint; +class Port; class TranslatingPort; /** @@ -69,6 +70,8 @@ struct ThreadState { short _asid); #endif + ~ThreadState(); + void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); @@ -136,6 +139,12 @@ struct ThreadState { /** Sets the status of this thread. */ void setStatus(Status new_status) { _status = new_status; } + protected: + /** Gets a functional port from the memory object that's connected + * to the CPU. */ + Port *getMemFuncPort(); + + public: /** Number of instructions committed. */ Counter numInst; /** Stat for number instructions committed. */ -- cgit v1.2.3 From 8d53f298a6efd3312cc1096b13b6be9e6a7fe02f Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 2 Nov 2006 15:17:45 -0500 Subject: Caches return a new functional port whenever asked for one. src/mem/cache/base_cache.cc: Have caches return a new functional port whenever asked for them. I'm pretty sure this is desired behavior. Ron can correct me if it's not. --HG-- extra : convert_revision : e1fadf895a7d714968128ff900d10e86fde53387 --- src/mem/cache/base_cache.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 47d40a490..1c519fb86 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -357,9 +357,7 @@ BaseCache::getPort(const std::string &if_name, int idx) } else if (if_name == "functional") { - if(cpuSidePort == NULL) - cpuSidePort = new CachePort(name() + "-cpu_side_port", this, true); - return cpuSidePort; + return new CachePort(name() + "-cpu_side_port", this, true); } else if (if_name == "cpu_side") { -- cgit v1.2.3 From c3485a654888f641dca23128f8197ef747c706d2 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 2 Nov 2006 15:18:35 -0500 Subject: Implement device that will return BadAddress. --HG-- extra : convert_revision : d833c20f691e01c84a0678f19f7d83f3ee50c0c1 --- src/dev/isa_fake.cc | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/dev/isa_fake.hh | 17 +++++++++++++++ 2 files changed, 80 insertions(+) (limited to 'src') diff --git a/src/dev/isa_fake.cc b/src/dev/isa_fake.cc index 23761cd10..ccc9a1f7c 100644 --- a/src/dev/isa_fake.cc +++ b/src/dev/isa_fake.cc @@ -88,6 +88,38 @@ IsaFake::write(PacketPtr pkt) return pioDelay; } +BadAddr::BadAddr(Params *p) + : BasicPioDevice(p) +{ +} + +void +BadAddr::init() +{ + // Only init this device if it's connected to anything. + if (pioPort) + PioDevice::init(); +} + +Tick +BadAddr::read(PacketPtr pkt) +{ + assert(pkt->result == Packet::Unknown); + DPRINTF(Tsunami, "read to bad address va=%#x size=%d\n", + pkt->getAddr(), pkt->getSize()); + pkt->result = Packet::BadAddress; + return pioDelay; +} + +Tick +BadAddr::write(PacketPtr pkt) +{ + DPRINTF(Tsunami, "write to bad address va=%#x size=%d \n", + pkt->getAddr(), pkt->getSize()); + pkt->result = Packet::BadAddress; + return pioDelay; +} + BEGIN_DECLARE_SIM_OBJECT_PARAMS(IsaFake) Param pio_addr; @@ -121,3 +153,34 @@ CREATE_SIM_OBJECT(IsaFake) } REGISTER_SIM_OBJECT("IsaFake", IsaFake) + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(BadAddr) + + Param pio_addr; + Param pio_latency; + SimObjectParam platform; + SimObjectParam system; + +END_DECLARE_SIM_OBJECT_PARAMS(BadAddr) + +BEGIN_INIT_SIM_OBJECT_PARAMS(BadAddr) + + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object") + +END_INIT_SIM_OBJECT_PARAMS(BadAddr) + +CREATE_SIM_OBJECT(BadAddr) +{ + BadAddr::Params *p = new BadAddr::Params; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + return new BadAddr(p); +} + +REGISTER_SIM_OBJECT("BadAddr", BadAddr) diff --git a/src/dev/isa_fake.hh b/src/dev/isa_fake.hh index 366061c25..6665f1a78 100644 --- a/src/dev/isa_fake.hh +++ b/src/dev/isa_fake.hh @@ -79,4 +79,21 @@ class IsaFake : public BasicPioDevice virtual Tick write(PacketPtr pkt); }; +/** + * BadAddr is a device that fills the packet's result field with "BadAddress". + * @todo: Consider consolidating with IsaFake and similar classes. + */ +class BadAddr : public BasicPioDevice +{ + public: + struct Params : public BasicPioDevice::Params + { + }; + + BadAddr(Params *p); + virtual void init(); + virtual Tick read(PacketPtr pkt); + virtual Tick write(PacketPtr pkt); +}; + #endif // __TSUNAMI_FAKE_HH__ -- cgit v1.2.3 From 45363ea658251df0c31a75d7bd5d0ac3a3809623 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 2 Nov 2006 15:20:37 -0500 Subject: Have bus use the BadAddress device to handle bad addresses. The O3 CPU should be able to boot into Linux with caches on after this change. src/mem/bus.cc: src/mem/bus.hh: Bus now will be setup with a default responder, unless the user overrides it. This default responder should return BadAddress if no matching port is found. src/python/m5/objects/Bus.py: Bus now has a default responder for FS mode if the user doesn't override it. It returns BadAddress if no matching port is found. src/python/m5/objects/Tsunami.py: Add bad address device. Also record when the user has specified their own default responder. --HG-- extra : convert_revision : 59070477ae313ee711b2d59baa2369c9a91c5b85 --- src/mem/bus.cc | 37 ++++++++++++++++++++++++++----------- src/mem/bus.hh | 9 +++++++-- src/python/m5/objects/Bus.py | 10 +++++++++- src/python/m5/objects/Tsunami.py | 4 ++++ 4 files changed, 46 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/mem/bus.cc b/src/mem/bus.cc index 86a148f87..7ae41e11e 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -42,13 +42,14 @@ Port * Bus::getPort(const std::string &if_name, int idx) { - if (if_name == "default") + if (if_name == "default") { if (defaultPort == NULL) { defaultPort = new BusPort(csprintf("%s-default",name()), this, - defaultId); + defaultId); return defaultPort; } else fatal("Default port already set\n"); + } // if_name ignored? forced to be empty? int id = interfaces.size(); @@ -269,7 +270,16 @@ Bus::findPort(Addr addr, int id) return defaultPort; } } - panic("Unable to find destination for addr: %#llx", addr); + + if (responderSet) { + panic("Unable to find destination for addr (user set default " + "responder): %#llx", addr); + } else { + DPRINTF(Bus, "Unable to find destination for addr: %#llx, will use " + "default port", addr); + + return defaultPort; + } } @@ -392,12 +402,15 @@ Bus::recvStatusChange(Port::Status status, int id) if (id == defaultId) { defaultRange.clear(); - defaultPort->getPeerAddressRanges(ranges, snoops); - assert(snoops.size() == 0); - for(iter = ranges.begin(); iter != ranges.end(); iter++) { - defaultRange.push_back(*iter); - DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n", - iter->start, iter->end); + // Only try to update these ranges if the user set a default responder. + if (responderSet) { + defaultPort->getPeerAddressRanges(ranges, snoops); + assert(snoops.size() == 0); + for(iter = ranges.begin(); iter != ranges.end(); iter++) { + defaultRange.push_back(*iter); + DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n", + iter->start, iter->end); + } } } else { @@ -503,18 +516,20 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bus) Param bus_id; Param clock; Param width; + Param responder_set; END_DECLARE_SIM_OBJECT_PARAMS(Bus) BEGIN_INIT_SIM_OBJECT_PARAMS(Bus) INIT_PARAM(bus_id, "a globally unique bus id"), INIT_PARAM(clock, "bus clock speed"), - INIT_PARAM(width, "width of the bus (bits)") + INIT_PARAM(width, "width of the bus (bits)"), + INIT_PARAM(responder_set, "Is a default responder set by the user") END_INIT_SIM_OBJECT_PARAMS(Bus) CREATE_SIM_OBJECT(Bus) { - return new Bus(getInstanceName(), bus_id, clock, width); + return new Bus(getInstanceName(), bus_id, clock, width, responder_set); } REGISTER_SIM_OBJECT("Bus", Bus) diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 7ec7e6830..619720a79 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -240,6 +240,9 @@ class Bus : public MemObject /** Port that handles requests that don't match any of the interfaces.*/ BusPort *defaultPort; + /** Has the user specified their own default responder? */ + bool responderSet; + public: /** A function used to return the port associated with this bus object. */ @@ -247,9 +250,11 @@ class Bus : public MemObject virtual void init(); - Bus(const std::string &n, int bus_id, int _clock, int _width) + Bus(const std::string &n, int bus_id, int _clock, int _width, + bool responder_set) : MemObject(n), busId(bus_id), clock(_clock), width(_width), - tickNextIdle(0), busIdle(this), inRetry(false), defaultPort(NULL) + tickNextIdle(0), busIdle(this), inRetry(false), defaultPort(NULL), + responderSet(responder_set) { //Both the width and clock period must be positive if (width <= 0) diff --git a/src/python/m5/objects/Bus.py b/src/python/m5/objects/Bus.py index 6710111e5..e7019f3ac 100644 --- a/src/python/m5/objects/Bus.py +++ b/src/python/m5/objects/Bus.py @@ -1,10 +1,18 @@ +from m5 import build_env from m5.params import * +from m5.proxy import * from MemObject import MemObject +from Tsunami import BadAddr class Bus(MemObject): type = 'Bus' port = VectorPort("vector port for connecting devices") - default = Port("Default port for requests that aren't handeled by a device.") bus_id = Param.Int(0, "blah") clock = Param.Clock("1GHz", "bus clock speed") width = Param.Int(64, "bus width (bytes)") + responder_set = Param.Bool(False, "Did the user specify a default responder.") + if build_env['FULL_SYSTEM']: + default = Port(Self.responder.pio, "Default port for requests that aren't handled by a device.") + responder = BadAddr(pio_addr=0x0, pio_latency="1ps") + else: + default = Port("Default port for requests that aren't handled by a device.") diff --git a/src/python/m5/objects/Tsunami.py b/src/python/m5/objects/Tsunami.py index 0b53153a0..42bcab089 100644 --- a/src/python/m5/objects/Tsunami.py +++ b/src/python/m5/objects/Tsunami.py @@ -15,6 +15,9 @@ class IsaFake(BasicPioDevice): type = 'IsaFake' pio_size = Param.Addr(0x8, "Size of address range") +class BadAddr(BasicPioDevice): + type = 'BadAddr' + class TsunamiIO(BasicPioDevice): type = 'TsunamiIO' time = Param.UInt64(1136073600, @@ -70,6 +73,7 @@ class Tsunami(Platform): self.cchip.pio = bus.port self.pchip.pio = bus.port self.pciconfig.pio = bus.default + bus.responder_set = True self.fake_sm_chip.pio = bus.port self.fake_uart1.pio = bus.port self.fake_uart2.pio = bus.port -- cgit v1.2.3 From fa918329000c3661a4c6840f952c3247522eb826 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 01:15:31 -0500 Subject: Fixed a comment --HG-- extra : convert_revision : bebc701508e1d38ee74a07377c634d5e46e89abe --- src/arch/sparc/asi.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/sparc/asi.hh b/src/arch/sparc/asi.hh index 876567225..6677b23df 100644 --- a/src/arch/sparc/asi.hh +++ b/src/arch/sparc/asi.hh @@ -219,4 +219,4 @@ namespace SparcISA }; -#endif // __ARCH_SPARC_TLB_HH__ +#endif // __ARCH_SPARC_ASI_HH__ -- cgit v1.2.3 From c8fc116c7636893517254f785707eba1726d3265 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 02:25:39 -0500 Subject: Add a new file which describes an ISA's interrupt handling mechanism. It records when interrupts are requested, and returns an interrupt to execute if the --HG-- extra : convert_revision : c535000a6a170caefd441687b60f940513d29739 --- src/arch/SConscript | 1 + src/arch/alpha/interrupts.hh | 171 +++++++++++++++++++++++++++++++++++++++++++ src/cpu/base.cc | 43 ++--------- src/cpu/base.hh | 18 +++-- src/cpu/o3/alpha/cpu_impl.hh | 48 +----------- src/cpu/simple/base.cc | 37 +--------- 6 files changed, 194 insertions(+), 124 deletions(-) create mode 100644 src/arch/alpha/interrupts.hh (limited to 'src') diff --git a/src/arch/SConscript b/src/arch/SConscript index dda1dea53..092fad225 100644 --- a/src/arch/SConscript +++ b/src/arch/SConscript @@ -49,6 +49,7 @@ sources = [] isa_switch_hdrs = Split(''' arguments.hh faults.hh + interrupts.hh isa_traits.hh locked_mem.hh process.hh diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh new file mode 100644 index 000000000..2f031f434 --- /dev/null +++ b/src/arch/alpha/interrupts.hh @@ -0,0 +1,171 @@ +/* + * Copyright (c) 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 + * Kevin Lim + */ + +#ifndef __ARCH_ALPHA_INTERRUPT_HH__ +#define __ARCH_ALPHA_INTERRUPT_HH__ + +#include "arch/alpha/faults.hh" +#include "arch/alpha/isa_traits.hh" +#include "cpu/thread_context.hh" + +namespace AlphaISA +{ + class Interrupts + { + protected: + uint64_t interrupts[NumInterruptLevels]; + uint64_t intstatus; + + public: + Interrupts() + { + memset(interrupts, 0, sizeof(interrupts)); + intstatus = 0; + } + + void post(int int_num, int index) + { + DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); + + if (int_num < 0 || int_num >= NumInterruptLevels) + panic("int_num out of bounds\n"); + + if (index < 0 || index >= sizeof(uint64_t) * 8) + panic("int_num out of bounds\n"); + + interrupts[int_num] |= 1 << index; + intstatus |= (ULL(1) << int_num); + } + + void clear(int int_num, int index) + { + DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); + + if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) + panic("int_num out of bounds\n"); + + if (index < 0 || index >= sizeof(uint64_t) * 8) + panic("int_num out of bounds\n"); + + interrupts[int_num] &= ~(1 << index); + if (interrupts[int_num] == 0) + intstatus &= ~(ULL(1) << int_num); + } + + void clear_all() + { + DPRINTF(Interrupt, "Interrupts all cleared\n"); + + memset(interrupts, 0, sizeof(interrupts)); + intstatus = 0; + } + + bool check_interrupt(int int_num) const { + if (int_num > NumInterruptLevels) + panic("int_num out of bounds\n"); + + return interrupts[int_num] != 0; + } + + bool check_interrupts() const { return intstatus != 0; } + + void serialize(std::ostream &os) + { + SERIALIZE_ARRAY(interrupts, NumInterruptLevels); + SERIALIZE_SCALAR(intstatus); + } + + void unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels); + UNSERIALIZE_SCALAR(intstatus); + } + + Fault getInterrupt(ThreadContext * tc) + { + int ipl = 0; + int summary = 0; + + if (tc->readMiscReg(IPR_ASTRR)) + panic("asynchronous traps not implemented\n"); + + if (tc->readMiscReg(IPR_SIRR)) { + for (int i = INTLEVEL_SOFTWARE_MIN; + i < INTLEVEL_SOFTWARE_MAX; i++) { + if (tc->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { + // See table 4-19 of 21164 hardware reference + ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; + summary |= (ULL(1) << i); + } + } + } + + uint64_t interrupts = intstatus; + if (interrupts) { + for (int i = INTLEVEL_EXTERNAL_MIN; + i < INTLEVEL_EXTERNAL_MAX; i++) { + if (interrupts & (ULL(1) << i)) { + // See table 4-19 of 21164 hardware reference + ipl = i; + summary |= (ULL(1) << i); + } + } + } + + if (ipl && ipl > tc->readMiscReg(IPR_IPLR)) { + tc->setMiscReg(IPR_ISR, summary); + tc->setMiscReg(IPR_INTID, ipl); + + /* The following needs to be added back in somehow */ + // Checker needs to know these two registers were updated. +/*#if USE_CHECKER + if (this->checker) { + this->checker->threadBase()->setMiscReg(IPR_ISR, summary); + this->checker->threadBase()->setMiscReg(IPR_INTID, ipl); + } +#endif*/ + + DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", + tc->readMiscReg(IPR_IPLR), ipl, summary); + + return new InterruptFault; + } else { + return NoFault; + } + } + + private: + uint64_t intr_status() const { return intstatus; } + }; +} + +#endif + diff --git a/src/cpu/base.cc b/src/cpu/base.cc index ea4b03bf2..66c5d3e11 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -168,11 +168,6 @@ BaseCPU::BaseCPU(Params *p) p->max_loads_all_threads, *counter); } -#if FULL_SYSTEM - memset(interrupts, 0, sizeof(interrupts)); - intstatus = 0; -#endif - functionTracingEnabled = false; if (p->functionTrace) { functionTraceStream = simout.find(csprintf("ftrace.%s", name())); @@ -314,9 +309,7 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) } #if FULL_SYSTEM - for (int i = 0; i < TheISA::NumInterruptLevels; ++i) - interrupts[i] = oldCPU->interrupts[i]; - intstatus = oldCPU->intstatus; + interrupts = oldCPU->interrupts; checkInterrupts = oldCPU->checkInterrupts; for (int i = 0; i < threadContexts.size(); ++i) @@ -348,57 +341,33 @@ BaseCPU::ProfileEvent::process() void BaseCPU::post_interrupt(int int_num, int index) { - DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); - - if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) - panic("int_num out of bounds\n"); - - if (index < 0 || index >= sizeof(uint64_t) * 8) - panic("int_num out of bounds\n"); - checkInterrupts = true; - interrupts[int_num] |= 1 << index; - intstatus |= (ULL(1) << int_num); + interrupts.post(int_num, index); } void BaseCPU::clear_interrupt(int int_num, int index) { - DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); - - if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) - panic("int_num out of bounds\n"); - - if (index < 0 || index >= sizeof(uint64_t) * 8) - panic("int_num out of bounds\n"); - - interrupts[int_num] &= ~(1 << index); - if (interrupts[int_num] == 0) - intstatus &= ~(ULL(1) << int_num); + interrupts.clear(int_num, index); } void BaseCPU::clear_interrupts() { - DPRINTF(Interrupt, "Interrupts all cleared\n"); - - memset(interrupts, 0, sizeof(interrupts)); - intstatus = 0; + interrupts.clear_all(); } void BaseCPU::serialize(std::ostream &os) { - SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); - SERIALIZE_SCALAR(intstatus); + interrupts.serialize(os); } void BaseCPU::unserialize(Checkpoint *cp, const std::string §ion) { - UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); - UNSERIALIZE_SCALAR(intstatus); + interrupts.unserialize(cp, section); } #endif // FULL_SYSTEM diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 75e0d86af..207473d80 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -40,6 +40,10 @@ #include "mem/mem_object.hh" #include "arch/isa_traits.hh" +#if FULL_SYSTEM +#include "arch/interrupts.hh" +#endif + class BranchPred; class CheckerCPU; class ThreadContext; @@ -75,8 +79,9 @@ class BaseCPU : public MemObject #if FULL_SYSTEM protected: - uint64_t interrupts[TheISA::NumInterruptLevels]; - uint64_t intstatus; +// uint64_t interrupts[TheISA::NumInterruptLevels]; +// uint64_t intstatus; + TheISA::Interrupts interrupts; public: virtual void post_interrupt(int int_num, int index); @@ -85,14 +90,11 @@ class BaseCPU : public MemObject bool checkInterrupts; bool check_interrupt(int int_num) const { - if (int_num > TheISA::NumInterruptLevels) - panic("int_num out of bounds\n"); - - return interrupts[int_num] != 0; + return interrupts.check_interrupt(int_num); } - bool check_interrupts() const { return intstatus != 0; } - uint64_t intr_status() const { return intstatus; } + bool check_interrupts() const { return interrupts.check_interrupts(); } + //uint64_t intr_status() const { return interrupts.intr_status(); } class ProfileEvent : public Event { diff --git a/src/cpu/o3/alpha/cpu_impl.hh b/src/cpu/o3/alpha/cpu_impl.hh index f5c2170ce..170a53c23 100644 --- a/src/cpu/o3/alpha/cpu_impl.hh +++ b/src/cpu/o3/alpha/cpu_impl.hh @@ -270,7 +270,6 @@ template void AlphaO3CPU::processInterrupts() { - using namespace TheISA; // Check for interrupts here. For now can copy the code that // exists within isa_fullsys_traits.hh. Also assume that thread 0 // is the one that handles the interrupts. @@ -279,52 +278,11 @@ AlphaO3CPU::processInterrupts() // Check if there are any outstanding interrupts //Handle the interrupts - int ipl = 0; - int summary = 0; - this->checkInterrupts = false; + Fault interrupt = this->interrupts.getInterrupt(this->tcBase(0)); - if (this->readMiscReg(IPR_ASTRR, 0)) - panic("asynchronous traps not implemented\n"); - - if (this->readMiscReg(IPR_SIRR, 0)) { - for (int i = INTLEVEL_SOFTWARE_MIN; - i < INTLEVEL_SOFTWARE_MAX; i++) { - if (this->readMiscReg(IPR_SIRR, 0) & (ULL(1) << i)) { - // See table 4-19 of the 21164 hardware reference - ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; - summary |= (ULL(1) << i); - } - } - } - - uint64_t interrupts = this->intr_status(); - - if (interrupts) { - for (int i = INTLEVEL_EXTERNAL_MIN; - i < INTLEVEL_EXTERNAL_MAX; i++) { - if (interrupts & (ULL(1) << i)) { - // See table 4-19 of the 21164 hardware reference - ipl = i; - summary |= (ULL(1) << i); - } - } - } - - if (ipl && ipl > this->readMiscReg(IPR_IPLR, 0)) { - this->setMiscReg(IPR_ISR, summary, 0); - this->setMiscReg(IPR_INTID, ipl, 0); - // Checker needs to know these two registers were updated. -#if USE_CHECKER - if (this->checker) { - this->checker->threadBase()->setMiscReg(IPR_ISR, summary); - this->checker->threadBase()->setMiscReg(IPR_INTID, ipl); - } -#endif - this->trap(Fault(new InterruptFault), 0); - DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - this->readMiscReg(IPR_IPLR, 0), ipl, summary); - } + if (interrupt != NoFault) + this->trap(interrupt, 0); } #endif // FULL_SYSTEM diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 6a2c0bbe9..0c7b5eafe 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -312,42 +312,11 @@ BaseSimpleCPU::checkForInterrupts() { #if FULL_SYSTEM if (checkInterrupts && check_interrupts() && !thread->inPalMode()) { - int ipl = 0; - int summary = 0; checkInterrupts = false; + Fault interrupt = interrupts.getInterrupt(tc); - if (thread->readMiscReg(IPR_SIRR)) { - for (int i = INTLEVEL_SOFTWARE_MIN; - i < INTLEVEL_SOFTWARE_MAX; i++) { - if (thread->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { - // See table 4-19 of 21164 hardware reference - ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; - summary |= (ULL(1) << i); - } - } - } - - uint64_t interrupts = thread->cpu->intr_status(); - for (int i = INTLEVEL_EXTERNAL_MIN; - i < INTLEVEL_EXTERNAL_MAX; i++) { - if (interrupts & (ULL(1) << i)) { - // See table 4-19 of 21164 hardware reference - ipl = i; - summary |= (ULL(1) << i); - } - } - - if (thread->readMiscReg(IPR_ASTRR)) - panic("asynchronous traps not implemented\n"); - - if (ipl && ipl > thread->readMiscReg(IPR_IPLR)) { - thread->setMiscReg(IPR_ISR, summary); - thread->setMiscReg(IPR_INTID, ipl); - - Fault(new InterruptFault)->invoke(tc); - - DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - thread->readMiscReg(IPR_IPLR), ipl, summary); + if (interrupt != NoFault) { + interrupt->invoke(tc); } } #endif -- cgit v1.2.3 From 118b9dc1f9e84a12ea26743f6cec1eac5b4ab13a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 04:25:33 -0500 Subject: Got rid of "inPalMode". Some places are still effectively checking if they are in PAL mode, however. --HG-- extra : convert_revision : b52d9642efc474eaf97437fa2df879efefa0062b --- src/arch/alpha/ev5.cc | 2 +- src/arch/alpha/faults.cc | 2 +- src/arch/alpha/interrupts.hh | 15 +++++---------- src/cpu/base.hh | 8 ++------ src/cpu/checker/cpu.hh | 1 - src/cpu/checker/thread_context.hh | 3 --- src/cpu/o3/alpha/cpu.hh | 3 --- src/cpu/o3/alpha/cpu_impl.hh | 5 +++-- src/cpu/o3/alpha/dyn_inst.hh | 2 -- src/cpu/o3/alpha/dyn_inst_impl.hh | 9 +-------- src/cpu/o3/alpha/thread_context.hh | 5 ----- src/cpu/o3/commit_impl.hh | 3 +-- src/cpu/o3/fetch_impl.hh | 13 ++++--------- src/cpu/ozone/cpu.hh | 6 ------ src/cpu/ozone/dyn_inst.hh | 1 - src/cpu/ozone/dyn_inst_impl.hh | 9 +-------- src/cpu/ozone/front_end_impl.hh | 9 ++------- src/cpu/ozone/inorder_back_end_impl.hh | 6 +++--- src/cpu/ozone/lw_back_end_impl.hh | 3 +-- src/cpu/simple/base.cc | 8 ++++++-- src/cpu/simple/base.hh | 1 - src/cpu/simple_thread.hh | 4 ---- src/cpu/thread_context.hh | 7 ------- 23 files changed, 31 insertions(+), 94 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 314b445e0..dca948bbd 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -147,7 +147,7 @@ AlphaISA::zeroRegisters(CPU *cpu) Fault SimpleThread::hwrei() { - if (!inPalMode()) + if (!(readPC() & 0x3)) return new UnimplementedOpcodeFault; setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR)); diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index 7179bf025..5efcf92e4 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -125,7 +125,7 @@ void AlphaFault::invoke(ThreadContext * tc) countStat()++; // exception restart address - if (setRestartAddress() || !tc->inPalMode()) + if (setRestartAddress() || !(tc->readPC() & 0x3)) tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, tc->readPC()); if (skipFaultingInstruction()) { diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index 2f031f434..75031ae47 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -88,15 +88,6 @@ namespace AlphaISA intstatus = 0; } - bool check_interrupt(int int_num) const { - if (int_num > NumInterruptLevels) - panic("int_num out of bounds\n"); - - return interrupts[int_num] != 0; - } - - bool check_interrupts() const { return intstatus != 0; } - void serialize(std::ostream &os) { SERIALIZE_ARRAY(interrupts, NumInterruptLevels); @@ -109,6 +100,11 @@ namespace AlphaISA UNSERIALIZE_SCALAR(intstatus); } + bool check_interrupts(ThreadContext * tc) const + { + return (intstatus != 0) && !(tc->readPC() & 0x3); + } + Fault getInterrupt(ThreadContext * tc) { int ipl = 0; @@ -163,7 +159,6 @@ namespace AlphaISA } private: - uint64_t intr_status() const { return intstatus; } }; } diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 207473d80..79d22c992 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -89,12 +89,8 @@ class BaseCPU : public MemObject virtual void clear_interrupts(); bool checkInterrupts; - bool check_interrupt(int int_num) const { - return interrupts.check_interrupt(int_num); - } - - bool check_interrupts() const { return interrupts.check_interrupts(); } - //uint64_t intr_status() const { return interrupts.intr_status(); } + bool check_interrupts(ThreadContext * tc) const + { return interrupts.check_interrupts(tc); } class ProfileEvent : public Event { diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 454f3892b..9be54529f 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -327,7 +327,6 @@ class CheckerCPU : public BaseCPU #if FULL_SYSTEM Fault hwrei() { return thread->hwrei(); } - bool inPalMode() { return thread->inPalMode(); } void ev5_trap(Fault fault) { fault->invoke(tc); } bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } #else diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh index cd399dd22..b46031167 100644 --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@ -271,9 +271,6 @@ class CheckerThreadContext : public ThreadContext checkerTC->setStCondFailures(sc_failures); actualTC->setStCondFailures(sc_failures); } -#if FULL_SYSTEM - bool inPalMode() { return actualTC->inPalMode(); } -#endif // @todo: Fix this! bool misspeculating() { return actualTC->misspeculating(); } diff --git a/src/cpu/o3/alpha/cpu.hh b/src/cpu/o3/alpha/cpu.hh index 01749a2a2..b62550062 100644 --- a/src/cpu/o3/alpha/cpu.hh +++ b/src/cpu/o3/alpha/cpu.hh @@ -153,9 +153,6 @@ class AlphaO3CPU : public FullO3CPU void post_interrupt(int int_num, int index); /** HW return from error interrupt. */ Fault hwrei(unsigned tid); - /** Returns if a specific PC is a PAL mode PC. */ - bool inPalMode(uint64_t PC) - { return AlphaISA::PcPAL(PC); } bool simPalCheck(int palFunc, unsigned tid); diff --git a/src/cpu/o3/alpha/cpu_impl.hh b/src/cpu/o3/alpha/cpu_impl.hh index 170a53c23..750ccc912 100644 --- a/src/cpu/o3/alpha/cpu_impl.hh +++ b/src/cpu/o3/alpha/cpu_impl.hh @@ -278,11 +278,12 @@ AlphaO3CPU::processInterrupts() // Check if there are any outstanding interrupts //Handle the interrupts - this->checkInterrupts = false; Fault interrupt = this->interrupts.getInterrupt(this->tcBase(0)); - if (interrupt != NoFault) + if (interrupt != NoFault) { + this->checkInterrupts = false; this->trap(interrupt, 0); + } } #endif // FULL_SYSTEM diff --git a/src/cpu/o3/alpha/dyn_inst.hh b/src/cpu/o3/alpha/dyn_inst.hh index e711de510..31df8ff78 100644 --- a/src/cpu/o3/alpha/dyn_inst.hh +++ b/src/cpu/o3/alpha/dyn_inst.hh @@ -126,8 +126,6 @@ class AlphaDynInst : public BaseDynInst #if FULL_SYSTEM /** Calls hardware return from error interrupt. */ Fault hwrei(); - /** Checks if system is in PAL mode. */ - bool inPalMode(); /** Traps to handle specified fault. */ void trap(Fault fault); bool simPalCheck(int palFunc); diff --git a/src/cpu/o3/alpha/dyn_inst_impl.hh b/src/cpu/o3/alpha/dyn_inst_impl.hh index f27cd5961..6fc548a85 100644 --- a/src/cpu/o3/alpha/dyn_inst_impl.hh +++ b/src/cpu/o3/alpha/dyn_inst_impl.hh @@ -113,7 +113,7 @@ Fault AlphaDynInst::hwrei() { // Can only do a hwrei when in pal mode. - if (!this->cpu->inPalMode(this->readPC())) + if (!(this->readPC() & 0x3)) return new AlphaISA::UnimplementedOpcodeFault; // Set the next PC based on the value of the EXC_ADDR IPR. @@ -127,13 +127,6 @@ AlphaDynInst::hwrei() return NoFault; } -template -bool -AlphaDynInst::inPalMode() -{ - return this->cpu->inPalMode(this->PC); -} - template void AlphaDynInst::trap(Fault fault) diff --git a/src/cpu/o3/alpha/thread_context.hh b/src/cpu/o3/alpha/thread_context.hh index f0cecee35..bcecb7087 100644 --- a/src/cpu/o3/alpha/thread_context.hh +++ b/src/cpu/o3/alpha/thread_context.hh @@ -47,11 +47,6 @@ class AlphaTC : public O3ThreadContext { return this->thread->quiesceEvent; } - - /** Returns if the thread is currently in PAL mode, based on - * the PC's value. */ - virtual bool inPalMode() - { return TheISA::PcPAL(this->cpu->readPC(this->thread->readTid())); } #endif virtual uint64_t readNextNPC() diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index ecf6ed632..bd5c4f9ce 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -638,8 +638,7 @@ DefaultCommit::commit() // and no other traps or external squashes are currently pending. // @todo: Allow other threads to handle interrupts. if (cpu->checkInterrupts && - cpu->check_interrupts() && - !cpu->inPalMode(readPC()) && + cpu->check_interrupts(cpu->tcBase(0)) && !trapSquash[0] && !tcSquash[0]) { // Tell fetch that there is an interrupt pending. This will diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 31f3b96d6..4c39341aa 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -559,14 +559,9 @@ DefaultFetch::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid { Fault fault = NoFault; -#if FULL_SYSTEM - // Flag to say whether or not address is physical addr. - unsigned flags = cpu->inPalMode(fetch_PC) ? PHYSICAL : 0; -#else - unsigned flags = 0; -#endif // FULL_SYSTEM - - if (cacheBlocked || isSwitchedOut() || (interruptPending && flags == 0)) { + //AlphaDep + if (cacheBlocked || isSwitchedOut() || + (interruptPending && (fetch_PC & 0x3))) { // Hold off fetch from getting new instructions when: // Cache is blocked, or // while an interrupt is pending and we're not in PAL mode, or @@ -585,7 +580,7 @@ DefaultFetch::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid // Setup the memReq to do a read of the first instruction's address. // Set the appropriate read size and flags as well. // Build request here. - RequestPtr mem_req = new Request(tid, fetch_PC, cacheBlkSize, flags, + RequestPtr mem_req = new Request(tid, fetch_PC, cacheBlkSize, 0, fetch_PC, cpu->readCpuId(), tid); memReq[tid] = mem_req; diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh index 828c2b4ca..b3d3531e9 100644 --- a/src/cpu/ozone/cpu.hh +++ b/src/cpu/ozone/cpu.hh @@ -239,10 +239,6 @@ class OzoneCPU : public BaseCPU void setStCondFailures(unsigned sc_failures) { thread->storeCondFailures = sc_failures; } -#if FULL_SYSTEM - bool inPalMode() { return cpu->inPalMode(); } -#endif - bool misspeculating() { return false; } #if !FULL_SYSTEM @@ -584,8 +580,6 @@ class OzoneCPU : public BaseCPU #if FULL_SYSTEM Fault hwrei(); - bool inPalMode() { return AlphaISA::PcPAL(thread.PC); } - bool inPalMode(Addr pc) { return AlphaISA::PcPAL(pc); } bool simPalCheck(int palFunc); void processInterrupts(); #else diff --git a/src/cpu/ozone/dyn_inst.hh b/src/cpu/ozone/dyn_inst.hh index 532317b08..9445a5309 100644 --- a/src/cpu/ozone/dyn_inst.hh +++ b/src/cpu/ozone/dyn_inst.hh @@ -238,7 +238,6 @@ class OzoneDynInst : public BaseDynInst #if FULL_SYSTEM Fault hwrei(); - bool inPalMode(); void trap(Fault fault); bool simPalCheck(int palFunc); #else diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh index 68736ae61..426841536 100644 --- a/src/cpu/ozone/dyn_inst_impl.hh +++ b/src/cpu/ozone/dyn_inst_impl.hh @@ -249,7 +249,7 @@ template Fault OzoneDynInst::hwrei() { - if (!this->cpu->inPalMode(this->readPC())) + if (!(this->readPC() & 0x3)) return new AlphaISA::UnimplementedOpcodeFault; this->setNextPC(this->thread->readMiscReg(AlphaISA::IPR_EXC_ADDR)); @@ -260,13 +260,6 @@ OzoneDynInst::hwrei() return NoFault; } -template -bool -OzoneDynInst::inPalMode() -{ - return this->cpu->inPalMode(); -} - template void OzoneDynInst::trap(Fault fault) diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh index 6d02c58cb..73ca6afbe 100644 --- a/src/cpu/ozone/front_end_impl.hh +++ b/src/cpu/ozone/front_end_impl.hh @@ -462,15 +462,10 @@ Fault FrontEnd::fetchCacheLine() { // Read a cache line, based on the current PC. -#if FULL_SYSTEM - // Flag to say whether or not address is physical addr. - unsigned flags = cpu->inPalMode(PC) ? PHYSICAL : 0; -#else - unsigned flags = 0; -#endif // FULL_SYSTEM Fault fault = NoFault; - if (interruptPending && flags == 0) { + //AlphaDep + if (interruptPending && (PC & 0x3)) { return fault; } diff --git a/src/cpu/ozone/inorder_back_end_impl.hh b/src/cpu/ozone/inorder_back_end_impl.hh index 8aef9c074..87bf0a7a2 100644 --- a/src/cpu/ozone/inorder_back_end_impl.hh +++ b/src/cpu/ozone/inorder_back_end_impl.hh @@ -152,11 +152,11 @@ InorderBackEnd::tick() #if FULL_SYSTEM if (interruptBlocked || (cpu->checkInterrupts && - cpu->check_interrupts() && - !cpu->inPalMode())) { + cpu->check_interrupts(tc))) { if (!robEmpty()) { interruptBlocked = true; - } else if (robEmpty() && cpu->inPalMode()) { + //AlphaDep + } else if (robEmpty() && (PC & 0x3)) { // Will need to let the front end continue a bit until // we're out of pal mode. Hopefully we never get into an // infinite loop... diff --git a/src/cpu/ozone/lw_back_end_impl.hh b/src/cpu/ozone/lw_back_end_impl.hh index c39b9e08b..a181c93f4 100644 --- a/src/cpu/ozone/lw_back_end_impl.hh +++ b/src/cpu/ozone/lw_back_end_impl.hh @@ -526,8 +526,7 @@ void LWBackEnd::checkInterrupts() { if (cpu->checkInterrupts && - cpu->check_interrupts() && - !cpu->inPalMode(thread->readPC()) && + cpu->check_interrupts(tc) && !trapSquash && !tcSquash) { frontEnd->interruptPending = true; diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 0c7b5eafe..e91569db2 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -311,11 +311,11 @@ void BaseSimpleCPU::checkForInterrupts() { #if FULL_SYSTEM - if (checkInterrupts && check_interrupts() && !thread->inPalMode()) { - checkInterrupts = false; + if (checkInterrupts && check_interrupts(tc)) { Fault interrupt = interrupts.getInterrupt(tc); if (interrupt != NoFault) { + checkInterrupts = false; interrupt->invoke(tc); } } @@ -371,6 +371,10 @@ BaseSimpleCPU::preExecute() StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->readPC())); #elif THE_ISA == SPARC_ISA StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC())); +#elif THE_ISA == MIPS_ISA + //Mips doesn't do anything in it's MakeExtMI function right now, + //so it won't be called. + StaticInstPtr instPtr = StaticInst::decode(inst); #endif if (instPtr->isMacroOp()) { curMacroStaticInst = instPtr; diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index d13be2877..efb884325 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -302,7 +302,6 @@ class BaseSimpleCPU : public BaseCPU #if FULL_SYSTEM Fault hwrei() { return thread->hwrei(); } - bool inPalMode() { return thread->inPalMode(); } void ev5_trap(Fault fault) { fault->invoke(tc); } bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } #else diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 9a575f06b..600588295 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -440,10 +440,6 @@ class SimpleThread : public ThreadState void setStCondFailures(unsigned sc_failures) { storeCondFailures = sc_failures; } -#if FULL_SYSTEM - bool inPalMode() { return AlphaISA::PcPAL(regs.readPC()); } -#endif - #if !FULL_SYSTEM TheISA::IntReg getSyscallArg(int i) { diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index dfc6fbc2a..82d75b161 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -236,10 +236,6 @@ class ThreadContext virtual void setStCondFailures(unsigned sc_failures) = 0; -#if FULL_SYSTEM - virtual bool inPalMode() = 0; -#endif - // Only really makes sense for old CPU model. Still could be useful though. virtual bool misspeculating() = 0; @@ -424,9 +420,6 @@ class ProxyThreadContext : public ThreadContext void setStCondFailures(unsigned sc_failures) { actualTC->setStCondFailures(sc_failures); } -#if FULL_SYSTEM - bool inPalMode() { return actualTC->inPalMode(); } -#endif // @todo: Fix this! bool misspeculating() { return actualTC->misspeculating(); } -- cgit v1.2.3 From 7c5a859243d681407d7cfa99835271e6d3b90338 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 10:52:08 -0500 Subject: removed ua2005.cc since it's been obsorbed into the miscregfile, and added system.cc --HG-- extra : convert_revision : 2a124adcefe0d15860632a05e8788d3fd34008c2 --- src/arch/sparc/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript index e317502e0..5843058a4 100644 --- a/src/arch/sparc/SConscript +++ b/src/arch/sparc/SConscript @@ -54,8 +54,8 @@ base_sources = Split(''' # Full-system sources full_system_sources = Split(''' - ua2005.cc vtophys.cc + system.cc ''') # Syscall emulation (non-full-system) sources -- cgit v1.2.3 From 694323b7c4922d0591598a0a501ff17f312c5307 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 10:54:34 -0500 Subject: Move around misc reg code src/arch/sparc/faults.cc: Moved some code here from miscregfile.cc src/arch/sparc/miscregfile.cc: Moved code from here to faults.cc, and merged (read|set)MiscRegWithEffect and it's FS version from ua2005.cc src/arch/sparc/miscregfile.hh: readFSRegWithEffect is no longer a seperate function, and is instead done in the main readRegWith Effect. --HG-- extra : convert_revision : 0b45f0f78e83929b32ddd2f443c8b1dbf9bc04fb --- src/arch/sparc/faults.cc | 36 ++++++++++- src/arch/sparc/miscregfile.cc | 143 +++++++++++++++++++++++++++++------------- src/arch/sparc/miscregfile.hh | 6 -- 3 files changed, 134 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 567ca5f5c..6bca6adc5 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -33,12 +33,13 @@ #include "arch/sparc/faults.hh" #include "arch/sparc/isa_traits.hh" -#include "arch/sparc/process.hh" #include "base/bitfield.hh" #include "base/trace.hh" +#include "config/full_system.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" #if !FULL_SYSTEM +#include "arch/sparc/process.hh" #include "mem/page_table.hh" #include "sim/process.hh" #endif @@ -361,6 +362,39 @@ void SparcFault::invoke(ThreadContext * tc) //Use the SPARC trap state machine } +void PowerOnReset::invoke(ThreadContext * tc) +{ + //For SPARC, when a system is first started, there is a power + //on reset Trap which sets the processor into the following state. + //Bits that aren't set aren't defined on startup. + /* + tl = MaxTL; + gl = MaxGL; + + tickFields.counter = 0; //The TICK register is unreadable bya + tickFields.npt = 1; //The TICK register is unreadable by by !priv + + softint = 0; // Clear all the soft interrupt bits + tick_cmprFields.int_dis = 1; // disable timer compare interrupts + tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing + stickFields.npt = 1; //The TICK register is unreadable by by !priv + stick_cmprFields.int_dis = 1; // disable timer compare interrupts + stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing + + tt[tl] = _trapType; + pstate = 0; // fields 0 but pef + pstateFields.pef = 1; + + hpstate = 0; + hpstateFields.red = 1; + hpstateFields.hpriv = 1; + hpstateFields.tlz = 0; // this is a guess + hintp = 0; // no interrupts pending + hstick_cmprFields.int_dis = 1; // disable timer compare interrupts + hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing + */ +} + #endif #if !FULL_SYSTEM diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 2f3cfb417..a66e40717 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -31,9 +31,14 @@ #include "arch/sparc/miscregfile.hh" #include "base/trace.hh" +#include "config/full_system.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" +#if FULL_SYSTEM +#include "arch/sparc/system.hh" +#endif + using namespace SparcISA; using namespace std; @@ -55,51 +60,8 @@ string SparcISA::getMiscRegName(RegIndex index) return miscRegName[index]; } -#if FULL_SYSTEM - -//XXX These need an implementation someplace -/** Fullsystem only register version of ReadRegWithEffect() */ -MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext *tc); -/** Fullsystem only register version of SetRegWithEffect() */ -void MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, - ThreadContext * tc); -#endif - void MiscRegFile::reset() { - //pstateFields.pef = 0; //No FPU - //pstateFields.pef = 1; //FPU -#if FULL_SYSTEM - //For SPARC, when a system is first started, there is a power - //on reset Trap which sets the processor into the following state. - //Bits that aren't set aren't defined on startup. - //XXX this code should be moved into the POR fault. - tl = MaxTL; - gl = MaxGL; - - tickFields.counter = 0; //The TICK register is unreadable bya - tickFields.npt = 1; //The TICK register is unreadable by by !priv - - softint = 0; // Clear all the soft interrupt bits - tick_cmprFields.int_dis = 1; // disable timer compare interrupts - tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing - stickFields.npt = 1; //The TICK register is unreadable by by !priv - stick_cmprFields.int_dis = 1; // disable timer compare interrupts - stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing - - - tt[tl] = power_on_reset; - pstate = 0; // fields 0 but pef - pstateFields.pef = 1; - - hpstate = 0; - hpstateFields.red = 1; - hpstateFields.hpriv = 1; - hpstateFields.tlz = 0; // this is a guess - hintp = 0; // no interrupts pending - hstick_cmprFields.int_dis = 1; // disable timer compare interrupts - hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing -#endif } MiscReg MiscRegFile::readReg(int miscReg) @@ -199,10 +161,20 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) case MISCREG_PCR: case MISCREG_PIC: panic("Performance Instrumentation not impl\n"); - /** Floating Point Status Register */ case MISCREG_FSR: panic("Floating Point not implemented\n"); +//We'll include this only in FS so we don't need the SparcSystem type around +//in SE. +#if FULL_SYSTEM + case MISCREG_STICK: + SparcSystem *sys; + sys = dynamic_cast(tc->getSystemPtr()); + assert(sys != NULL); + return curTick/Clock::Int::ns - sys->sysTick | stickFields.npt << 63; +#endif + case MISCREG_HVER: + return NWindows | MaxTL << 8 | MaxGL << 16; } return readReg(miscReg); } @@ -350,6 +322,10 @@ void MiscRegFile::setRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc) { const uint64_t Bit64 = (1ULL << 63); + uint64_t time; +#if FULL_SYSTEM + SparcSystem *sys; +#endif switch (miscReg) { case MISCREG_TICK: tickFields.counter = tc->getCpuPtr()->curCycle() - val & ~Bit64; @@ -375,6 +351,68 @@ void MiscRegFile::setRegWithEffect(int miscReg, case MISCREG_GL: tc->changeRegFileContext(CONTEXT_GLOBALS, val); break; + case MISCREG_SOFTINT: + //We need to inject interrupts, and or notify the interrupt + //object that it needs to use a different interrupt level. + //Any newly appropriate interrupts will happen when the cpu gets + //around to checking for them. This might not be quite what we + //want. + break; + case MISCREG_SOFTINT_CLR: + //Do whatever this is supposed to do... + break; + case MISCREG_SOFTINT_SET: + //Do whatever this is supposed to do... + break; + case MISCREG_TICK_CMPR: + if (tickCompare == NULL) + tickCompare = new TickCompareEvent(this, tc); + setReg(miscReg, val); + if (tick_cmprFields.int_dis && tickCompare->scheduled()) + tickCompare->deschedule(); + time = tick_cmprFields.tick_cmpr - tickFields.counter; + if (!tick_cmprFields.int_dis && time > 0) + tickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); + break; + case MISCREG_PIL: + //We need to inject interrupts, and or notify the interrupt + //object that it needs to use a different interrupt level. + //Any newly appropriate interrupts will happen when the cpu gets + //around to checking for them. This might not be quite what we + //want. + break; +//We'll include this only in FS so we don't need the SparcSystem type around +//in SE. +#if FULL_SYSTEM + case MISCREG_STICK: + sys = dynamic_cast(tc->getSystemPtr()); + assert(sys != NULL); + sys->sysTick = curTick/Clock::Int::ns - val & ~Bit64; + stickFields.npt = val & Bit64 ? 1 : 0; + break; + case MISCREG_STICK_CMPR: + if (sTickCompare == NULL) + sTickCompare = new STickCompareEvent(this, tc); + sys = dynamic_cast(tc->getSystemPtr()); + assert(sys != NULL); + if (stick_cmprFields.int_dis && sTickCompare->scheduled()) + sTickCompare->deschedule(); + time = stick_cmprFields.tick_cmpr - sys->sysTick; + if (!stick_cmprFields.int_dis && time > 0) + sTickCompare->schedule(time * Clock::Int::ns); + break; + case MISCREG_HSTICK_CMPR: + if (hSTickCompare == NULL) + hSTickCompare = new HSTickCompareEvent(this, tc); + sys = dynamic_cast(tc->getSystemPtr()); + assert(sys != NULL); + if (hstick_cmprFields.int_dis && hSTickCompare->scheduled()) + hSTickCompare->deschedule(); + int64_t time = hstick_cmprFields.tick_cmpr - sys->sysTick; + if (!hstick_cmprFields.int_dis && time > 0) + hSTickCompare->schedule(time * Clock::Int::ns); + break; +#endif } setReg(miscReg, val); } @@ -444,3 +482,20 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) implicitDataAsi = (ASI)temp; } +void +MiscRegFile::processTickCompare(ThreadContext *tc) +{ + panic("tick compare not implemented\n"); +} + +void +MiscRegFile::processSTickCompare(ThreadContext *tc) +{ + panic("tick compare not implemented\n"); +} + +void +MiscRegFile::processHSTickCompare(ThreadContext *tc) +{ + panic("tick compare not implemented\n"); +} diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index ac1ad90b9..0e424dbd2 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -354,12 +354,6 @@ namespace SparcISA typedef CpuEventWrapper HSTickCompareEvent; HSTickCompareEvent *hSTickCompare; - - /** Fullsystem only register version of ReadRegWithEffect() */ - MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc); - /** Fullsystem only register version of SetRegWithEffect() */ - Fault setFSRegWithEffect(int miscReg, const MiscReg &val, - ThreadContext * tc); #endif public: -- cgit v1.2.3 From e6fed44625802bd185cfbbf9808624f792637d43 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 10:55:29 -0500 Subject: Add an invoke function for PowerOnReset --HG-- extra : convert_revision : a1cdd35c74f6e85f42a04061b466ec7617da8ac2 --- src/arch/sparc/faults.hh | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index 394a06294..c087365a2 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -130,6 +130,7 @@ class PowerOnReset : public SparcFault TrapType trapType() {return _trapType;} FaultPriority priority() {return _priority;} FaultStat & countStat() {return _count;} + void invoke(ThreadContext * tc); }; class WatchDogReset : public SparcFault -- cgit v1.2.3 From ab651344dda9ba09c1c3e1855a5bbc250bdc5ea0 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 10:56:47 -0500 Subject: Add the syscall number as the second parameter for the trap fault. This could be improved and syscalls could be called from the trap's invoke method. --HG-- extra : convert_revision : 127a3673a076110fb3605c0fbc93e8d7e9fec84b --- src/arch/sparc/isa/decoder.isa | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index a5f43367d..33352cb2c 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -726,7 +726,7 @@ decode OP default Unknown::unknown() #if FULL_SYSTEM int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2); DPRINTF(Sparc, "The trap number is %d\n", lTrapNum); - fault = new TrapInstruction(lTrapNum); + fault = new TrapInstruction(lTrapNum, R1); #else DPRINTF(Sparc, "The syscall number is %d\n", R1); xc->syscall(R1); @@ -739,7 +739,7 @@ decode OP default Unknown::unknown() #if FULL_SYSTEM int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2); DPRINTF(Sparc, "The trap number is %d\n", lTrapNum); - fault = new TrapInstruction(lTrapNum); + fault = new TrapInstruction(lTrapNum, R1); #else DPRINTF(Sparc, "The syscall number is %d\n", R1); xc->syscall(R1); -- cgit v1.2.3 From 6b701a6d25f16e0e1b146fb2ce9277f53fbdbbc5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 11:03:03 -0500 Subject: Compilation fixes. --HG-- extra : convert_revision : 44d67a3bb95f875f17586499aa4a04268aa2fd46 --- src/arch/sparc/system.cc | 13 ++++++++----- src/arch/sparc/system.hh | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc index ef6443d17..952ac2deb 100644 --- a/src/arch/sparc/system.cc +++ b/src/arch/sparc/system.cc @@ -77,7 +77,7 @@ SparcSystem::SparcSystem(Params *p) hypervisor->loadSections(&functionalPort, SparcISA::LoadAddrMask); // load symbols - if (!reset->loadGlobalSymbols(reset)) + if (!reset->loadGlobalSymbols(resetSymtab)) panic("could not load reset symbols\n"); if (!openboot->loadGlobalSymbols(openbootSymtab)) @@ -148,7 +148,10 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcSystem) Param hypervisor_bin; Param openboot_bin; + Param boot_cpu_frequency; Param boot_osflags; + Param system_type; + Param system_rev; Param readfile; Param init_param; @@ -156,7 +159,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(SparcSystem) BEGIN_INIT_SIM_OBJECT_PARAMS(SparcSystem) - INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), INIT_PARAM(physmem, "phsyical memory"), INIT_ENUM_PARAM(mem_mode, "Memory Mode, (1=atomic, 2=timing)", System::MemoryModeStrings), @@ -164,12 +166,13 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SparcSystem) INIT_PARAM(reset_bin, "file that contains the reset code"), INIT_PARAM(hypervisor_bin, "file that contains the hypervisor code"), INIT_PARAM(openboot_bin, "file that contains the openboot code"), + INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", "a"), - INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), - INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), - INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10) + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), + INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), + INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0) END_INIT_SIM_OBJECT_PARAMS(SparcSystem) diff --git a/src/arch/sparc/system.hh b/src/arch/sparc/system.hh index 614707f6c..3c8c6327e 100644 --- a/src/arch/sparc/system.hh +++ b/src/arch/sparc/system.hh @@ -46,7 +46,7 @@ class SparcSystem : public System struct Params : public System::Params { std::string reset_bin; - std::string hypervison_bin; + std::string hypervisor_bin; std::string openboot_bin; std::string boot_osflags; uint64_t system_type; -- cgit v1.2.3 From 3f4b098985e5544d2fb2ef74004d2c3359936097 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 11:04:10 -0500 Subject: Added a stub initCPU function. This would be a good place to force in a PowerOnReset fault to kick start the CPU. --HG-- extra : convert_revision : 79e1fa2ef40e326682069639e260db255fd29d93 --- src/arch/sparc/utility.hh | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/arch/sparc/utility.hh b/src/arch/sparc/utility.hh index 23fddf0e9..d8880e317 100644 --- a/src/arch/sparc/utility.hh +++ b/src/arch/sparc/utility.hh @@ -99,6 +99,12 @@ namespace SparcISA template void zeroRegisters(TC *tc); + void initCPU(ThreadContext *tc, int cpuId) + { + //This would be a good place to stick a PowerOnReset fault into the + //cpu. + } + } // namespace SparcISA #endif -- cgit v1.2.3 From 29a79acb7c1b1c6614134f00097487d6baeed15b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 11:05:13 -0500 Subject: Gutted out the old Alpha stuff. --HG-- extra : convert_revision : 6767dc1305a58e3e7eb0ee909d54768e51744927 --- src/arch/sparc/vtophys.cc | 132 ++++++++-------------------------------------- 1 file changed, 22 insertions(+), 110 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/vtophys.cc b/src/arch/sparc/vtophys.cc index f7fd92c15..429126b70 100644 --- a/src/arch/sparc/vtophys.cc +++ b/src/arch/sparc/vtophys.cc @@ -32,135 +32,47 @@ #include -#include "arch/alpha/ev5.hh" -#include "arch/alpha/vtophys.hh" +#include "arch/sparc/vtophys.hh" #include "base/chunk_generator.hh" #include "base/trace.hh" #include "cpu/thread_context.hh" #include "mem/vport.hh" using namespace std; -using namespace AlphaISA; -AlphaISA::PageTableEntry -AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr) +namespace SparcISA { - Addr level1_pte = ptbr + vaddr.level1(); - AlphaISA::PageTableEntry level1 = mem->read(level1_pte); - if (!level1.valid()) { - DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr); - return 0; + PageTableEntry kernel_pte_lookup(FunctionalPort *mem, + Addr ptbr, VAddr vaddr) + { + PageTableEntry pte(4); + return pte; } - Addr level2_pte = level1.paddr() + vaddr.level2(); - AlphaISA::PageTableEntry level2 = mem->read(level2_pte); - if (!level2.valid()) { - DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr); - return 0; + Addr vtophys(Addr vaddr) + { + return vaddr; } - Addr level3_pte = level2.paddr() + vaddr.level3(); - AlphaISA::PageTableEntry level3 = mem->read(level3_pte); - if (!level3.valid()) { - DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr); - return 0; + Addr vtophys(ThreadContext *tc, Addr addr) + { + return addr; } - return level3; -} -Addr -AlphaISA::vtophys(Addr vaddr) -{ - Addr paddr = 0; - if (AlphaISA::IsUSeg(vaddr)) - DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr); - else if (AlphaISA::IsK0Seg(vaddr)) - paddr = AlphaISA::K0Seg2Phys(vaddr); - else - panic("vtophys: ptbr is not set on virtual lookup"); - DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr); - - return paddr; -} - -Addr -AlphaISA::vtophys(ThreadContext *tc, Addr addr) -{ - AlphaISA::VAddr vaddr = addr; - Addr ptbr = tc->readMiscReg(AlphaISA::IPR_PALtemp20); - Addr paddr = 0; - //@todo Andrew couldn't remember why he commented some of this code - //so I put it back in. Perhaps something to do with gdb debugging? - if (AlphaISA::PcPAL(vaddr) && (vaddr < EV5::PalMax)) { - paddr = vaddr & ~ULL(1); - } else { - if (AlphaISA::IsK0Seg(vaddr)) { - paddr = AlphaISA::K0Seg2Phys(vaddr); - } else if (!ptbr) { - paddr = vaddr; - } else { - AlphaISA::PageTableEntry pte = - kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr); - if (pte.valid()) - paddr = pte.paddr() | vaddr.offset(); - } + void CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen) + { } + void CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen) + { + } - DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr); - - return paddr; -} - - -void -AlphaISA::CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen) -{ - uint8_t *dst = (uint8_t *)dest; - VirtualPort *vp = tc->getVirtPort(tc); - - vp->readBlob(src, dst, cplen); - - tc->delVirtPort(vp); - -} - -void -AlphaISA::CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen) -{ - uint8_t *src = (uint8_t *)source; - VirtualPort *vp = tc->getVirtPort(tc); - - vp->writeBlob(dest, src, cplen); - - tc->delVirtPort(vp); -} - -void -AlphaISA::CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen) -{ - int len = 0; - VirtualPort *vp = tc->getVirtPort(tc); - - do { - vp->readBlob(vaddr++, (uint8_t*)dst++, 1); - len++; - } while (len < maxlen && dst[len] != 0 ); - - tc->delVirtPort(vp); - dst[len] = 0; -} + void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen) + { + } -void -AlphaISA::CopyStringIn(ThreadContext *tc, char *src, Addr vaddr) -{ - VirtualPort *vp = tc->getVirtPort(tc); - for (ChunkGenerator gen(vaddr, strlen(src), AlphaISA::PageBytes); !gen.done(); - gen.next()) + void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr) { - vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size()); - src += gen.size(); } - tc->delVirtPort(vp); } -- cgit v1.2.3 From 4a5cb3f4250544cd5cdf423405d66471b33c545c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 11:05:56 -0500 Subject: The tc needs to be protected instead of private so that the CpuEventWrapper can access it. --HG-- extra : convert_revision : bd836d63ac3630b20dda552e7b289730f3c114ef --- src/cpu/cpuevent.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cpu/cpuevent.hh b/src/cpu/cpuevent.hh index 9dfae27cf..3339f8252 100644 --- a/src/cpu/cpuevent.hh +++ b/src/cpu/cpuevent.hh @@ -44,7 +44,7 @@ class ThreadContext; * */ class CpuEvent : public Event { - private: + protected: /** type of global list of cpu events. */ typedef std::vector CpuEventList; -- cgit v1.2.3 From 6ad386f1a8df96c9679dcffb326420b240e98c05 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 14:40:35 -0500 Subject: Calling syscalls from within the trap instruction's invoke method won't work because apparently you need an xc for that and not a tc. Cleaned up the TrapInstruction fault in light of this. --HG-- extra : convert_revision : 1805c9244cfd62d0ee7862d8fd7c9983e00c5747 --- src/arch/sparc/faults.cc | 5 ----- src/arch/sparc/faults.hh | 7 +------ src/arch/sparc/isa/decoder.isa | 4 ++-- 3 files changed, 3 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 6bca6adc5..da7fc730d 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -399,11 +399,6 @@ void PowerOnReset::invoke(ThreadContext * tc) #if !FULL_SYSTEM -void TrapInstruction::invoke(ThreadContext * tc) -{ - // Should be handled in ISA. -} - void SpillNNormal::invoke(ThreadContext *tc) { doNormalFault(tc, trapType()); diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index c087365a2..0c7106707 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -604,17 +604,12 @@ class TrapInstruction : public EnumeratedFault static TrapType _baseTrapType; static FaultPriority _priority; static FaultStat _count; - uint64_t syscall_num; TrapType baseTrapType() {return _baseTrapType;} public: - TrapInstruction(uint32_t n, uint64_t syscall) : - EnumeratedFault(n), syscall_num(syscall) {;} + TrapInstruction(int32_t n) : EnumeratedFault(n) {;} FaultName name() {return _name;} FaultPriority priority() {return _priority;} FaultStat & countStat() {return _count;} -#if !FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif }; diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 33352cb2c..a5f43367d 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -726,7 +726,7 @@ decode OP default Unknown::unknown() #if FULL_SYSTEM int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2); DPRINTF(Sparc, "The trap number is %d\n", lTrapNum); - fault = new TrapInstruction(lTrapNum, R1); + fault = new TrapInstruction(lTrapNum); #else DPRINTF(Sparc, "The syscall number is %d\n", R1); xc->syscall(R1); @@ -739,7 +739,7 @@ decode OP default Unknown::unknown() #if FULL_SYSTEM int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2); DPRINTF(Sparc, "The trap number is %d\n", lTrapNum); - fault = new TrapInstruction(lTrapNum, R1); + fault = new TrapInstruction(lTrapNum); #else DPRINTF(Sparc, "The syscall number is %d\n", R1); xc->syscall(R1); -- cgit v1.2.3 From 8778d85b2d352fdbfbbf077332790f94852b20d3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 14:41:27 -0500 Subject: Use a PowerOnReset to initialize the cpu. --HG-- extra : convert_revision : 9e65af095c37c7c67db377424d2d4363fa8065f9 --- src/arch/sparc/utility.hh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/utility.hh b/src/arch/sparc/utility.hh index d8880e317..e2b0b2307 100644 --- a/src/arch/sparc/utility.hh +++ b/src/arch/sparc/utility.hh @@ -31,6 +31,7 @@ #ifndef __ARCH_SPARC_UTILITY_HH__ #define __ARCH_SPARC_UTILITY_HH__ +#include "arch/sparc/faults.hh" #include "arch/sparc/isa_traits.hh" #include "base/misc.hh" #include "base/bitfield.hh" @@ -99,10 +100,10 @@ namespace SparcISA template void zeroRegisters(TC *tc); - void initCPU(ThreadContext *tc, int cpuId) + inline void initCPU(ThreadContext *tc, int cpuId) { - //This would be a good place to stick a PowerOnReset fault into the - //cpu. + static Fault por = new PowerOnReset(); + por->invoke(tc); } } // namespace SparcISA -- cgit v1.2.3 From 601822c6b507f6c3145eacf8f9db216522f70733 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Nov 2006 14:42:12 -0500 Subject: Make things compile in SE again. --HG-- extra : convert_revision : cf7faf5001b31d61c61ddce2386d61c919075800 --- src/arch/sparc/miscregfile.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index a66e40717..217fba0bd 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -322,8 +322,8 @@ void MiscRegFile::setRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc) { const uint64_t Bit64 = (1ULL << 63); - uint64_t time; #if FULL_SYSTEM + uint64_t time; SparcSystem *sys; #endif switch (miscReg) { @@ -364,6 +364,7 @@ void MiscRegFile::setRegWithEffect(int miscReg, case MISCREG_SOFTINT_SET: //Do whatever this is supposed to do... break; +#if FULL_SYSTEM case MISCREG_TICK_CMPR: if (tickCompare == NULL) tickCompare = new TickCompareEvent(this, tc); @@ -374,6 +375,7 @@ void MiscRegFile::setRegWithEffect(int miscReg, if (!tick_cmprFields.int_dis && time > 0) tickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); break; +#endif case MISCREG_PIL: //We need to inject interrupts, and or notify the interrupt //object that it needs to use a different interrupt level. @@ -482,6 +484,7 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) implicitDataAsi = (ASI)temp; } +#if FULL_SYSTEM void MiscRegFile::processTickCompare(ThreadContext *tc) { @@ -499,3 +502,4 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc) { panic("tick compare not implemented\n"); } +#endif -- cgit v1.2.3 From 21cf4a46b9e9ce52266aac873aa107cad82cc847 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 4 Nov 2006 21:41:01 -0500 Subject: fixes so that M5 will compile under solaris SConstruct: Add check to see if we need to include libsocket src/arch/sparc/floatregfile.cc: src/arch/sparc/intregfile.cc: use memset rather than bzero and include the appropriate headerfile src/base/pollevent.cc: If we're compling under solaris we need sys/file.h src/base/random.cc: src/base/random.hh: solaris doesn't have random(), so use rint with the correct rounding mode if we're compiling on solaris src/base/stats/flags.hh: u_int32_t?? src/base/time.hh: grab the timersub() define from freebsd since it doesn't exist in solaris src/cpu/inst_seq.hh: we don't need to include stdint here src/sim/byteswap.hh: the method to detect endianness on Solaris is a little more complex... --HG-- extra : convert_revision : 6b7db0e900e7bccfc250d65c125065f27280dda1 --- src/arch/sparc/floatregfile.cc | 4 +++- src/arch/sparc/intregfile.cc | 4 +++- src/base/pollevent.cc | 3 +++ src/base/random.cc | 24 +++++++++++++++++++++-- src/base/random.hh | 1 + src/base/stats/flags.hh | 2 +- src/base/time.hh | 44 ++++++++++++++++++++++++++++++++++++++++++ src/cpu/inst_seq.hh | 2 -- src/sim/byteswap.hh | 6 ++++-- 9 files changed, 81 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc index 3afe6ef54..7f3d5a758 100644 --- a/src/arch/sparc/floatregfile.cc +++ b/src/arch/sparc/floatregfile.cc @@ -34,6 +34,8 @@ #include "sim/byteswap.hh" #include "sim/serialize.hh" +#include + using namespace SparcISA; using namespace std; @@ -55,7 +57,7 @@ string SparcISA::getFloatRegName(RegIndex index) void FloatRegFile::clear() { - bzero(regSpace, sizeof(regSpace)); + memset(regSpace, 0, sizeof(regSpace)); } FloatReg FloatRegFile::readReg(int floatReg, int width) diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index 164f194dd..0e313dc94 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -33,6 +33,8 @@ #include "base/trace.hh" #include "sim/serialize.hh" +#include + using namespace SparcISA; using namespace std; @@ -62,7 +64,7 @@ void IntRegFile::clear() for (x = 0; x < MaxGL; x++) memset(regGlobals[x], 0, sizeof(IntReg) * RegsPerFrame); for(int x = 0; x < 2 * NWindows; x++) - bzero(regSegments[x], sizeof(IntReg) * RegsPerFrame); + memset(regSegments[x], 0, sizeof(IntReg) * RegsPerFrame); } IntRegFile::IntRegFile() diff --git a/src/base/pollevent.cc b/src/base/pollevent.cc index 2743cd95d..fd5b09d28 100644 --- a/src/base/pollevent.cc +++ b/src/base/pollevent.cc @@ -30,6 +30,9 @@ #include #include +#if defined(__sun__) +#include +#endif #include #include diff --git a/src/base/random.cc b/src/base/random.cc index e135b55f5..82c9e3566 100644 --- a/src/base/random.cc +++ b/src/base/random.cc @@ -32,6 +32,10 @@ #include #include +#if defined(__sun__) +#include +#endif + #include "sim/param.hh" #include "base/random.hh" #include "base/trace.hh" @@ -65,12 +69,27 @@ getLong() return mrand48(); } +double +m5round(double r) +{ +#if defined(__sun__) + double val; + fp_rnd oldrnd = fpsetround(FP_RN); + val = rint(r); + fpsetround(oldrnd); + return val; +#else + return round(r); +#endif +} + int64_t getUniform(int64_t min, int64_t max) { double r; r = drand48() * (max-min) + min; - return (int64_t)round(r); + + return (int64_t)m5round(r); } uint64_t @@ -78,7 +97,8 @@ getUniformPos(uint64_t min, uint64_t max) { double r; r = drand48() * (max-min) + min; - return (uint64_t)round(r); + + return (uint64_t)m5round(r); } diff --git a/src/base/random.hh b/src/base/random.hh index b5eb39f94..40d62da7f 100644 --- a/src/base/random.hh +++ b/src/base/random.hh @@ -36,6 +36,7 @@ long getLong(); double getDouble(); +double m5random(double r); uint64_t getUniformPos(uint64_t min, uint64_t max); int64_t getUniform(int64_t min, int64_t max); diff --git a/src/base/stats/flags.hh b/src/base/stats/flags.hh index ada1a4a87..69f73f66a 100644 --- a/src/base/stats/flags.hh +++ b/src/base/stats/flags.hh @@ -36,7 +36,7 @@ namespace Stats { * Define the storage for format flags. * @todo Can probably shrink this. */ -typedef u_int32_t StatFlags; +typedef uint32_t StatFlags; /** Nothing extra to print. */ const StatFlags none = 0x00000000; diff --git a/src/base/time.hh b/src/base/time.hh index 24e8a8a53..7aa4c50db 100644 --- a/src/base/time.hh +++ b/src/base/time.hh @@ -65,4 +65,48 @@ Time operator-(const Time &l, const Time &r); std::ostream &operator<<(std::ostream &out, const Time &time); + +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)time.h 8.2 (Berkeley) 7/10/94 + */ + +#if defined(__sun__) +#define timersub(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ + if ((vvp)->tv_usec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_usec += 1000000; \ + } \ + } while (0) +#endif + #endif // __SIM_TIME_HH__ diff --git a/src/cpu/inst_seq.hh b/src/cpu/inst_seq.hh index e7acd215f..21e04ed25 100644 --- a/src/cpu/inst_seq.hh +++ b/src/cpu/inst_seq.hh @@ -32,8 +32,6 @@ #ifndef __STD_TYPES_HH__ #define __STD_TYPES_HH__ -#include - // inst sequence type, used to order instructions in the ready list, // if this rolls over the ready list order temporarily will get messed // up, but execution will continue and complete correctly diff --git a/src/sim/byteswap.hh b/src/sim/byteswap.hh index 7648b8fcd..7b1ae701e 100644 --- a/src/sim/byteswap.hh +++ b/src/sim/byteswap.hh @@ -47,6 +47,8 @@ // If one doesn't exist, we pretty much get what is listed below, so it all // works out #include +#elif defined (__sun__) +#include #else #include #endif @@ -128,12 +130,12 @@ template static inline T letobe(T value) {return swap_byte(value);} //For conversions not involving the guest system, we can define the functions //conditionally based on the BYTE_ORDER macro and outside of the namespaces -#if BYTE_ORDER == BIG_ENDIAN +#if defined(_BIG_ENDIAN) || BYTE_ORDER == BIG_ENDIAN template static inline T htole(T value) {return swap_byte(value);} template static inline T letoh(T value) {return swap_byte(value);} template static inline T htobe(T value) {return value;} template static inline T betoh(T value) {return value;} -#elif BYTE_ORDER == LITTLE_ENDIAN +#elif defined(_LITTLE_ENDIAN) || BYTE_ORDER == LITTLE_ENDIAN template static inline T htole(T value) {return value;} template static inline T letoh(T value) {return value;} template static inline T htobe(T value) {return swap_byte(value);} -- cgit v1.2.3 From 067c9c5531cb591aa7a2472ebbe366683fcfeb0d Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Sun, 5 Nov 2006 20:29:38 -0500 Subject: Initialize pointer to NULL. src/cpu/o3/lsq_unit_impl.hh: Be sure to initialize pointer to NULL. --HG-- extra : convert_revision : 917d5119e4bd8eae10959ed07069d8c694315c7a --- src/cpu/o3/lsq_unit_impl.hh | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index d940d7cb3..9a0e48819 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -131,6 +131,7 @@ LSQUnit::init(Params *params, LSQ *lsq_ptr, unsigned maxLQEntries, usedPorts = 0; cachePorts = params->cachePorts; + retryPkt = NULL; memDepViolator = NULL; blockedLoadSeqNum = 0; -- cgit v1.2.3 From 652281a61c6be7210b575e50566e7efdc82ab6ba Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Mon, 6 Nov 2006 13:27:45 -0500 Subject: Clean up clock phase drift code a bit. src/cpu/base.cc: Move clock phase drift code to the base CPU so that any CPU model can use it. src/cpu/base.hh: Added two functions to help get the next cycle the CPU should be scheduled. src/cpu/simple/atomic.cc: src/cpu/simple/timing.cc: Use the function now in BaseCPU. --HG-- extra : convert_revision : 444494b66ffc85fc473c23f57683c5f9458ad80c --- src/cpu/base.cc | 20 ++++++++++++++++++++ src/cpu/base.hh | 14 ++++++++++++++ src/cpu/simple/atomic.cc | 12 +++--------- src/cpu/simple/timing.cc | 18 ++++++++---------- 4 files changed, 45 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/cpu/base.cc b/src/cpu/base.cc index ea4b03bf2..55ceea8fb 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -259,6 +259,26 @@ BaseCPU::regStats() #endif } +Tick +BaseCPU::nextCycle() +{ + Tick next_tick = curTick + clock - 1; + next_tick -= (next_tick % clock); + return next_tick; +} + +Tick +BaseCPU::nextCycle(Tick begin_tick) +{ + Tick next_tick = begin_tick; + + while (next_tick < curTick) + next_tick += clock; + + next_tick -= (next_tick % clock); + assert(next_tick >= curTick); + return next_tick; +} void BaseCPU::registerThreadContexts() diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 75e0d86af..df665ed23 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -73,6 +73,20 @@ class BaseCPU : public MemObject inline Tick cycles(int numCycles) const { return clock * numCycles; } inline Tick curCycle() const { return curTick / clock; } + /** The next cycle the CPU should be scheduled, given a cache + * access or quiesce event returning on this cycle. This function + * may return curTick if the CPU should run on the current cycle. + */ + Tick nextCycle(); + + /** The next cycle the CPU should be scheduled, given a cache + * access or quiesce event returning on the given Tick. This + * function may return curTick if the CPU should run on the + * current cycle. + * @param begin_tick The tick that the event is completing on. + */ + Tick nextCycle(Tick begin_tick); + #if FULL_SYSTEM protected: uint64_t interrupts[TheISA::NumInterruptLevels]; diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 72249be41..4f68cfd6f 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -180,9 +180,7 @@ AtomicSimpleCPU::resume() changeState(SimObject::Running); if (thread->status() == ThreadContext::Active) { if (!tickEvent.scheduled()) { - Tick nextTick = curTick + cycles(1) - 1; - nextTick -= (nextTick % (cycles(1))); - tickEvent.schedule(nextTick); + tickEvent.schedule(nextCycle()); } } } @@ -211,9 +209,7 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU) ThreadContext *tc = threadContexts[i]; if (tc->status() == ThreadContext::Active && _status != Running) { _status = Running; - Tick nextTick = curTick + cycles(1) - 1; - nextTick -= (nextTick % (cycles(1))); - tickEvent.schedule(nextTick); + tickEvent.schedule(nextCycle()); break; } } @@ -231,9 +227,7 @@ AtomicSimpleCPU::activateContext(int thread_num, int delay) notIdleFraction++; //Make sure ticks are still on multiples of cycles - Tick nextTick = curTick + cycles(delay + 1) - 1; - nextTick -= (nextTick % (cycles(1))); - tickEvent.schedule(nextTick); + tickEvent.schedule(nextCycle(curTick + cycles(delay))); _status = Running; } diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 4d57bf6d5..abf316095 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -532,14 +532,13 @@ TimingSimpleCPU::IcachePort::recvTiming(PacketPtr pkt) { if (pkt->isResponse()) { // delay processing of returned data until next CPU clock edge - Tick time = pkt->req->getTime(); - while (time < curTick) - time += lat; + Tick mem_time = pkt->req->getTime(); + Tick next_tick = cpu->nextCycle(mem_time); - if (time == curTick) + if (next_tick == curTick) cpu->completeIfetch(pkt); else - tickEvent.schedule(pkt, time); + tickEvent.schedule(pkt, next_tick); return true; } @@ -610,14 +609,13 @@ TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt) { if (pkt->isResponse()) { // delay processing of returned data until next CPU clock edge - Tick time = pkt->req->getTime(); - while (time < curTick) - time += lat; + Tick mem_time = pkt->req->getTime(); + Tick next_tick = cpu->nextCycle(mem_time); - if (time == curTick) + if (next_tick == curTick) cpu->completeDataAccess(pkt); else - tickEvent.schedule(pkt, time); + tickEvent.schedule(pkt, next_tick); return true; } -- cgit v1.2.3 From bf3223d7ce681db8ca59dac49c6b44b672012e5d Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 6 Nov 2006 16:24:25 -0500 Subject: delete pcifake, tsunamifake. Combine BadAddr/IsaFake into one src/SConscript: remove pcifake and tsunami fake from sconscript src/dev/isa_fake.cc: src/dev/isa_fake.hh: combine badaddr and isa fake into one src/python/m5/objects/Pci.py: remove pcifake src/python/m5/objects/Tsunami.py: make badaddr derive from isafake --HG-- extra : convert_revision : 91470db60aa1de6b85827304e27bd3414cc9d8d1 --- src/SConscript | 2 - src/dev/isa_fake.cc | 137 ++++++++++++++------------------------- src/dev/isa_fake.hh | 32 +++------ src/python/m5/objects/Pci.py | 3 - src/python/m5/objects/Tsunami.py | 6 +- 5 files changed, 64 insertions(+), 116 deletions(-) (limited to 'src') diff --git a/src/SConscript b/src/SConscript index 28f39bc29..d938d533f 100644 --- a/src/SConscript +++ b/src/SConscript @@ -227,7 +227,6 @@ full_system_sources = Split(''' dev/ns_gige.cc dev/pciconfigall.cc dev/pcidev.cc - dev/pcifake.cc dev/pktfifo.cc dev/platform.cc dev/simconsole.cc @@ -235,7 +234,6 @@ full_system_sources = Split(''' dev/tsunami.cc dev/tsunami_cchip.cc dev/tsunami_io.cc - dev/tsunami_fake.cc dev/tsunami_pchip.cc dev/uart.cc diff --git a/src/dev/isa_fake.cc b/src/dev/isa_fake.cc index ccc9a1f7c..103fdd8ce 100644 --- a/src/dev/isa_fake.cc +++ b/src/dev/isa_fake.cc @@ -25,18 +25,13 @@ * (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: Miguel Serrano - * Ali Saidi + * Authors: Ali Saidi */ /** @file * Isa Fake Device implementation */ -#include -#include -#include - #include "base/trace.hh" #include "dev/isa_fake.hh" #include "mem/packet.hh" @@ -49,74 +44,67 @@ using namespace std; IsaFake::IsaFake(Params *p) : BasicPioDevice(p) { - pioSize = p->pio_size; -} - -Tick -IsaFake::read(PacketPtr pkt) -{ - assert(pkt->result == Packet::Unknown); - assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - - DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize()); - - switch (pkt->getSize()) { - case sizeof(uint64_t): - pkt->set(0xFFFFFFFFFFFFFFFFULL); - break; - case sizeof(uint32_t): - pkt->set((uint32_t)0xFFFFFFFF); - break; - case sizeof(uint16_t): - pkt->set((uint16_t)0xFFFF); - break; - case sizeof(uint8_t): - pkt->set((uint8_t)0xFF); - break; - default: - panic("invalid access size(?) for PCI configspace!\n"); - } - pkt->result = Packet::Success; - return pioDelay; -} - -Tick -IsaFake::write(PacketPtr pkt) -{ - DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize()); - pkt->result = Packet::Success; - return pioDelay; -} + if (!params()->retBadAddr) + pioSize = p->pio_size; -BadAddr::BadAddr(Params *p) - : BasicPioDevice(p) -{ + memset(&retData, p->retData, sizeof(retData)); } void -BadAddr::init() +IsaFake::init() { // Only init this device if it's connected to anything. if (pioPort) PioDevice::init(); } + Tick -BadAddr::read(PacketPtr pkt) +IsaFake::read(PacketPtr pkt) { assert(pkt->result == Packet::Unknown); - DPRINTF(Tsunami, "read to bad address va=%#x size=%d\n", - pkt->getAddr(), pkt->getSize()); - pkt->result = Packet::BadAddress; + + if (params()->retBadAddr) { + DPRINTF(Tsunami, "read to bad address va=%#x size=%d\n", + pkt->getAddr(), pkt->getSize()); + pkt->result = Packet::BadAddress; + } else { + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + DPRINTF(Tsunami, "read va=%#x size=%d\n", + pkt->getAddr(), pkt->getSize()); + switch (pkt->getSize()) { + case sizeof(uint64_t): + pkt->set(retData); + break; + case sizeof(uint32_t): + pkt->set((uint32_t)retData); + break; + case sizeof(uint16_t): + pkt->set((uint16_t)retData); + break; + case sizeof(uint8_t): + pkt->set((uint8_t)retData); + break; + default: + panic("invalid access size!\n"); + } + pkt->result = Packet::Success; + } return pioDelay; } Tick -BadAddr::write(PacketPtr pkt) +IsaFake::write(PacketPtr pkt) { - DPRINTF(Tsunami, "write to bad address va=%#x size=%d \n", - pkt->getAddr(), pkt->getSize()); - pkt->result = Packet::BadAddress; + if (params()->retBadAddr) { + DPRINTF(Tsunami, "write to bad address va=%#x size=%d \n", + pkt->getAddr(), pkt->getSize()); + pkt->result = Packet::BadAddress; + } else { + DPRINTF(Tsunami, "write - va=%#x size=%d \n", + pkt->getAddr(), pkt->getSize()); + pkt->result = Packet::Success; + } return pioDelay; } @@ -125,6 +113,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(IsaFake) Param pio_addr; Param pio_latency; Param pio_size; + Param ret_bad_addr; + Param ret_data; SimObjectParam platform; SimObjectParam system; @@ -135,6 +125,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(IsaFake) INIT_PARAM(pio_addr, "Device Address"), INIT_PARAM(pio_latency, "Programmed IO latency"), INIT_PARAM(pio_size, "Size of address range"), + INIT_PARAM(ret_bad_addr, "Return pkt status BadAddr"), + INIT_PARAM(ret_data, "Data to return if not bad addr"), INIT_PARAM(platform, "platform"), INIT_PARAM(system, "system object") @@ -147,40 +139,11 @@ CREATE_SIM_OBJECT(IsaFake) p->pio_addr = pio_addr; p->pio_delay = pio_latency; p->pio_size = pio_size; + p->retBadAddr = ret_bad_addr; + p->retData = ret_data; p->platform = platform; p->system = system; return new IsaFake(p); } REGISTER_SIM_OBJECT("IsaFake", IsaFake) - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(BadAddr) - - Param pio_addr; - Param pio_latency; - SimObjectParam platform; - SimObjectParam system; - -END_DECLARE_SIM_OBJECT_PARAMS(BadAddr) - -BEGIN_INIT_SIM_OBJECT_PARAMS(BadAddr) - - INIT_PARAM(pio_addr, "Device Address"), - INIT_PARAM(pio_latency, "Programmed IO latency"), - INIT_PARAM(platform, "platform"), - INIT_PARAM(system, "system object") - -END_INIT_SIM_OBJECT_PARAMS(BadAddr) - -CREATE_SIM_OBJECT(BadAddr) -{ - BadAddr::Params *p = new BadAddr::Params; - p->name = getInstanceName(); - p->pio_addr = pio_addr; - p->pio_delay = pio_latency; - p->platform = platform; - p->system = system; - return new BadAddr(p); -} - -REGISTER_SIM_OBJECT("BadAddr", BadAddr) diff --git a/src/dev/isa_fake.hh b/src/dev/isa_fake.hh index 6665f1a78..c4072e42c 100644 --- a/src/dev/isa_fake.hh +++ b/src/dev/isa_fake.hh @@ -25,8 +25,7 @@ * (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: Miguel Serrano - * Ali Saidi + * Authors: Ali Saidi */ /** @file @@ -42,10 +41,11 @@ #include "mem/packet.hh" /** - * IsaFake is a device that returns -1 on all reads and - * accepts all writes. It is meant to be placed at an address range + * IsaFake is a device that returns, BadAddr, 1 or 0 on all reads and + * rites. It is meant to be placed at an address range * so that an mcheck doesn't occur when an os probes a piece of hw - * that doesn't exist (e.g. UARTs1-3). + * that doesn't exist (e.g. UARTs1-3), or catch requests in the memory system + * that have no responders.. */ class IsaFake : public BasicPioDevice { @@ -53,9 +53,12 @@ class IsaFake : public BasicPioDevice struct Params : public BasicPioDevice::Params { Addr pio_size; + bool retBadAddr; + uint8_t retData; }; protected: const Params *params() const { return (const Params*)_params; } + uint64_t retData; public: /** @@ -77,23 +80,8 @@ class IsaFake : public BasicPioDevice * @param data the data to not write. */ virtual Tick write(PacketPtr pkt); -}; -/** - * BadAddr is a device that fills the packet's result field with "BadAddress". - * @todo: Consider consolidating with IsaFake and similar classes. - */ -class BadAddr : public BasicPioDevice -{ - public: - struct Params : public BasicPioDevice::Params - { - }; - - BadAddr(Params *p); - virtual void init(); - virtual Tick read(PacketPtr pkt); - virtual Tick write(PacketPtr pkt); + void init(); }; -#endif // __TSUNAMI_FAKE_HH__ +#endif // __ISA_FAKE_HH__ diff --git a/src/python/m5/objects/Pci.py b/src/python/m5/objects/Pci.py index 55bf23534..9d40adbfe 100644 --- a/src/python/m5/objects/Pci.py +++ b/src/python/m5/objects/Pci.py @@ -57,6 +57,3 @@ class PciDevice(DmaDevice): pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks") configdata = Param.PciConfigData(Parent.any, "PCI Config data") config_latency = Param.Latency('20ns', "Config read or write latency") - -class PciFake(PciDevice): - type = 'PciFake' diff --git a/src/python/m5/objects/Tsunami.py b/src/python/m5/objects/Tsunami.py index 42bcab089..78ab65b31 100644 --- a/src/python/m5/objects/Tsunami.py +++ b/src/python/m5/objects/Tsunami.py @@ -14,9 +14,11 @@ class TsunamiCChip(BasicPioDevice): class IsaFake(BasicPioDevice): type = 'IsaFake' pio_size = Param.Addr(0x8, "Size of address range") + ret_data = Param.UInt8(0xFF, "Default data to return") + ret_bad_addr = Param.Bool(False, "Return pkt status bad address on access") -class BadAddr(BasicPioDevice): - type = 'BadAddr' +class BadAddr(IsaFake): + ret_bad_addr = Param.Bool(True, "Return pkt status bad address on access") class TsunamiIO(BasicPioDevice): type = 'TsunamiIO' -- cgit v1.2.3 From 1ffff78ca90d04622da78e7d1212148762bccef6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 6 Nov 2006 18:26:11 -0500 Subject: Created seperate SConscript for the dev directory. Made subdirectories for Alpha and SPARC and put SConscripts in them. --HG-- rename : src/base/kgdb.h => src/arch/alpha/kgdb.h rename : src/dev/alpha_access.h => src/dev/alpha/access.h rename : src/dev/alpha_console.cc => src/dev/alpha/console.cc rename : src/dev/alpha_console.hh => src/dev/alpha/console.hh extra : convert_revision : a7dd466308cb83edc40528689aacb72413089cdf --- src/SConscript | 35 +---- src/arch/alpha/kgdb.h | 174 ++++++++++++++++++++++++ src/base/kgdb.h | 174 ------------------------ src/dev/SConscript | 85 ++++++++++++ src/dev/alpha/SConscript | 70 ++++++++++ src/dev/alpha/access.h | 75 ++++++++++ src/dev/alpha/console.cc | 348 +++++++++++++++++++++++++++++++++++++++++++++++ src/dev/alpha/console.hh | 131 ++++++++++++++++++ src/dev/alpha_access.h | 75 ---------- src/dev/alpha_console.cc | 348 ----------------------------------------------- src/dev/alpha_console.hh | 131 ------------------ src/dev/sparc/SConscript | 46 +++++++ 12 files changed, 934 insertions(+), 758 deletions(-) create mode 100644 src/arch/alpha/kgdb.h delete mode 100644 src/base/kgdb.h create mode 100644 src/dev/SConscript create mode 100644 src/dev/alpha/SConscript create mode 100644 src/dev/alpha/access.h create mode 100644 src/dev/alpha/console.cc create mode 100644 src/dev/alpha/console.hh delete mode 100644 src/dev/alpha_access.h delete mode 100644 src/dev/alpha_console.cc delete mode 100644 src/dev/alpha_console.hh create mode 100644 src/dev/sparc/SConscript (limited to 'src') diff --git a/src/SConscript b/src/SConscript index 28f39bc29..b383f58d6 100644 --- a/src/SConscript +++ b/src/SConscript @@ -211,33 +211,6 @@ full_system_sources = Split(''' cpu/intr_control.cc cpu/profile.cc - dev/alpha_console.cc - dev/baddev.cc - dev/disk_image.cc - dev/etherbus.cc - dev/etherdump.cc - dev/etherint.cc - dev/etherlink.cc - dev/etherpkt.cc - dev/ethertap.cc - dev/ide_ctrl.cc - dev/ide_disk.cc - dev/io_device.cc - dev/isa_fake.cc - dev/ns_gige.cc - dev/pciconfigall.cc - dev/pcidev.cc - dev/pcifake.cc - dev/pktfifo.cc - dev/platform.cc - dev/simconsole.cc - dev/simple_disk.cc - dev/tsunami.cc - dev/tsunami_cchip.cc - dev/tsunami_io.cc - dev/tsunami_fake.cc - dev/tsunami_pchip.cc - dev/uart.cc dev/uart8250.cc @@ -254,7 +227,6 @@ full_system_sources = Split(''' #dev/sinic.cc #dev/i8254xGBe.cc - if env['TARGET_ISA'] == 'alpha': full_system_sources += Split(''' kern/tru64/dump_mbuf.cc @@ -318,9 +290,12 @@ env.Append(CPPPATH=Dir('.')) # Add a flag defining what THE_ISA should be for all compilation env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) -arch_sources = SConscript('arch/SConscript', exports = 'env') +arch_sources = SConscript(os.path.join('arch', 'SConscript'), exports = 'env') + +cpu_sources = SConscript(os.path.join('cpu', 'SConscript'), exports = 'env') -cpu_sources = SConscript('cpu/SConscript', exports = 'env') +dev_sources = SConscript(os.path.join('dev', 'SConscript'), exports = 'env') +full_system_sources += dev_sources # This is outside of cpu/SConscript since the source directory isn't # underneath 'cpu'. diff --git a/src/arch/alpha/kgdb.h b/src/arch/alpha/kgdb.h new file mode 100644 index 000000000..104244d0b --- /dev/null +++ b/src/arch/alpha/kgdb.h @@ -0,0 +1,174 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratories. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)remote-sl.h 8.1 (Berkeley) 6/11/93 + */ + +/* $NetBSD: kgdb.h,v 1.4 1998/08/13 02:10:59 eeh Exp $ */ + +#ifndef __KGDB_H__ +#define __KGDB_H__ + +/* + * Message types. + */ +#define KGDB_SIGNAL '?' // last sigal +#define KGDB_SET_BAUD 'b' // set baud (deprecated) +#define KGDB_SET_BREAK 'B' // set breakpoint (deprecated) +#define KGDB_CONT 'c' // resume +#define KGDB_ASYNC_CONT 'C' // continue with signal +#define KGDB_DEBUG 'd' // toggle debug flags (deprecated) +#define KGDB_DETACH 'D' // detach remote gdb +#define KGDB_REG_R 'g' // read general registers +#define KGDB_REG_W 'G' // write general registers +#define KGDB_SET_THREAD 'H' // set thread +#define KGDB_CYCLE_STEP 'i' // step a single cycle +#define KGDB_SIG_CYCLE_STEP 'I' // signal then single cycle step +#define KGDB_KILL 'k' // kill program +#define KGDB_MEM_R 'm' // read memory +#define KGDB_MEM_W 'M' // write memory +#define KGDB_READ_REG 'p' // read register +#define KGDB_SET_REG 'P' // write register +#define KGDB_QUERY_VAR 'q' // query variable +#define KGDB_SET_VAR 'Q' // set variable +#define KGDB_RESET 'r' // reset system. (Deprecated) +#define KGDB_STEP 's' // step +#define KGDB_ASYNC_STEP 'S' // signal and step +#define KGDB_THREAD_ALIVE 'T' // find out if the thread is alive. +#define KGDB_TARGET_EXIT 'W' // target exited +#define KGDB_BINARY_DLOAD 'X' // write memory +#define KGDB_CLR_HW_BKPT 'z' // remove breakpoint or watchpoint +#define KGDB_SET_HW_BKPT 'Z' // insert breakpoint or watchpoint + +/* + * start of frame/end of frame + */ +#define KGDB_START '$' +#define KGDB_END '#' +#define KGDB_GOODP '+' +#define KGDB_BADP '-' + +/* + * Stuff for KGDB. + */ +#define KGDB_NUMREGS 66 /* from tm-alpha.h, NUM_REGS */ +#define KGDB_REG_V0 0 +#define KGDB_REG_T0 1 +#define KGDB_REG_T1 2 +#define KGDB_REG_T2 3 +#define KGDB_REG_T3 4 +#define KGDB_REG_T4 5 +#define KGDB_REG_T5 6 +#define KGDB_REG_T6 7 +#define KGDB_REG_T7 8 +#define KGDB_REG_S0 9 +#define KGDB_REG_S1 10 +#define KGDB_REG_S2 11 +#define KGDB_REG_S3 12 +#define KGDB_REG_S4 13 +#define KGDB_REG_S5 14 +#define KGDB_REG_S6 15 /* FP */ +#define KGDB_REG_A0 16 +#define KGDB_REG_A1 17 +#define KGDB_REG_A2 18 +#define KGDB_REG_A3 19 +#define KGDB_REG_A4 20 +#define KGDB_REG_A5 21 +#define KGDB_REG_T8 22 +#define KGDB_REG_T9 23 +#define KGDB_REG_T10 24 +#define KGDB_REG_T11 25 +#define KGDB_REG_RA 26 +#define KGDB_REG_T12 27 +#define KGDB_REG_AT 28 +#define KGDB_REG_GP 29 +#define KGDB_REG_SP 30 +#define KGDB_REG_ZERO 31 +#define KGDB_REG_F0 32 +#define KGDB_REG_F1 33 +#define KGDB_REG_F2 34 +#define KGDB_REG_F3 35 +#define KGDB_REG_F4 36 +#define KGDB_REG_F5 37 +#define KGDB_REG_F6 38 +#define KGDB_REG_F7 39 +#define KGDB_REG_F8 40 +#define KGDB_REG_F9 41 +#define KGDB_REG_F10 42 +#define KGDB_REG_F11 43 +#define KGDB_REG_F12 44 +#define KGDB_REG_F13 45 +#define KGDB_REG_F14 46 +#define KGDB_REG_F15 47 +#define KGDB_REG_F16 48 +#define KGDB_REG_F17 49 +#define KGDB_REG_F18 50 +#define KGDB_REG_F19 51 +#define KGDB_REG_F20 52 +#define KGDB_REG_F21 53 +#define KGDB_REG_F22 54 +#define KGDB_REG_F23 55 +#define KGDB_REG_F24 56 +#define KGDB_REG_F25 57 +#define KGDB_REG_F26 58 +#define KGDB_REG_F27 59 +#define KGDB_REG_F28 60 +#define KGDB_REG_F29 61 +#define KGDB_REG_F30 62 +#define KGDB_REG_F31 63 +#define KGDB_REG_PC 64 +#define KGDB_REG_VFP 65 + +/* Too much? Must be large enough for register transfer. */ +#define KGDB_BUFLEN 1024 + +/* + * Kernel Entry Vectors. [OSF/1 PALcode Specific] + */ + +#define ALPHA_KENTRY_INT 0 +#define ALPHA_KENTRY_ARITH 1 +#define ALPHA_KENTRY_MM 2 +#define ALPHA_KENTRY_IF 3 +#define ALPHA_KENTRY_UNA 4 +#define ALPHA_KENTRY_SYS 5 + +#endif /* __KGDB_H__ */ diff --git a/src/base/kgdb.h b/src/base/kgdb.h deleted file mode 100644 index 104244d0b..000000000 --- a/src/base/kgdb.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This software was developed by the Computer Systems Engineering group - * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and - * contributed to Berkeley. - * - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Lawrence Berkeley Laboratories. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)remote-sl.h 8.1 (Berkeley) 6/11/93 - */ - -/* $NetBSD: kgdb.h,v 1.4 1998/08/13 02:10:59 eeh Exp $ */ - -#ifndef __KGDB_H__ -#define __KGDB_H__ - -/* - * Message types. - */ -#define KGDB_SIGNAL '?' // last sigal -#define KGDB_SET_BAUD 'b' // set baud (deprecated) -#define KGDB_SET_BREAK 'B' // set breakpoint (deprecated) -#define KGDB_CONT 'c' // resume -#define KGDB_ASYNC_CONT 'C' // continue with signal -#define KGDB_DEBUG 'd' // toggle debug flags (deprecated) -#define KGDB_DETACH 'D' // detach remote gdb -#define KGDB_REG_R 'g' // read general registers -#define KGDB_REG_W 'G' // write general registers -#define KGDB_SET_THREAD 'H' // set thread -#define KGDB_CYCLE_STEP 'i' // step a single cycle -#define KGDB_SIG_CYCLE_STEP 'I' // signal then single cycle step -#define KGDB_KILL 'k' // kill program -#define KGDB_MEM_R 'm' // read memory -#define KGDB_MEM_W 'M' // write memory -#define KGDB_READ_REG 'p' // read register -#define KGDB_SET_REG 'P' // write register -#define KGDB_QUERY_VAR 'q' // query variable -#define KGDB_SET_VAR 'Q' // set variable -#define KGDB_RESET 'r' // reset system. (Deprecated) -#define KGDB_STEP 's' // step -#define KGDB_ASYNC_STEP 'S' // signal and step -#define KGDB_THREAD_ALIVE 'T' // find out if the thread is alive. -#define KGDB_TARGET_EXIT 'W' // target exited -#define KGDB_BINARY_DLOAD 'X' // write memory -#define KGDB_CLR_HW_BKPT 'z' // remove breakpoint or watchpoint -#define KGDB_SET_HW_BKPT 'Z' // insert breakpoint or watchpoint - -/* - * start of frame/end of frame - */ -#define KGDB_START '$' -#define KGDB_END '#' -#define KGDB_GOODP '+' -#define KGDB_BADP '-' - -/* - * Stuff for KGDB. - */ -#define KGDB_NUMREGS 66 /* from tm-alpha.h, NUM_REGS */ -#define KGDB_REG_V0 0 -#define KGDB_REG_T0 1 -#define KGDB_REG_T1 2 -#define KGDB_REG_T2 3 -#define KGDB_REG_T3 4 -#define KGDB_REG_T4 5 -#define KGDB_REG_T5 6 -#define KGDB_REG_T6 7 -#define KGDB_REG_T7 8 -#define KGDB_REG_S0 9 -#define KGDB_REG_S1 10 -#define KGDB_REG_S2 11 -#define KGDB_REG_S3 12 -#define KGDB_REG_S4 13 -#define KGDB_REG_S5 14 -#define KGDB_REG_S6 15 /* FP */ -#define KGDB_REG_A0 16 -#define KGDB_REG_A1 17 -#define KGDB_REG_A2 18 -#define KGDB_REG_A3 19 -#define KGDB_REG_A4 20 -#define KGDB_REG_A5 21 -#define KGDB_REG_T8 22 -#define KGDB_REG_T9 23 -#define KGDB_REG_T10 24 -#define KGDB_REG_T11 25 -#define KGDB_REG_RA 26 -#define KGDB_REG_T12 27 -#define KGDB_REG_AT 28 -#define KGDB_REG_GP 29 -#define KGDB_REG_SP 30 -#define KGDB_REG_ZERO 31 -#define KGDB_REG_F0 32 -#define KGDB_REG_F1 33 -#define KGDB_REG_F2 34 -#define KGDB_REG_F3 35 -#define KGDB_REG_F4 36 -#define KGDB_REG_F5 37 -#define KGDB_REG_F6 38 -#define KGDB_REG_F7 39 -#define KGDB_REG_F8 40 -#define KGDB_REG_F9 41 -#define KGDB_REG_F10 42 -#define KGDB_REG_F11 43 -#define KGDB_REG_F12 44 -#define KGDB_REG_F13 45 -#define KGDB_REG_F14 46 -#define KGDB_REG_F15 47 -#define KGDB_REG_F16 48 -#define KGDB_REG_F17 49 -#define KGDB_REG_F18 50 -#define KGDB_REG_F19 51 -#define KGDB_REG_F20 52 -#define KGDB_REG_F21 53 -#define KGDB_REG_F22 54 -#define KGDB_REG_F23 55 -#define KGDB_REG_F24 56 -#define KGDB_REG_F25 57 -#define KGDB_REG_F26 58 -#define KGDB_REG_F27 59 -#define KGDB_REG_F28 60 -#define KGDB_REG_F29 61 -#define KGDB_REG_F30 62 -#define KGDB_REG_F31 63 -#define KGDB_REG_PC 64 -#define KGDB_REG_VFP 65 - -/* Too much? Must be large enough for register transfer. */ -#define KGDB_BUFLEN 1024 - -/* - * Kernel Entry Vectors. [OSF/1 PALcode Specific] - */ - -#define ALPHA_KENTRY_INT 0 -#define ALPHA_KENTRY_ARITH 1 -#define ALPHA_KENTRY_MM 2 -#define ALPHA_KENTRY_IF 3 -#define ALPHA_KENTRY_UNA 4 -#define ALPHA_KENTRY_SYS 5 - -#endif /* __KGDB_H__ */ diff --git a/src/dev/SConscript b/src/dev/SConscript new file mode 100644 index 000000000..2b8ef28f5 --- /dev/null +++ b/src/dev/SConscript @@ -0,0 +1,85 @@ +# -*- mode:python -*- + +# Copyright (c) 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 +# Gabe Black + +import os.path, sys + +# Import build environment variable from SConstruct. +Import('env') + +# Right now there are no source files immediately in this directory +sources = [] + +# +# Now include other ISA-specific sources from the ISA subdirectories. +# + +isa = env['TARGET_ISA'] # someday this may be a list of ISAs + +# +# These source files can be used by any architecture +# + +sources += Split(''' + baddev.cc + disk_image.cc + etherbus.cc + etherdump.cc + etherint.cc + etherlink.cc + etherpkt.cc + ethertap.cc + ide_ctrl.cc + ide_disk.cc + io_device.cc + isa_fake.cc + ns_gige.cc + pciconfigall.cc + pcidev.cc + pcifake.cc + pktfifo.cc + platform.cc + simconsole.cc + simple_disk.cc + tsunami.cc + tsunami_cchip.cc + tsunami_io.cc + tsunami_fake.cc + tsunami_pchip.cc + ''') + +# Let the target architecture define what additional sources it needs +sources += SConscript(os.path.join(isa, 'SConscript'), exports = 'env') + +# Convert file names to SCons File objects. This takes care of the +# path relative to the top of the directory tree. +sources = [File(s) for s in sources] + +Return('sources') diff --git a/src/dev/alpha/SConscript b/src/dev/alpha/SConscript new file mode 100644 index 000000000..b4b879385 --- /dev/null +++ b/src/dev/alpha/SConscript @@ -0,0 +1,70 @@ +# -*- mode:python -*- + +# Copyright (c) 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 +# Gabe Black + +import os.path, sys + +# Import build environment variable from SConstruct. +Import('env') + +sources = Split(''' + console.cc + ''') +# dev/baddev.cc +# dev/disk_image.cc +# dev/etherbus.cc +# dev/etherdump.cc +# dev/etherint.cc +# dev/etherlink.cc +# dev/etherpkt.cc +# dev/ethertap.cc +# dev/ide_ctrl.cc +# dev/ide_disk.cc +# dev/io_device.cc +# dev/isa_fake.cc +# dev/ns_gige.cc +# dev/pciconfigall.cc +# dev/pcidev.cc +# dev/pcifake.cc +# dev/pktfifo.cc +# dev/platform.cc +# dev/simconsole.cc +# dev/simple_disk.cc +# dev/tsunami.cc +# dev/tsunami_cchip.cc +# dev/tsunami_io.cc +# dev/tsunami_fake.cc +# dev/tsunami_pchip.cc + +# Convert file names to SCons File objects. This takes care of the +# path relative to the top of the directory tree. +sources = [File(s) for s in sources] + +Return('sources') diff --git a/src/dev/alpha/access.h b/src/dev/alpha/access.h new file mode 100644 index 000000000..4adeaf84b --- /dev/null +++ b/src/dev/alpha/access.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2002-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: Nathan Binkert + */ + +#ifndef __ALPHA_ACCESS_H__ +#define __ALPHA_ACCESS_H__ + +/** @file + * System Console Memory Mapped Register Definition + */ + +#define ALPHA_ACCESS_VERSION (1305) + +#ifdef CONSOLE +typedef unsigned uint32_t; +typedef unsigned long uint64_t; +#endif + +// This structure hacked up from simos +struct AlphaAccess +{ + uint32_t last_offset; // 00: must be first field + uint32_t version; // 04: + uint32_t numCPUs; // 08: + uint32_t intrClockFrequency; // 0C: Hz + uint64_t cpuClock; // 10: MHz + uint64_t mem_size; // 18: + + // Loaded kernel + uint64_t kernStart; // 20: + uint64_t kernEnd; // 28: + uint64_t entryPoint; // 30: + + // console disk stuff + uint64_t diskUnit; // 38: + uint64_t diskCount; // 40: + uint64_t diskPAddr; // 48: + uint64_t diskBlock; // 50: + uint64_t diskOperation; // 58: + + // console simple output stuff + uint64_t outputChar; // 60: Placeholder for output + uint64_t inputChar; // 68: Placeholder for input + + // MP boot + uint64_t cpuStack[64]; // 70: +}; + +#endif // __ALPHA_ACCESS_H__ diff --git a/src/dev/alpha/console.cc b/src/dev/alpha/console.cc new file mode 100644 index 000000000..f077efe6c --- /dev/null +++ b/src/dev/alpha/console.cc @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2001-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: Nathan Binkert + * Ali Saidi + * Steve Reinhardt + * Erik Hallnor + */ + +/** @file + * Alpha Console Definition + */ + +#include +#include + +#include "arch/alpha/system.hh" +#include "base/inifile.hh" +#include "base/str.hh" +#include "base/trace.hh" +#include "cpu/base.hh" +#include "cpu/thread_context.hh" +#include "dev/alpha/console.hh" +#include "dev/platform.hh" +#include "dev/simconsole.hh" +#include "dev/simple_disk.hh" +#include "mem/packet.hh" +#include "mem/packet_access.hh" +#include "mem/physical.hh" +#include "sim/builder.hh" +#include "sim/sim_object.hh" + +using namespace std; +using namespace AlphaISA; + +AlphaConsole::AlphaConsole(Params *p) + : BasicPioDevice(p), disk(p->disk), + console(params()->cons), system(params()->alpha_sys), cpu(params()->cpu) +{ + + pioSize = sizeof(struct AlphaAccess); + + alphaAccess = new Access(); + alphaAccess->last_offset = pioSize - 1; + + alphaAccess->version = ALPHA_ACCESS_VERSION; + alphaAccess->diskUnit = 1; + + alphaAccess->diskCount = 0; + alphaAccess->diskPAddr = 0; + alphaAccess->diskBlock = 0; + alphaAccess->diskOperation = 0; + alphaAccess->outputChar = 0; + alphaAccess->inputChar = 0; + bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack)); + +} + +void +AlphaConsole::startup() +{ + system->setAlphaAccess(pioAddr); + alphaAccess->numCPUs = system->getNumCPUs(); + alphaAccess->kernStart = system->getKernelStart(); + alphaAccess->kernEnd = system->getKernelEnd(); + alphaAccess->entryPoint = system->getKernelEntry(); + alphaAccess->mem_size = system->physmem->size(); + alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz + alphaAccess->intrClockFrequency = params()->platform->intrFrequency(); +} + +Tick +AlphaConsole::read(PacketPtr pkt) +{ + + /** XXX Do we want to push the addr munging to a bus brige or something? So + * the device has it's physical address and then the bridge adds on whatever + * machine dependent address swizzle is required? + */ + + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + + Addr daddr = pkt->getAddr() - pioAddr; + + pkt->allocate(); + + switch (pkt->getSize()) + { + case sizeof(uint32_t): + switch (daddr) + { + case offsetof(AlphaAccess, last_offset): + pkt->set(alphaAccess->last_offset); + break; + case offsetof(AlphaAccess, version): + pkt->set(alphaAccess->version); + break; + case offsetof(AlphaAccess, numCPUs): + pkt->set(alphaAccess->numCPUs); + break; + case offsetof(AlphaAccess, intrClockFrequency): + pkt->set(alphaAccess->intrClockFrequency); + break; + default: + /* Old console code read in everyting as a 32bit int + * we now break that for better error checking. + */ + pkt->result = Packet::BadAddress; + } + DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, + pkt->get()); + break; + case sizeof(uint64_t): + switch (daddr) + { + case offsetof(AlphaAccess, inputChar): + pkt->set(console->console_in()); + break; + case offsetof(AlphaAccess, cpuClock): + pkt->set(alphaAccess->cpuClock); + break; + case offsetof(AlphaAccess, mem_size): + pkt->set(alphaAccess->mem_size); + break; + case offsetof(AlphaAccess, kernStart): + pkt->set(alphaAccess->kernStart); + break; + case offsetof(AlphaAccess, kernEnd): + pkt->set(alphaAccess->kernEnd); + break; + case offsetof(AlphaAccess, entryPoint): + pkt->set(alphaAccess->entryPoint); + break; + case offsetof(AlphaAccess, diskUnit): + pkt->set(alphaAccess->diskUnit); + break; + case offsetof(AlphaAccess, diskCount): + pkt->set(alphaAccess->diskCount); + break; + case offsetof(AlphaAccess, diskPAddr): + pkt->set(alphaAccess->diskPAddr); + break; + case offsetof(AlphaAccess, diskBlock): + pkt->set(alphaAccess->diskBlock); + break; + case offsetof(AlphaAccess, diskOperation): + pkt->set(alphaAccess->diskOperation); + break; + case offsetof(AlphaAccess, outputChar): + pkt->set(alphaAccess->outputChar); + break; + default: + int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / + sizeof(alphaAccess->cpuStack[0]); + + if (cpunum >= 0 && cpunum < 64) + pkt->set(alphaAccess->cpuStack[cpunum]); + else + panic("Unknown 64bit access, %#x\n", daddr); + } + DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, + pkt->get()); + break; + default: + pkt->result = Packet::BadAddress; + } + if (pkt->result == Packet::Unknown) + pkt->result = Packet::Success; + return pioDelay; +} + +Tick +AlphaConsole::write(PacketPtr pkt) +{ + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + Addr daddr = pkt->getAddr() - pioAddr; + + uint64_t val = pkt->get(); + assert(pkt->getSize() == sizeof(uint64_t)); + + switch (daddr) { + case offsetof(AlphaAccess, diskUnit): + alphaAccess->diskUnit = val; + break; + + case offsetof(AlphaAccess, diskCount): + alphaAccess->diskCount = val; + break; + + case offsetof(AlphaAccess, diskPAddr): + alphaAccess->diskPAddr = val; + break; + + case offsetof(AlphaAccess, diskBlock): + alphaAccess->diskBlock = val; + break; + + case offsetof(AlphaAccess, diskOperation): + if (val == 0x13) + disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock, + alphaAccess->diskCount); + else + panic("Invalid disk operation!"); + + break; + + case offsetof(AlphaAccess, outputChar): + console->out((char)(val & 0xff)); + break; + + default: + int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / + sizeof(alphaAccess->cpuStack[0]); + warn("%d: Trying to launch CPU number %d!", curTick, cpunum); + assert(val > 0 && "Must not access primary cpu"); + if (cpunum >= 0 && cpunum < 64) + alphaAccess->cpuStack[cpunum] = val; + else + panic("Unknown 64bit access, %#x\n", daddr); + } + + pkt->result = Packet::Success; + + return pioDelay; +} + +void +AlphaConsole::Access::serialize(ostream &os) +{ + SERIALIZE_SCALAR(last_offset); + SERIALIZE_SCALAR(version); + SERIALIZE_SCALAR(numCPUs); + SERIALIZE_SCALAR(mem_size); + SERIALIZE_SCALAR(cpuClock); + SERIALIZE_SCALAR(intrClockFrequency); + SERIALIZE_SCALAR(kernStart); + SERIALIZE_SCALAR(kernEnd); + SERIALIZE_SCALAR(entryPoint); + SERIALIZE_SCALAR(diskUnit); + SERIALIZE_SCALAR(diskCount); + SERIALIZE_SCALAR(diskPAddr); + SERIALIZE_SCALAR(diskBlock); + SERIALIZE_SCALAR(diskOperation); + SERIALIZE_SCALAR(outputChar); + SERIALIZE_SCALAR(inputChar); + SERIALIZE_ARRAY(cpuStack,64); +} + +void +AlphaConsole::Access::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(last_offset); + UNSERIALIZE_SCALAR(version); + UNSERIALIZE_SCALAR(numCPUs); + UNSERIALIZE_SCALAR(mem_size); + UNSERIALIZE_SCALAR(cpuClock); + UNSERIALIZE_SCALAR(intrClockFrequency); + UNSERIALIZE_SCALAR(kernStart); + UNSERIALIZE_SCALAR(kernEnd); + UNSERIALIZE_SCALAR(entryPoint); + UNSERIALIZE_SCALAR(diskUnit); + UNSERIALIZE_SCALAR(diskCount); + UNSERIALIZE_SCALAR(diskPAddr); + UNSERIALIZE_SCALAR(diskBlock); + UNSERIALIZE_SCALAR(diskOperation); + UNSERIALIZE_SCALAR(outputChar); + UNSERIALIZE_SCALAR(inputChar); + UNSERIALIZE_ARRAY(cpuStack, 64); +} + +void +AlphaConsole::serialize(ostream &os) +{ + alphaAccess->serialize(os); +} + +void +AlphaConsole::unserialize(Checkpoint *cp, const std::string §ion) +{ + alphaAccess->unserialize(cp, section); +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) + + SimObjectParam sim_console; + SimObjectParam disk; + Param pio_addr; + SimObjectParam system; + SimObjectParam cpu; + SimObjectParam platform; + Param pio_latency; + +END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) + +BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole) + + INIT_PARAM(sim_console, "The Simulator Console"), + INIT_PARAM(disk, "Simple Disk"), + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(system, "system object"), + INIT_PARAM(cpu, "Processor"), + INIT_PARAM(platform, "platform"), + INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000) + +END_INIT_SIM_OBJECT_PARAMS(AlphaConsole) + +CREATE_SIM_OBJECT(AlphaConsole) +{ + AlphaConsole::Params *p = new AlphaConsole::Params; + p->name = getInstanceName(); + p->platform = platform; + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->cons = sim_console; + p->disk = disk; + p->alpha_sys = system; + p->system = system; + p->cpu = cpu; + return new AlphaConsole(p); +} + +REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole) diff --git a/src/dev/alpha/console.hh b/src/dev/alpha/console.hh new file mode 100644 index 000000000..b8d21ad5d --- /dev/null +++ b/src/dev/alpha/console.hh @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2001-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: Nathan Binkert + */ + +/** @file + * System Console Interface + */ + +#ifndef __ALPHA_CONSOLE_HH__ +#define __ALPHA_CONSOLE_HH__ + +#include "base/range.hh" +#include "dev/alpha/access.h" +#include "dev/io_device.hh" +#include "sim/host.hh" +#include "sim/sim_object.hh" + +class BaseCPU; +class SimConsole; +class AlphaSystem; +class SimpleDisk; + +/** + * Memory mapped interface to the system console. This device + * represents a shared data region between the OS Kernel and the + * System Console. + * + * The system console is a small standalone program that is initially + * run when the system boots. It contains the necessary code to + * access the boot disk, to read/write from the console, and to pass + * boot parameters to the kernel. + * + * This version of the system console is very different from the one + * that would be found in a real system. Many of the functions use + * some sort of backdoor to get their job done. For example, reading + * from the boot device on a real system would require a minimal + * device driver to access the disk controller, but since we have a + * simulator here, we are able to bypass the disk controller and + * access the disk image directly. There are also some things like + * reading the kernel off the disk image into memory that are normally + * taken care of by the console that are now taken care of by the + * simulator. + * + * These shortcuts are acceptable since the system console is + * primarily used doing boot before the kernel has loaded its device + * drivers. + */ +class AlphaConsole : public BasicPioDevice +{ + protected: + struct Access : public AlphaAccess + { + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + }; + + union { + Access *alphaAccess; + uint8_t *consoleData; + }; + + /** the disk must be accessed from the console */ + SimpleDisk *disk; + + /** the system console (the terminal) is accessable from the console */ + SimConsole *console; + + /** a pointer to the system we are running in */ + AlphaSystem *system; + + /** a pointer to the CPU boot cpu */ + BaseCPU *cpu; + + public: + struct Params : public BasicPioDevice::Params + { + SimConsole *cons; + SimpleDisk *disk; + AlphaSystem *alpha_sys; + BaseCPU *cpu; + }; + protected: + const Params *params() const {return (const Params *)_params; } + + public: + + /** Standard Constructor */ + AlphaConsole(Params *p); + + virtual void startup(); + + /** + * memory mapped reads and writes + */ + virtual Tick read(PacketPtr pkt); + virtual Tick write(PacketPtr pkt); + + /** + * standard serialization routines for checkpointing + */ + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +#endif // __ALPHA_CONSOLE_HH__ diff --git a/src/dev/alpha_access.h b/src/dev/alpha_access.h deleted file mode 100644 index 4adeaf84b..000000000 --- a/src/dev/alpha_access.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2002-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: Nathan Binkert - */ - -#ifndef __ALPHA_ACCESS_H__ -#define __ALPHA_ACCESS_H__ - -/** @file - * System Console Memory Mapped Register Definition - */ - -#define ALPHA_ACCESS_VERSION (1305) - -#ifdef CONSOLE -typedef unsigned uint32_t; -typedef unsigned long uint64_t; -#endif - -// This structure hacked up from simos -struct AlphaAccess -{ - uint32_t last_offset; // 00: must be first field - uint32_t version; // 04: - uint32_t numCPUs; // 08: - uint32_t intrClockFrequency; // 0C: Hz - uint64_t cpuClock; // 10: MHz - uint64_t mem_size; // 18: - - // Loaded kernel - uint64_t kernStart; // 20: - uint64_t kernEnd; // 28: - uint64_t entryPoint; // 30: - - // console disk stuff - uint64_t diskUnit; // 38: - uint64_t diskCount; // 40: - uint64_t diskPAddr; // 48: - uint64_t diskBlock; // 50: - uint64_t diskOperation; // 58: - - // console simple output stuff - uint64_t outputChar; // 60: Placeholder for output - uint64_t inputChar; // 68: Placeholder for input - - // MP boot - uint64_t cpuStack[64]; // 70: -}; - -#endif // __ALPHA_ACCESS_H__ diff --git a/src/dev/alpha_console.cc b/src/dev/alpha_console.cc deleted file mode 100644 index 40868de51..000000000 --- a/src/dev/alpha_console.cc +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (c) 2001-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: Nathan Binkert - * Ali Saidi - * Steve Reinhardt - * Erik Hallnor - */ - -/** @file - * Alpha Console Definition - */ - -#include -#include - -#include "arch/alpha/system.hh" -#include "base/inifile.hh" -#include "base/str.hh" -#include "base/trace.hh" -#include "cpu/base.hh" -#include "cpu/thread_context.hh" -#include "dev/alpha_console.hh" -#include "dev/platform.hh" -#include "dev/simconsole.hh" -#include "dev/simple_disk.hh" -#include "mem/packet.hh" -#include "mem/packet_access.hh" -#include "mem/physical.hh" -#include "sim/builder.hh" -#include "sim/sim_object.hh" - -using namespace std; -using namespace AlphaISA; - -AlphaConsole::AlphaConsole(Params *p) - : BasicPioDevice(p), disk(p->disk), - console(params()->cons), system(params()->alpha_sys), cpu(params()->cpu) -{ - - pioSize = sizeof(struct AlphaAccess); - - alphaAccess = new Access(); - alphaAccess->last_offset = pioSize - 1; - - alphaAccess->version = ALPHA_ACCESS_VERSION; - alphaAccess->diskUnit = 1; - - alphaAccess->diskCount = 0; - alphaAccess->diskPAddr = 0; - alphaAccess->diskBlock = 0; - alphaAccess->diskOperation = 0; - alphaAccess->outputChar = 0; - alphaAccess->inputChar = 0; - bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack)); - -} - -void -AlphaConsole::startup() -{ - system->setAlphaAccess(pioAddr); - alphaAccess->numCPUs = system->getNumCPUs(); - alphaAccess->kernStart = system->getKernelStart(); - alphaAccess->kernEnd = system->getKernelEnd(); - alphaAccess->entryPoint = system->getKernelEntry(); - alphaAccess->mem_size = system->physmem->size(); - alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz - alphaAccess->intrClockFrequency = params()->platform->intrFrequency(); -} - -Tick -AlphaConsole::read(PacketPtr pkt) -{ - - /** XXX Do we want to push the addr munging to a bus brige or something? So - * the device has it's physical address and then the bridge adds on whatever - * machine dependent address swizzle is required? - */ - - assert(pkt->result == Packet::Unknown); - assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - - Addr daddr = pkt->getAddr() - pioAddr; - - pkt->allocate(); - - switch (pkt->getSize()) - { - case sizeof(uint32_t): - switch (daddr) - { - case offsetof(AlphaAccess, last_offset): - pkt->set(alphaAccess->last_offset); - break; - case offsetof(AlphaAccess, version): - pkt->set(alphaAccess->version); - break; - case offsetof(AlphaAccess, numCPUs): - pkt->set(alphaAccess->numCPUs); - break; - case offsetof(AlphaAccess, intrClockFrequency): - pkt->set(alphaAccess->intrClockFrequency); - break; - default: - /* Old console code read in everyting as a 32bit int - * we now break that for better error checking. - */ - pkt->result = Packet::BadAddress; - } - DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, - pkt->get()); - break; - case sizeof(uint64_t): - switch (daddr) - { - case offsetof(AlphaAccess, inputChar): - pkt->set(console->console_in()); - break; - case offsetof(AlphaAccess, cpuClock): - pkt->set(alphaAccess->cpuClock); - break; - case offsetof(AlphaAccess, mem_size): - pkt->set(alphaAccess->mem_size); - break; - case offsetof(AlphaAccess, kernStart): - pkt->set(alphaAccess->kernStart); - break; - case offsetof(AlphaAccess, kernEnd): - pkt->set(alphaAccess->kernEnd); - break; - case offsetof(AlphaAccess, entryPoint): - pkt->set(alphaAccess->entryPoint); - break; - case offsetof(AlphaAccess, diskUnit): - pkt->set(alphaAccess->diskUnit); - break; - case offsetof(AlphaAccess, diskCount): - pkt->set(alphaAccess->diskCount); - break; - case offsetof(AlphaAccess, diskPAddr): - pkt->set(alphaAccess->diskPAddr); - break; - case offsetof(AlphaAccess, diskBlock): - pkt->set(alphaAccess->diskBlock); - break; - case offsetof(AlphaAccess, diskOperation): - pkt->set(alphaAccess->diskOperation); - break; - case offsetof(AlphaAccess, outputChar): - pkt->set(alphaAccess->outputChar); - break; - default: - int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / - sizeof(alphaAccess->cpuStack[0]); - - if (cpunum >= 0 && cpunum < 64) - pkt->set(alphaAccess->cpuStack[cpunum]); - else - panic("Unknown 64bit access, %#x\n", daddr); - } - DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, - pkt->get()); - break; - default: - pkt->result = Packet::BadAddress; - } - if (pkt->result == Packet::Unknown) - pkt->result = Packet::Success; - return pioDelay; -} - -Tick -AlphaConsole::write(PacketPtr pkt) -{ - assert(pkt->result == Packet::Unknown); - assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - Addr daddr = pkt->getAddr() - pioAddr; - - uint64_t val = pkt->get(); - assert(pkt->getSize() == sizeof(uint64_t)); - - switch (daddr) { - case offsetof(AlphaAccess, diskUnit): - alphaAccess->diskUnit = val; - break; - - case offsetof(AlphaAccess, diskCount): - alphaAccess->diskCount = val; - break; - - case offsetof(AlphaAccess, diskPAddr): - alphaAccess->diskPAddr = val; - break; - - case offsetof(AlphaAccess, diskBlock): - alphaAccess->diskBlock = val; - break; - - case offsetof(AlphaAccess, diskOperation): - if (val == 0x13) - disk->read(alphaAccess->diskPAddr, alphaAccess->diskBlock, - alphaAccess->diskCount); - else - panic("Invalid disk operation!"); - - break; - - case offsetof(AlphaAccess, outputChar): - console->out((char)(val & 0xff)); - break; - - default: - int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / - sizeof(alphaAccess->cpuStack[0]); - warn("%d: Trying to launch CPU number %d!", curTick, cpunum); - assert(val > 0 && "Must not access primary cpu"); - if (cpunum >= 0 && cpunum < 64) - alphaAccess->cpuStack[cpunum] = val; - else - panic("Unknown 64bit access, %#x\n", daddr); - } - - pkt->result = Packet::Success; - - return pioDelay; -} - -void -AlphaConsole::Access::serialize(ostream &os) -{ - SERIALIZE_SCALAR(last_offset); - SERIALIZE_SCALAR(version); - SERIALIZE_SCALAR(numCPUs); - SERIALIZE_SCALAR(mem_size); - SERIALIZE_SCALAR(cpuClock); - SERIALIZE_SCALAR(intrClockFrequency); - SERIALIZE_SCALAR(kernStart); - SERIALIZE_SCALAR(kernEnd); - SERIALIZE_SCALAR(entryPoint); - SERIALIZE_SCALAR(diskUnit); - SERIALIZE_SCALAR(diskCount); - SERIALIZE_SCALAR(diskPAddr); - SERIALIZE_SCALAR(diskBlock); - SERIALIZE_SCALAR(diskOperation); - SERIALIZE_SCALAR(outputChar); - SERIALIZE_SCALAR(inputChar); - SERIALIZE_ARRAY(cpuStack,64); -} - -void -AlphaConsole::Access::unserialize(Checkpoint *cp, const std::string §ion) -{ - UNSERIALIZE_SCALAR(last_offset); - UNSERIALIZE_SCALAR(version); - UNSERIALIZE_SCALAR(numCPUs); - UNSERIALIZE_SCALAR(mem_size); - UNSERIALIZE_SCALAR(cpuClock); - UNSERIALIZE_SCALAR(intrClockFrequency); - UNSERIALIZE_SCALAR(kernStart); - UNSERIALIZE_SCALAR(kernEnd); - UNSERIALIZE_SCALAR(entryPoint); - UNSERIALIZE_SCALAR(diskUnit); - UNSERIALIZE_SCALAR(diskCount); - UNSERIALIZE_SCALAR(diskPAddr); - UNSERIALIZE_SCALAR(diskBlock); - UNSERIALIZE_SCALAR(diskOperation); - UNSERIALIZE_SCALAR(outputChar); - UNSERIALIZE_SCALAR(inputChar); - UNSERIALIZE_ARRAY(cpuStack, 64); -} - -void -AlphaConsole::serialize(ostream &os) -{ - alphaAccess->serialize(os); -} - -void -AlphaConsole::unserialize(Checkpoint *cp, const std::string §ion) -{ - alphaAccess->unserialize(cp, section); -} - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) - - SimObjectParam sim_console; - SimObjectParam disk; - Param pio_addr; - SimObjectParam system; - SimObjectParam cpu; - SimObjectParam platform; - Param pio_latency; - -END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) - -BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole) - - INIT_PARAM(sim_console, "The Simulator Console"), - INIT_PARAM(disk, "Simple Disk"), - INIT_PARAM(pio_addr, "Device Address"), - INIT_PARAM(system, "system object"), - INIT_PARAM(cpu, "Processor"), - INIT_PARAM(platform, "platform"), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000) - -END_INIT_SIM_OBJECT_PARAMS(AlphaConsole) - -CREATE_SIM_OBJECT(AlphaConsole) -{ - AlphaConsole::Params *p = new AlphaConsole::Params; - p->name = getInstanceName(); - p->platform = platform; - p->pio_addr = pio_addr; - p->pio_delay = pio_latency; - p->cons = sim_console; - p->disk = disk; - p->alpha_sys = system; - p->system = system; - p->cpu = cpu; - return new AlphaConsole(p); -} - -REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole) diff --git a/src/dev/alpha_console.hh b/src/dev/alpha_console.hh deleted file mode 100644 index 7d6d1e679..000000000 --- a/src/dev/alpha_console.hh +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2001-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: Nathan Binkert - */ - -/** @file - * System Console Interface - */ - -#ifndef __ALPHA_CONSOLE_HH__ -#define __ALPHA_CONSOLE_HH__ - -#include "base/range.hh" -#include "dev/alpha_access.h" -#include "dev/io_device.hh" -#include "sim/host.hh" -#include "sim/sim_object.hh" - -class BaseCPU; -class SimConsole; -class AlphaSystem; -class SimpleDisk; - -/** - * Memory mapped interface to the system console. This device - * represents a shared data region between the OS Kernel and the - * System Console. - * - * The system console is a small standalone program that is initially - * run when the system boots. It contains the necessary code to - * access the boot disk, to read/write from the console, and to pass - * boot parameters to the kernel. - * - * This version of the system console is very different from the one - * that would be found in a real system. Many of the functions use - * some sort of backdoor to get their job done. For example, reading - * from the boot device on a real system would require a minimal - * device driver to access the disk controller, but since we have a - * simulator here, we are able to bypass the disk controller and - * access the disk image directly. There are also some things like - * reading the kernel off the disk image into memory that are normally - * taken care of by the console that are now taken care of by the - * simulator. - * - * These shortcuts are acceptable since the system console is - * primarily used doing boot before the kernel has loaded its device - * drivers. - */ -class AlphaConsole : public BasicPioDevice -{ - protected: - struct Access : public AlphaAccess - { - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); - }; - - union { - Access *alphaAccess; - uint8_t *consoleData; - }; - - /** the disk must be accessed from the console */ - SimpleDisk *disk; - - /** the system console (the terminal) is accessable from the console */ - SimConsole *console; - - /** a pointer to the system we are running in */ - AlphaSystem *system; - - /** a pointer to the CPU boot cpu */ - BaseCPU *cpu; - - public: - struct Params : public BasicPioDevice::Params - { - SimConsole *cons; - SimpleDisk *disk; - AlphaSystem *alpha_sys; - BaseCPU *cpu; - }; - protected: - const Params *params() const {return (const Params *)_params; } - - public: - - /** Standard Constructor */ - AlphaConsole(Params *p); - - virtual void startup(); - - /** - * memory mapped reads and writes - */ - virtual Tick read(PacketPtr pkt); - virtual Tick write(PacketPtr pkt); - - /** - * standard serialization routines for checkpointing - */ - virtual void serialize(std::ostream &os); - virtual void unserialize(Checkpoint *cp, const std::string §ion); -}; - -#endif // __ALPHA_CONSOLE_HH__ diff --git a/src/dev/sparc/SConscript b/src/dev/sparc/SConscript new file mode 100644 index 000000000..701e533a8 --- /dev/null +++ b/src/dev/sparc/SConscript @@ -0,0 +1,46 @@ +# -*- mode:python -*- + +# Copyright (c) 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 +# Gabe Black + +import os.path, sys + +# Import build environment variable from SConstruct. +Import('env') + +sources = [] + +sources += Split(''' + ''') + +# Convert file names to SCons File objects. This takes care of the +# path relative to the top of the directory tree. +sources = [File(s) for s in sources] + +Return('sources') -- cgit v1.2.3 From e39de58d21723df527ec979cde1df29980fab234 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 6 Nov 2006 18:28:10 -0500 Subject: Took the Alpha prefix off of AlphaArguments, and made sure it was being used from TheISA:: rather than AlphaISA:: --HG-- extra : convert_revision : 17c143d3cbc2f58a7a9d01366a8f649810ff7f33 --- src/arch/alpha/arguments.cc | 6 +++--- src/arch/alpha/arguments.hh | 30 +++++++++++++++--------------- src/kern/linux/events.cc | 2 +- src/kern/linux/printk.cc | 2 +- src/kern/linux/printk.hh | 6 ++++-- src/kern/tru64/dump_mbuf.cc | 2 +- src/kern/tru64/dump_mbuf.hh | 2 +- src/kern/tru64/printf.cc | 2 +- src/kern/tru64/printf.hh | 2 +- src/kern/tru64/tru64_events.cc | 6 +++--- 10 files changed, 31 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/arguments.cc b/src/arch/alpha/arguments.cc index 9f9002003..e89bd70b0 100644 --- a/src/arch/alpha/arguments.cc +++ b/src/arch/alpha/arguments.cc @@ -35,7 +35,7 @@ using namespace AlphaISA; -AlphaArguments::Data::~Data() +Arguments::Data::~Data() { while (!data.empty()) { delete [] data.front(); @@ -44,7 +44,7 @@ AlphaArguments::Data::~Data() } char * -AlphaArguments::Data::alloc(size_t size) +Arguments::Data::alloc(size_t size) { char *buf = new char[size]; data.push_back(buf); @@ -52,7 +52,7 @@ AlphaArguments::Data::alloc(size_t size) } uint64_t -AlphaArguments::getArg(bool fp) +Arguments::getArg(bool fp) { if (number < 6) { if (fp) diff --git a/src/arch/alpha/arguments.hh b/src/arch/alpha/arguments.hh index d977d48d6..c44181a8d 100644 --- a/src/arch/alpha/arguments.hh +++ b/src/arch/alpha/arguments.hh @@ -41,7 +41,7 @@ class ThreadContext; namespace AlphaISA { -class AlphaArguments +class Arguments { protected: ThreadContext *tc; @@ -65,62 +65,62 @@ class AlphaArguments RefCountingPtr data; public: - AlphaArguments(ThreadContext *ctx, int n = 0) + Arguments(ThreadContext *ctx, int n = 0) : tc(ctx), number(n), data(NULL) { assert(number >= 0); data = new Data;} - AlphaArguments(const AlphaArguments &args) + Arguments(const Arguments &args) : tc(args.tc), number(args.number), data(args.data) {} - ~AlphaArguments() {} + ~Arguments() {} ThreadContext *getThreadContext() const { return tc; } - const AlphaArguments &operator=(const AlphaArguments &args) { + const Arguments &operator=(const Arguments &args) { tc = args.tc; number = args.number; data = args.data; return *this; } - AlphaArguments &operator++() { + Arguments &operator++() { ++number; assert(number >= 0); return *this; } - AlphaArguments operator++(int) { - AlphaArguments args = *this; + Arguments operator++(int) { + Arguments args = *this; ++number; assert(number >= 0); return args; } - AlphaArguments &operator--() { + Arguments &operator--() { --number; assert(number >= 0); return *this; } - AlphaArguments operator--(int) { - AlphaArguments args = *this; + Arguments operator--(int) { + Arguments args = *this; --number; assert(number >= 0); return args; } - const AlphaArguments &operator+=(int index) { + const Arguments &operator+=(int index) { number += index; assert(number >= 0); return *this; } - const AlphaArguments &operator-=(int index) { + const Arguments &operator-=(int index) { number -= index; assert(number >= 0); return *this; } - AlphaArguments operator[](int index) { - return AlphaArguments(tc, index); + Arguments operator[](int index) { + return Arguments(tc, index); } template diff --git a/src/kern/linux/events.cc b/src/kern/linux/events.cc index 289ece5ce..ba52e040a 100644 --- a/src/kern/linux/events.cc +++ b/src/kern/linux/events.cc @@ -49,7 +49,7 @@ DebugPrintkEvent::process(ThreadContext *tc) DPRINTFN(""); } - AlphaISA::AlphaArguments args(tc); + TheISA::Arguments args(tc); Printk(args); SkipFuncEvent::process(tc); } diff --git a/src/kern/linux/printk.cc b/src/kern/linux/printk.cc index 004d1be2f..ea3d59f19 100644 --- a/src/kern/linux/printk.cc +++ b/src/kern/linux/printk.cc @@ -39,7 +39,7 @@ using namespace std; void -Printk(AlphaISA::AlphaArguments args) +Printk(TheISA::Arguments args) { char *p = (char *)args++; diff --git a/src/kern/linux/printk.hh b/src/kern/linux/printk.hh index 5ddf0a018..17d59b765 100644 --- a/src/kern/linux/printk.hh +++ b/src/kern/linux/printk.hh @@ -32,8 +32,10 @@ #ifndef __PRINTK_HH__ #define __PRINTK_HH__ -class AlphaISA::AlphaArguments; +#include "arch/isa_specific.hh" -void Printk(AlphaISA::AlphaArguments args); +class TheISA::Arguments; + +void Printk(TheISA::Arguments args); #endif // __PRINTK_HH__ diff --git a/src/kern/tru64/dump_mbuf.cc b/src/kern/tru64/dump_mbuf.cc index 8f88f8904..22d2228f0 100644 --- a/src/kern/tru64/dump_mbuf.cc +++ b/src/kern/tru64/dump_mbuf.cc @@ -47,7 +47,7 @@ using namespace TheISA; namespace tru64 { void -DumpMbuf(AlphaArguments args) +DumpMbuf(Arguments args) { ThreadContext *tc = args.getThreadContext(); Addr addr = (Addr)args; diff --git a/src/kern/tru64/dump_mbuf.hh b/src/kern/tru64/dump_mbuf.hh index 25c6fd31d..30b1102b9 100644 --- a/src/kern/tru64/dump_mbuf.hh +++ b/src/kern/tru64/dump_mbuf.hh @@ -34,7 +34,7 @@ #include "arch/arguments.hh" namespace tru64 { - void DumpMbuf(AlphaISA::AlphaArguments args); + void DumpMbuf(TheISA::Arguments args); } #endif // __DUMP_MBUF_HH__ diff --git a/src/kern/tru64/printf.cc b/src/kern/tru64/printf.cc index 29dd443d2..2c767c4d2 100644 --- a/src/kern/tru64/printf.cc +++ b/src/kern/tru64/printf.cc @@ -42,7 +42,7 @@ using namespace std; namespace tru64 { void -Printf(AlphaISA::AlphaArguments args) +Printf(TheISA::Arguments args) { char *p = (char *)args++; diff --git a/src/kern/tru64/printf.hh b/src/kern/tru64/printf.hh index f6a4544ad..ff453b1c1 100644 --- a/src/kern/tru64/printf.hh +++ b/src/kern/tru64/printf.hh @@ -34,7 +34,7 @@ #include "arch/arguments.hh" namespace tru64 { - void Printf(AlphaISA::AlphaArguments args); + void Printf(TheISA::Arguments args); } #endif // __PRINTF_HH__ diff --git a/src/kern/tru64/tru64_events.cc b/src/kern/tru64/tru64_events.cc index 69638bde1..851b3a526 100644 --- a/src/kern/tru64/tru64_events.cc +++ b/src/kern/tru64/tru64_events.cc @@ -81,7 +81,7 @@ PrintfEvent::process(ThreadContext *tc) if (DTRACE(Printf)) { DebugOut() << curTick << ": " << tc->getCpuPtr()->name() << ": "; - AlphaArguments args(tc); + Arguments args(tc); tru64::Printf(args); } } @@ -93,7 +93,7 @@ DebugPrintfEvent::process(ThreadContext *tc) if (!raw) DebugOut() << curTick << ": " << tc->getCpuPtr()->name() << ": "; - AlphaArguments args(tc); + Arguments args(tc); tru64::Printf(args); } } @@ -102,7 +102,7 @@ void DumpMbufEvent::process(ThreadContext *tc) { if (DTRACE(DebugPrintf)) { - AlphaArguments args(tc); + Arguments args(tc); tru64::DumpMbuf(args); } } -- cgit v1.2.3 From 85a6079db7c2e7146dc437c9c032d2aa56dd9048 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 6 Nov 2006 18:29:58 -0500 Subject: Remote GDB support has been changed to use inheritance. Alpha should work, but isn't tested. Other architectures will not. --HG-- extra : convert_revision : fc7e1e73e2f3b1a4ab9905a1eb98c5f07c6c8707 --- src/arch/SConscript | 1 + src/arch/alpha/SConscript | 1 + src/arch/alpha/ev5.cc | 2 +- src/arch/alpha/remote_gdb.cc | 424 +++++++++++++++++++++++++++++++++++++++ src/arch/alpha/remote_gdb.hh | 130 ++++++++++++ src/arch/alpha/system.cc | 2 +- src/arch/sparc/remote_gdb.cc | 456 ++++++++++++++++++++++++++++++++++++++++++ src/arch/sparc/remote_gdb.hh | 129 ++++++++++++ src/base/remote_gdb.cc | 461 ++++++++++++------------------------------- src/base/remote_gdb.hh | 125 ++++++++---- src/cpu/o3/fetch_impl.hh | 1 - src/sim/system.cc | 2 +- src/sim/system.hh | 7 +- 13 files changed, 1368 insertions(+), 373 deletions(-) create mode 100644 src/arch/alpha/remote_gdb.cc create mode 100644 src/arch/alpha/remote_gdb.hh create mode 100644 src/arch/sparc/remote_gdb.cc create mode 100644 src/arch/sparc/remote_gdb.hh (limited to 'src') diff --git a/src/arch/SConscript b/src/arch/SConscript index 092fad225..2ef3d5ee0 100644 --- a/src/arch/SConscript +++ b/src/arch/SConscript @@ -54,6 +54,7 @@ isa_switch_hdrs = Split(''' locked_mem.hh process.hh regfile.hh + remote_gdb.hh stacktrace.hh syscallreturn.hh tlb.hh diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript index 9a5680649..2d733d73b 100644 --- a/src/arch/alpha/SConscript +++ b/src/arch/alpha/SConscript @@ -60,6 +60,7 @@ full_system_sources = Split(''' osfpal.cc stacktrace.cc vtophys.cc + remote_gdb.cc system.cc freebsd/system.cc linux/system.cc diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index dca948bbd..6f8f255b4 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -33,7 +33,7 @@ #include "arch/alpha/isa_traits.hh" #include "arch/alpha/osfpal.hh" #include "arch/alpha/tlb.hh" -#include "base/kgdb.h" +#include "arch/alpha/kgdb.h" #include "base/remote_gdb.hh" #include "base/stats/events.hh" #include "config/full_system.hh" diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc new file mode 100644 index 000000000..96c7ea6e2 --- /dev/null +++ b/src/arch/alpha/remote_gdb.cc @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2002-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: Nathan Binkert + */ + +/* + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratories. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 + */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * $NetBSD: kgdb_stub.c,v 1.8 2001/07/07 22:58:00 wdk Exp $ + * + * Taken from NetBSD + * + * "Stub" to allow remote cpu to debug over a serial line using gdb. + */ + +#include + +#include +#include + +#include "arch/vtophys.hh" +#include "arch/alpha/remote_gdb.hh" +#include "base/intmath.hh" +#include "base/remote_gdb.hh" +#include "base/socket.hh" +#include "base/trace.hh" +#include "config/full_system.hh" +#include "cpu/thread_context.hh" +#include "cpu/static_inst.hh" +#include "mem/physical.hh" +#include "mem/port.hh" +#include "sim/system.hh" + +using namespace std; +using namespace AlphaISA; + +RemoteGDB::Event::Event(RemoteGDB *g, int fd, int e) + : PollEvent(fd, e), gdb(g) +{} + +void +RemoteGDB::Event::process(int revent) +{ + if (revent & POLLIN) + gdb->trap(ALPHA_KENTRY_IF); + else if (revent & POLLNVAL) + gdb->detach(); +} + +RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) + : BaseRemoteGDB(_system, c, KGDB_NUMREGS), + event(NULL) +{} + +RemoteGDB::~RemoteGDB() +{ + if (event) + delete event; +} + +/////////////////////////////////////////////////////////// +// RemoteGDB::acc +// +// Determine if the mapping at va..(va+len) is valid. +// +bool +RemoteGDB::acc(Addr va, size_t len) +{ + Addr last_va; + + va = TheISA::TruncPage(va); + last_va = TheISA::RoundPage(va + len); + + do { + if (TheISA::IsK0Seg(va)) { + if (va < (TheISA::K0SegBase + pmem->size())) { + DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= " + "%#x < K0SEG + size\n", va); + return true; + } else { + DPRINTF(GDBAcc, "acc: Mapping invalid %#x > K0SEG + size\n", + va); + return false; + } + } + + /** + * This code says that all accesses to palcode (instruction and data) + * are valid since there isn't a va->pa mapping because palcode is + * accessed physically. At some point this should probably be cleaned up + * but there is no easy way to do it. + */ + + if (AlphaISA::PcPAL(va) || va < 0x10000) + return true; + + Addr ptbr = context->readMiscReg(AlphaISA::IPR_PALtemp20); + TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va); + if (!pte.valid()) { + DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); + return false; + } + va += TheISA::PageBytes; + } while (va < last_va); + + DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va); + return true; +} + +/////////////////////////////////////////////////////////// +// RemoteGDB::getregs +// +// Translate the kernel debugger register format into +// the GDB register format. +void +RemoteGDB::getregs() +{ + memset(gdbregs.regs, 0, gdbregs.size); + + gdbregs.regs[KGDB_REG_PC] = context->readPC(); + + // @todo: Currently this is very Alpha specific. + if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) { + for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + gdbregs.regs[i] = context->readIntReg(AlphaISA::reg_redir[i]); + } + } else { + for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + gdbregs.regs[i] = context->readIntReg(i); + } + } + +#ifdef KGDB_FP_REGS + for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { + gdbregs.regs[i + KGDB_REG_F0] = context->readFloatRegBits(i); + } +#endif +} + +/////////////////////////////////////////////////////////// +// RemoteGDB::setregs +// +// Translate the GDB register format into the kernel +// debugger register format. +// +void +RemoteGDB::setregs() +{ + // @todo: Currently this is very Alpha specific. + if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) { + for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + context->setIntReg(AlphaISA::reg_redir[i], gdbregs.regs[i]); + } + } else { + for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + context->setIntReg(i, gdbregs.regs[i]); + } + } + +#ifdef KGDB_FP_REGS + for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { + context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]); + } +#endif + context->setPC(gdbregs.regs[KGDB_REG_PC]); +} + +void +RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr) +{ + DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", addr); + + bkpt.address = addr; + insertHardBreak(addr, 4); +} + +void +RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt) +{ + DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", + bkpt.address); + + + removeHardBreak(bkpt.address, 4); + bkpt.address = 0; +} + +void +RemoteGDB::clearSingleStep() +{ + DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n", + takenBkpt.address, notTakenBkpt.address); + + if (takenBkpt.address != 0) + clearTempBreakpoint(takenBkpt); + + if (notTakenBkpt.address != 0) + clearTempBreakpoint(notTakenBkpt); +} + +void +RemoteGDB::setSingleStep() +{ + Addr pc = context->readPC(); + Addr npc, bpc; + bool set_bt = false; + + npc = pc + sizeof(MachInst); + + // User was stopped at pc, e.g. the instruction at pc was not + // executed. + MachInst inst = read(pc); + StaticInstPtr si(inst); + if (si->hasBranchTarget(pc, context, bpc)) { + // Don't bother setting a breakpoint on the taken branch if it + // is the same as the next pc + if (bpc != npc) + set_bt = true; + } + + DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n", + takenBkpt.address, notTakenBkpt.address); + + setTempBreakpoint(notTakenBkpt, npc); + + if (set_bt) + setTempBreakpoint(takenBkpt, bpc); +} + +// Write bytes to kernel address space for debugger. +bool +RemoteGDB::write(Addr vaddr, size_t size, const char *data) +{ + if (BaseRemoteGDB::write(vaddr, size, data)) { +#ifdef IMB + alpha_pal_imb(); +#endif + return true; + } else { + return false; + } +} + + +PCEventQueue *RemoteGDB::getPcEventQueue() +{ + return &system->pcEventQueue; +} + + +RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc) + : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc), + gdb(_gdb), refcount(0) +{ + DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc); +} + +void +RemoteGDB::HardBreakpoint::process(ThreadContext *tc) +{ + DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc()); + + if (tc == gdb->context) + gdb->trap(ALPHA_KENTRY_INT); +} + +bool +RemoteGDB::insertSoftBreak(Addr addr, size_t len) +{ + if (len != sizeof(MachInst)) + panic("invalid length\n"); + + return insertHardBreak(addr, len); +} + +bool +RemoteGDB::removeSoftBreak(Addr addr, size_t len) +{ + if (len != sizeof(MachInst)) + panic("invalid length\n"); + + return removeHardBreak(addr, len); +} + +bool +RemoteGDB::insertHardBreak(Addr addr, size_t len) +{ + if (len != sizeof(MachInst)) + panic("invalid length\n"); + + DPRINTF(GDBMisc, "inserting hardware breakpoint at %#x\n", addr); + + HardBreakpoint *&bkpt = hardBreakMap[addr]; + if (bkpt == 0) + bkpt = new HardBreakpoint(this, addr); + + bkpt->refcount++; + + return true; +} + +bool +RemoteGDB::removeHardBreak(Addr addr, size_t len) +{ + if (len != sizeof(MachInst)) + panic("invalid length\n"); + + DPRINTF(GDBMisc, "removing hardware breakpoint at %#x\n", addr); + + break_iter_t i = hardBreakMap.find(addr); + if (i == hardBreakMap.end()) + return false; + + HardBreakpoint *hbp = (*i).second; + if (--hbp->refcount == 0) { + delete hbp; + hardBreakMap.erase(i); + } + + return true; +} diff --git a/src/arch/alpha/remote_gdb.hh b/src/arch/alpha/remote_gdb.hh new file mode 100644 index 000000000..1dd4ada38 --- /dev/null +++ b/src/arch/alpha/remote_gdb.hh @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2002-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: Nathan Binkert + */ + +#ifndef __ARCH_ALPHA_REMOTE_GDB_HH__ +#define __ARCH_ALPHA_REMOTE_GDB_HH__ + +#include + +#include "arch/alpha/types.hh" +#include "arch/alpha/kgdb.h" +#include "base/remote_gdb.hh" +#include "cpu/pc_event.hh" +#include "base/pollevent.hh" +#include "base/socket.hh" + +class System; +class ThreadContext; +class PhysicalMemory; + +namespace AlphaISA +{ + class RemoteGDB : public BaseRemoteGDB + { + private: + friend void debugger(); + friend class GDBListener; + + protected: + class Event : public PollEvent + { + protected: + RemoteGDB *gdb; + + public: + Event(RemoteGDB *g, int fd, int e); + void process(int revent); + }; + + friend class Event; + Event *event; + + protected: + // Machine memory + bool write(Addr addr, size_t size, const char *data); + + public: + RemoteGDB(System *system, ThreadContext *context); + ~RemoteGDB(); + + bool acc(Addr addr, size_t len); + + protected: + void getregs(); + void setregs(); + + void clearSingleStep(); + void setSingleStep(); + + PCEventQueue *getPcEventQueue(); + + protected: + class HardBreakpoint : public PCEvent + { + private: + RemoteGDB *gdb; + + public: + int refcount; + + public: + HardBreakpoint(RemoteGDB *_gdb, Addr addr); + std::string name() { return gdb->name() + ".hwbkpt"; } + + virtual void process(ThreadContext *tc); + }; + friend class HardBreakpoint; + + typedef std::map break_map_t; + typedef break_map_t::iterator break_iter_t; + break_map_t hardBreakMap; + + bool insertSoftBreak(Addr addr, size_t len); + bool removeSoftBreak(Addr addr, size_t len); + bool insertHardBreak(Addr addr, size_t len); + bool removeHardBreak(Addr addr, size_t len); + + protected: + struct TempBreakpoint { + Addr address; // set here + MachInst bkpt_inst; // saved instruction at bkpt + int init_count; // number of times to skip bkpt + int count; // current count + }; + + TempBreakpoint notTakenBkpt; + TempBreakpoint takenBkpt; + + void clearTempBreakpoint(TempBreakpoint &bkpt); + void setTempBreakpoint(TempBreakpoint &bkpt, Addr addr); + }; +} + +#endif /* __ARCH_ALPHA_REMOTE_GDB_H__ */ diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc index 5597eaedc..710f6ef46 100644 --- a/src/arch/alpha/system.cc +++ b/src/arch/alpha/system.cc @@ -31,8 +31,8 @@ #include "arch/alpha/ev5.hh" #include "arch/alpha/system.hh" +#include "arch/alpha/remote_gdb.hh" #include "arch/vtophys.hh" -#include "base/remote_gdb.hh" #include "base/loader/object_file.hh" #include "base/loader/symtab.hh" #include "base/trace.hh" diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc new file mode 100644 index 000000000..2e662af7f --- /dev/null +++ b/src/arch/sparc/remote_gdb.cc @@ -0,0 +1,456 @@ +/* + * Copyright (c) 2002-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: Nathan Binkert + */ + +/* + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratories. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 + */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * $NetBSD: kgdb_stub.c,v 1.8 2001/07/07 22:58:00 wdk Exp $ + * + * Taken from NetBSD + * + * "Stub" to allow remote cpu to debug over a serial line using gdb. + */ + +#include + +#include +#include + +#include "arch/vtophys.hh" +#include "arch/sparc/remote_gdb.hh" +#include "base/intmath.hh" +#include "base/kgdb.h" +#include "base/remote_gdb.hh" +#include "base/socket.hh" +#include "base/trace.hh" +#include "config/full_system.hh" +#include "cpu/thread_context.hh" +#include "cpu/static_inst.hh" +#include "mem/physical.hh" +#include "mem/port.hh" +#include "sim/system.hh" + +using namespace std; +using namespace TheISA; + +RemoteGDB::Event::Event(RemoteGDB *g, int fd, int e) + : PollEvent(fd, e), gdb(g) +{} + +void +RemoteGDB::Event::process(int revent) +{ + if (revent & POLLIN) + gdb->trap(ALPHA_KENTRY_IF); + else if (revent & POLLNVAL) + gdb->detach(); +} + +RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) + : BaseRemoteGDB(_system, c, KGDB_NUMREGS), + event(NULL) +{} + +RemoteGDB::~RemoteGDB() +{ + if (event) + delete event; +} + +/////////////////////////////////////////////////////////// +// RemoteGDB::acc +// +// Determine if the mapping at va..(va+len) is valid. +// +bool +RemoteGDB::acc(Addr va, size_t len) +{ + Addr last_va; + + va = TheISA::TruncPage(va); + last_va = TheISA::RoundPage(va + len); + + do { + if (TheISA::IsK0Seg(va)) { + if (va < (TheISA::K0SegBase + pmem->size())) { + DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= " + "%#x < K0SEG + size\n", va); + return true; + } else { + DPRINTF(GDBAcc, "acc: Mapping invalid %#x > K0SEG + size\n", + va); + return false; + } + } + + /** + * This code says that all accesses to palcode (instruction and data) + * are valid since there isn't a va->pa mapping because palcode is + * accessed physically. At some point this should probably be cleaned up + * but there is no easy way to do it. + */ + + if (AlphaISA::PcPAL(va) || va < 0x10000) + return true; + + Addr ptbr = context->readMiscReg(AlphaISA::IPR_PALtemp20); + TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va); + if (!pte.valid()) { + DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); + return false; + } + va += TheISA::PageBytes; + } while (va < last_va); + + DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va); + return true; +} + +/////////////////////////////////////////////////////////// +// RemoteGDB::signal +// +// Translate a trap number into a Unix-compatible signal number. +// (GDB only understands Unix signal numbers.) +// +int +RemoteGDB::signal(int type) +{ + switch (type) { + case ALPHA_KENTRY_INT: + return (SIGTRAP); + + case ALPHA_KENTRY_UNA: + return (SIGBUS); + + case ALPHA_KENTRY_ARITH: + return (SIGFPE); + + case ALPHA_KENTRY_IF: + return (SIGILL); + + case ALPHA_KENTRY_MM: + return (SIGSEGV); + + default: + panic("unknown signal type"); + return 0; + } +} + +/////////////////////////////////////////////////////////// +// RemoteGDB::getregs +// +// Translate the kernel debugger register format into +// the GDB register format. +void +RemoteGDB::getregs() +{ + memset(gdbregs.regs, 0, gdbregs.size); + + gdbregs.regs[KGDB_REG_PC] = context->readPC(); + + // @todo: Currently this is very Alpha specific. + if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) { + for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + gdbregs.regs[i] = context->readIntReg(AlphaISA::reg_redir[i]); + } + } else { + for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + gdbregs.regs[i] = context->readIntReg(i); + } + } + +#ifdef KGDB_FP_REGS + for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { + gdbregs.regs[i + KGDB_REG_F0] = context->readFloatRegBits(i); + } +#endif +} + +/////////////////////////////////////////////////////////// +// RemoteGDB::setregs +// +// Translate the GDB register format into the kernel +// debugger register format. +// +void +RemoteGDB::setregs() +{ + // @todo: Currently this is very Alpha specific. + if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) { + for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + context->setIntReg(AlphaISA::reg_redir[i], gdbregs.regs[i]); + } + } else { + for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + context->setIntReg(i, gdbregs.regs[i]); + } + } + +#ifdef KGDB_FP_REGS + for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { + context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]); + } +#endif + context->setPC(gdbregs.regs[KGDB_REG_PC]); +} + +void +RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr) +{ + DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", addr); + + bkpt.address = addr; + insertHardBreak(addr, 4); +} + +void +RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt) +{ + DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", + bkpt.address); + + + removeHardBreak(bkpt.address, 4); + bkpt.address = 0; +} + +void +RemoteGDB::clearSingleStep() +{ + DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n", + takenBkpt.address, notTakenBkpt.address); + + if (takenBkpt.address != 0) + clearTempBreakpoint(takenBkpt); + + if (notTakenBkpt.address != 0) + clearTempBreakpoint(notTakenBkpt); +} + +void +RemoteGDB::setSingleStep() +{ + Addr pc = context->readPC(); + Addr npc, bpc; + bool set_bt = false; + + npc = pc + sizeof(MachInst); + + // User was stopped at pc, e.g. the instruction at pc was not + // executed. + MachInst inst = read(pc); + StaticInstPtr si(inst); + if (si->hasBranchTarget(pc, context, bpc)) { + // Don't bother setting a breakpoint on the taken branch if it + // is the same as the next pc + if (bpc != npc) + set_bt = true; + } + + DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n", + takenBkpt.address, notTakenBkpt.address); + + setTempBreakpoint(notTakenBkpt, npc); + + if (set_bt) + setTempBreakpoint(takenBkpt, bpc); +} + +// Write bytes to kernel address space for debugger. +bool +RemoteGDB::write(Addr vaddr, size_t size, const char *data) +{ + if (BaseRemoteGDB::write(vaddr, size, data)) { +#ifdef IMB + alpha_pal_imb(); +#endif + return true; + } else { + return false; + } +} + + +PCEventQueue *RemoteGDB::getPcEventQueue() +{ + return &system->pcEventQueue; +} + + +RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc) + : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc), + gdb(_gdb), refcount(0) +{ + DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc); +} + +void +RemoteGDB::HardBreakpoint::process(ThreadContext *tc) +{ + DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc()); + + if (tc == gdb->context) + gdb->trap(ALPHA_KENTRY_INT); +} + +bool +RemoteGDB::insertSoftBreak(Addr addr, size_t len) +{ + if (len != sizeof(MachInst)) + panic("invalid length\n"); + + return insertHardBreak(addr, len); +} + +bool +RemoteGDB::removeSoftBreak(Addr addr, size_t len) +{ + if (len != sizeof(MachInst)) + panic("invalid length\n"); + + return removeHardBreak(addr, len); +} + +bool +RemoteGDB::insertHardBreak(Addr addr, size_t len) +{ + if (len != sizeof(MachInst)) + panic("invalid length\n"); + + DPRINTF(GDBMisc, "inserting hardware breakpoint at %#x\n", addr); + + HardBreakpoint *&bkpt = hardBreakMap[addr]; + if (bkpt == 0) + bkpt = new HardBreakpoint(this, addr); + + bkpt->refcount++; + + return true; +} + +bool +RemoteGDB::removeHardBreak(Addr addr, size_t len) +{ + if (len != sizeof(MachInst)) + panic("invalid length\n"); + + DPRINTF(GDBMisc, "removing hardware breakpoint at %#x\n", addr); + + break_iter_t i = hardBreakMap.find(addr); + if (i == hardBreakMap.end()) + return false; + + HardBreakpoint *hbp = (*i).second; + if (--hbp->refcount == 0) { + delete hbp; + hardBreakMap.erase(i); + } + + return true; +} diff --git a/src/arch/sparc/remote_gdb.hh b/src/arch/sparc/remote_gdb.hh new file mode 100644 index 000000000..6ac4f296f --- /dev/null +++ b/src/arch/sparc/remote_gdb.hh @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2002-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: Nathan Binkert + */ + +#ifndef __ARCH_ALPHA_REMOTE_GDB_HH__ +#define __ARCH_ALPHA_REMOTE_GDB_HH__ + +#include + +#include "arch/types.hh" +#include "base/remote_gdb.hh" +#include "cpu/pc_event.hh" +#include "base/pollevent.hh" + +class System; +class ThreadContext; +class PhysicalMemory; + +namespace SparcISA +{ + class RemoteGDB : public BaseRemoteGDB + { + private: + friend void debugger(); + friend class GDBListener; + + protected: + class Event : public PollEvent + { + protected: + RemoteGDB *gdb; + + public: + Event(RemoteGDB *g, int fd, int e); + void process(int revent); + }; + + friend class Event; + Event *event; + + protected: + // Machine memory + bool write(Addr addr, size_t size, const char *data); + + public: + RemoteGDB(System *system, ThreadContext *context); + ~RemoteGDB(); + + bool acc(Addr addr, size_t len); + int signal(int type); + + protected: + void getregs(); + void setregs(); + + void clearSingleStep(); + void setSingleStep(); + + PCEventQueue *getPcEventQueue(); + + protected: + class HardBreakpoint : public PCEvent + { + private: + RemoteGDB *gdb; + + public: + int refcount; + + public: + HardBreakpoint(RemoteGDB *_gdb, Addr addr); + std::string name() { return gdb->name() + ".hwbkpt"; } + + virtual void process(ThreadContext *tc); + }; + friend class HardBreakpoint; + + typedef std::map break_map_t; + typedef break_map_t::iterator break_iter_t; + break_map_t hardBreakMap; + + bool insertSoftBreak(Addr addr, size_t len); + bool removeSoftBreak(Addr addr, size_t len); + bool insertHardBreak(Addr addr, size_t len); + bool removeHardBreak(Addr addr, size_t len); + + protected: + struct TempBreakpoint { + Addr address; // set here + MachInst bkpt_inst; // saved instruction at bkpt + int init_count; // number of times to skip bkpt + int count; // current count + }; + + TempBreakpoint notTakenBkpt; + TempBreakpoint takenBkpt; + + void clearTempBreakpoint(TempBreakpoint &bkpt); + void setTempBreakpoint(TempBreakpoint &bkpt, Addr addr); + }; +} + +#endif /* __ARCH_ALPHA_REMOTE_GDB_H__ */ diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index e4efa31e3..01166d46f 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -123,7 +123,6 @@ #include "arch/vtophys.hh" #include "base/intmath.hh" -#include "base/kgdb.h" #include "base/remote_gdb.hh" #include "base/socket.hh" #include "base/trace.hh" @@ -138,18 +137,18 @@ using namespace std; using namespace TheISA; #ifndef NDEBUG -vector debuggers; -int current_debugger = -1; +vector debuggers; void debugger() { + static int current_debugger = -1; if (current_debugger >= 0 && current_debugger < debuggers.size()) { - RemoteGDB *gdb = debuggers[current_debugger]; + BaseRemoteGDB *gdb = debuggers[current_debugger]; if (!gdb->isattached()) gdb->listener->accept(); if (gdb->isattached()) - gdb->trap(ALPHA_KENTRY_IF); + gdb->trap(SIGILL); } } #endif @@ -169,7 +168,7 @@ GDBListener::Event::process(int revent) listener->accept(); } -GDBListener::GDBListener(RemoteGDB *g, int p) +GDBListener::GDBListener(BaseRemoteGDB *g, int p) : event(NULL), gdb(g), port(p) { assert(!gdb->listener); @@ -229,55 +228,46 @@ GDBListener::accept() } } -/////////////////////////////////////////////////////////// -// -// -// -int digit2i(char); -char i2digit(int); -void mem2hex(void *, const void *, int); -const char *hex2mem(void *, const char *, int); -Addr hex2i(const char **); - -RemoteGDB::Event::Event(RemoteGDB *g, int fd, int e) +BaseRemoteGDB::Event::Event(BaseRemoteGDB *g, int fd, int e) : PollEvent(fd, e), gdb(g) {} void -RemoteGDB::Event::process(int revent) +BaseRemoteGDB::Event::process(int revent) { if (revent & POLLIN) - gdb->trap(ALPHA_KENTRY_IF); + gdb->trap(SIGILL); else if (revent & POLLNVAL) gdb->detach(); } -RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) +BaseRemoteGDB::BaseRemoteGDB(System *_system, ThreadContext *c, size_t cacheSize) : event(NULL), listener(NULL), number(-1), fd(-1), active(false), attached(false), - system(_system), pmem(_system->physmem), context(c) + system(_system), pmem(_system->physmem), context(c), + gdbregs(cacheSize) { - memset(gdbregs, 0, sizeof(gdbregs)); + memset(gdbregs.regs, 0, gdbregs.size); } -RemoteGDB::~RemoteGDB() +BaseRemoteGDB::~BaseRemoteGDB() { if (event) delete event; } string -RemoteGDB::name() +BaseRemoteGDB::name() { return system->name() + ".remote_gdb"; } bool -RemoteGDB::isattached() +BaseRemoteGDB::isattached() { return attached; } void -RemoteGDB::attach(int f) +BaseRemoteGDB::attach(int f) { fd = f; @@ -289,7 +279,7 @@ RemoteGDB::attach(int f) } void -RemoteGDB::detach() +BaseRemoteGDB::detach() { attached = false; close(fd); @@ -300,250 +290,50 @@ RemoteGDB::detach() } const char * -gdb_command(char cmd) +BaseRemoteGDB::gdb_command(char cmd) { switch (cmd) { - case KGDB_SIGNAL: return "KGDB_SIGNAL"; - case KGDB_SET_BAUD: return "KGDB_SET_BAUD"; - case KGDB_SET_BREAK: return "KGDB_SET_BREAK"; - case KGDB_CONT: return "KGDB_CONT"; - case KGDB_ASYNC_CONT: return "KGDB_ASYNC_CONT"; - case KGDB_DEBUG: return "KGDB_DEBUG"; - case KGDB_DETACH: return "KGDB_DETACH"; - case KGDB_REG_R: return "KGDB_REG_R"; - case KGDB_REG_W: return "KGDB_REG_W"; - case KGDB_SET_THREAD: return "KGDB_SET_THREAD"; - case KGDB_CYCLE_STEP: return "KGDB_CYCLE_STEP"; - case KGDB_SIG_CYCLE_STEP: return "KGDB_SIG_CYCLE_STEP"; - case KGDB_KILL: return "KGDB_KILL"; - case KGDB_MEM_W: return "KGDB_MEM_W"; - case KGDB_MEM_R: return "KGDB_MEM_R"; - case KGDB_SET_REG: return "KGDB_SET_REG"; - case KGDB_READ_REG: return "KGDB_READ_REG"; - case KGDB_QUERY_VAR: return "KGDB_QUERY_VAR"; - case KGDB_SET_VAR: return "KGDB_SET_VAR"; - case KGDB_RESET: return "KGDB_RESET"; - case KGDB_STEP: return "KGDB_STEP"; - case KGDB_ASYNC_STEP: return "KGDB_ASYNC_STEP"; - case KGDB_THREAD_ALIVE: return "KGDB_THREAD_ALIVE"; - case KGDB_TARGET_EXIT: return "KGDB_TARGET_EXIT"; - case KGDB_BINARY_DLOAD: return "KGDB_BINARY_DLOAD"; - case KGDB_CLR_HW_BKPT: return "KGDB_CLR_HW_BKPT"; - case KGDB_SET_HW_BKPT: return "KGDB_SET_HW_BKPT"; - case KGDB_START: return "KGDB_START"; - case KGDB_END: return "KGDB_END"; - case KGDB_GOODP: return "KGDB_GOODP"; - case KGDB_BADP: return "KGDB_BADP"; + case GDBSignal: return "KGDB_SIGNAL"; + case GDBSetBaud: return "KGDB_SET_BAUD"; + case GDBSetBreak: return "KGDB_SET_BREAK"; + case GDBCont: return "KGDB_CONT"; + case GDBAsyncCont: return "KGDB_ASYNC_CONT"; + case GDBDebug: return "KGDB_DEBUG"; + case GDBDetach: return "KGDB_DETACH"; + case GDBRegR: return "KGDB_REG_R"; + case GDBRegW: return "KGDB_REG_W"; + case GDBSetThread: return "KGDB_SET_THREAD"; + case GDBCycleStep: return "KGDB_CYCLE_STEP"; + case GDBSigCycleStep: return "KGDB_SIG_CYCLE_STEP"; + case GDBKill: return "KGDB_KILL"; + case GDBMemW: return "KGDB_MEM_W"; + case GDBMemR: return "KGDB_MEM_R"; + case GDBSetReg: return "KGDB_SET_REG"; + case GDBReadReg: return "KGDB_READ_REG"; + case GDBQueryVar: return "KGDB_QUERY_VAR"; + case GDBSetVar: return "KGDB_SET_VAR"; + case GDBReset: return "KGDB_RESET"; + case GDBStep: return "KGDB_STEP"; + case GDBAsyncStep: return "KGDB_ASYNC_STEP"; + case GDBThreadAlive: return "KGDB_THREAD_ALIVE"; + case GDBTargetExit: return "KGDB_TARGET_EXIT"; + case GDBBinaryDload: return "KGDB_BINARY_DLOAD"; + case GDBClrHwBkpt: return "KGDB_CLR_HW_BKPT"; + case GDBSetHwBkpt: return "KGDB_SET_HW_BKPT"; + case GDBStart: return "KGDB_START"; + case GDBEnd: return "KGDB_END"; + case GDBGoodP: return "KGDB_GOODP"; + case GDBBadP: return "KGDB_BADP"; default: return "KGDB_UNKNOWN"; } } -/////////////////////////////////////////////////////////// -// RemoteGDB::acc -// -// Determine if the mapping at va..(va+len) is valid. -// -bool -RemoteGDB::acc(Addr va, size_t len) -{ - Addr last_va; - - va = TheISA::TruncPage(va); - last_va = TheISA::RoundPage(va + len); - - do { - if (TheISA::IsK0Seg(va)) { - if (va < (TheISA::K0SegBase + pmem->size())) { - DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= " - "%#x < K0SEG + size\n", va); - return true; - } else { - DPRINTF(GDBAcc, "acc: Mapping invalid %#x > K0SEG + size\n", - va); - return false; - } - } - - /** - * This code says that all accesses to palcode (instruction and data) - * are valid since there isn't a va->pa mapping because palcode is - * accessed physically. At some point this should probably be cleaned up - * but there is no easy way to do it. - */ - - if (AlphaISA::PcPAL(va) || va < 0x10000) - return true; - - Addr ptbr = context->readMiscReg(AlphaISA::IPR_PALtemp20); - TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va); - if (!pte.valid()) { - DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); - return false; - } - va += TheISA::PageBytes; - } while (va < last_va); - - DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va); - return true; -} - -/////////////////////////////////////////////////////////// -// RemoteGDB::signal -// -// Translate a trap number into a Unix-compatible signal number. -// (GDB only understands Unix signal numbers.) -// -int -RemoteGDB::signal(int type) -{ - switch (type) { - case ALPHA_KENTRY_INT: - return (SIGTRAP); - - case ALPHA_KENTRY_UNA: - return (SIGBUS); - - case ALPHA_KENTRY_ARITH: - return (SIGFPE); - - case ALPHA_KENTRY_IF: - return (SIGILL); - - case ALPHA_KENTRY_MM: - return (SIGSEGV); - - default: - panic("unknown signal type"); - return 0; - } -} - -/////////////////////////////////////////////////////////// -// RemoteGDB::getregs -// -// Translate the kernel debugger register format into -// the GDB register format. -void -RemoteGDB::getregs() -{ - memset(gdbregs, 0, sizeof(gdbregs)); - - gdbregs[KGDB_REG_PC] = context->readPC(); - - // @todo: Currently this is very Alpha specific. - if (AlphaISA::PcPAL(gdbregs[KGDB_REG_PC])) { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { - gdbregs[i] = context->readIntReg(AlphaISA::reg_redir[i]); - } - } else { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { - gdbregs[i] = context->readIntReg(i); - } - } - -#ifdef KGDB_FP_REGS - for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { - gdbregs[i + KGDB_REG_F0] = context->readFloatRegBits(i); - } -#endif -} - -/////////////////////////////////////////////////////////// -// RemoteGDB::setregs -// -// Translate the GDB register format into the kernel -// debugger register format. -// -void -RemoteGDB::setregs() -{ - // @todo: Currently this is very Alpha specific. - if (AlphaISA::PcPAL(gdbregs[KGDB_REG_PC])) { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { - context->setIntReg(AlphaISA::reg_redir[i], gdbregs[i]); - } - } else { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { - context->setIntReg(i, gdbregs[i]); - } - } - -#ifdef KGDB_FP_REGS - for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { - context->setFloatRegBits(i, gdbregs[i + KGDB_REG_F0]); - } -#endif - context->setPC(gdbregs[KGDB_REG_PC]); -} - -void -RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr) -{ - DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", addr); - - bkpt.address = addr; - insertHardBreak(addr, 4); -} - -void -RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt) -{ - DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", - bkpt.address); - - - removeHardBreak(bkpt.address, 4); - bkpt.address = 0; -} - -void -RemoteGDB::clearSingleStep() -{ - DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n", - takenBkpt.address, notTakenBkpt.address); - - if (takenBkpt.address != 0) - clearTempBreakpoint(takenBkpt); - - if (notTakenBkpt.address != 0) - clearTempBreakpoint(notTakenBkpt); -} - -void -RemoteGDB::setSingleStep() -{ - Addr pc = context->readPC(); - Addr npc, bpc; - bool set_bt = false; - - npc = pc + sizeof(MachInst); - - // User was stopped at pc, e.g. the instruction at pc was not - // executed. - MachInst inst = read(pc); - StaticInstPtr si(inst); - if (si->hasBranchTarget(pc, context, bpc)) { - // Don't bother setting a breakpoint on the taken branch if it - // is the same as the next pc - if (bpc != npc) - set_bt = true; - } - - DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n", - takenBkpt.address, notTakenBkpt.address); - - setTempBreakpoint(notTakenBkpt, npc); - - if (set_bt) - setTempBreakpoint(takenBkpt, bpc); -} - ///////////////////////// // // uint8_t -RemoteGDB::getbyte() +BaseRemoteGDB::getbyte() { uint8_t b; ::read(fd, &b, 1); @@ -551,14 +341,14 @@ RemoteGDB::getbyte() } void -RemoteGDB::putbyte(uint8_t b) +BaseRemoteGDB::putbyte(uint8_t b) { ::write(fd, &b, 1); } // Send a packet to gdb void -RemoteGDB::send(const char *bp) +BaseRemoteGDB::send(const char *bp) { const char *p; uint8_t csum, c; @@ -567,20 +357,26 @@ RemoteGDB::send(const char *bp) do { p = bp; - putbyte(KGDB_START); + //Start sending a packet + putbyte(GDBStart); + //Send the contents, and also keep a check sum. for (csum = 0; (c = *p); p++) { putbyte(c); csum += c; } - putbyte(KGDB_END); + //Send the ending character. + putbyte(GDBEnd); + //Sent the checksum. putbyte(i2digit(csum >> 4)); putbyte(i2digit(csum)); - } while ((c = getbyte() & 0x7f) == KGDB_BADP); + //Try transmitting over and over again until the other end doesn't send an + //error back. + } while ((c = getbyte() & 0x7f) == GDBBadP); } // Receive a packet from gdb int -RemoteGDB::recv(char *bp, int maxlen) +BaseRemoteGDB::recv(char *bp, int maxlen) { char *p; int c, csum; @@ -589,28 +385,37 @@ RemoteGDB::recv(char *bp, int maxlen) do { p = bp; csum = len = 0; - while ((c = getbyte()) != KGDB_START) + //Find the beginning of a packet + while ((c = getbyte()) != GDBStart) ; - while ((c = getbyte()) != KGDB_END && len < maxlen) { + //Read until you find the end of the data in the packet, and keep + //track of the check sum. + while ((c = getbyte()) != GDBEnd && len < maxlen) { c &= 0x7f; csum += c; *p++ = c; len++; } + + //Mask the check sum, and terminate the command string. csum &= 0xff; *p = '\0'; + //If the command was too long, report an error. if (len >= maxlen) { - putbyte(KGDB_BADP); + putbyte(GDBBadP); continue; } + //Bring in the checksum. If the check sum matches, csum will be 0. csum -= digit2i(getbyte()) * 16; csum -= digit2i(getbyte()); + //If the check sum was correct if (csum == 0) { - putbyte(KGDB_GOODP); + //Report that the packet was received correctly + putbyte(GDBGoodP); // Sequence present? if (bp[2] == ':') { putbyte(bp[0]); @@ -620,7 +425,8 @@ RemoteGDB::recv(char *bp, int maxlen) } break; } - putbyte(KGDB_BADP); + //Otherwise, report that there was a mistake. + putbyte(GDBBadP); } while (1); DPRINTF(GDBRecv, "recv: %s: %s\n", gdb_command(*bp), bp); @@ -630,7 +436,7 @@ RemoteGDB::recv(char *bp, int maxlen) // Read bytes from kernel address space for debugger. bool -RemoteGDB::read(Addr vaddr, size_t size, char *data) +BaseRemoteGDB::read(Addr vaddr, size_t size, char *data) { static Addr lastaddr = 0; static size_t lastsize = 0; @@ -662,7 +468,7 @@ RemoteGDB::read(Addr vaddr, size_t size, char *data) // Write bytes to kernel address space for debugger. bool -RemoteGDB::write(Addr vaddr, size_t size, const char *data) +BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data) { static Addr lastaddr = 0; static size_t lastsize = 0; @@ -685,21 +491,15 @@ RemoteGDB::write(Addr vaddr, size_t size, const char *data) vp->writeBlob(vaddr, (uint8_t*)data, size); context->delVirtPort(vp); -#ifdef IMB - alpha_pal_imb(); -#endif - return true; } - -PCEventQueue *RemoteGDB::getPcEventQueue() +PCEventQueue *BaseRemoteGDB::getPcEventQueue() { return &system->pcEventQueue; } - -RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc) +BaseRemoteGDB::HardBreakpoint::HardBreakpoint(BaseRemoteGDB *_gdb, Addr pc) : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc), gdb(_gdb), refcount(0) { @@ -707,25 +507,25 @@ RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc) } void -RemoteGDB::HardBreakpoint::process(ThreadContext *tc) +BaseRemoteGDB::HardBreakpoint::process(ThreadContext *tc) { DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc()); if (tc == gdb->context) - gdb->trap(ALPHA_KENTRY_INT); + gdb->trap(SIGTRAP); } bool -RemoteGDB::insertSoftBreak(Addr addr, size_t len) +BaseRemoteGDB::insertSoftBreak(Addr addr, size_t len) { - if (len != sizeof(MachInst)) + if (len != sizeof(TheISA::MachInst)) panic("invalid length\n"); return insertHardBreak(addr, len); } bool -RemoteGDB::removeSoftBreak(Addr addr, size_t len) +BaseRemoteGDB::removeSoftBreak(Addr addr, size_t len) { if (len != sizeof(MachInst)) panic("invalid length\n"); @@ -734,7 +534,7 @@ RemoteGDB::removeSoftBreak(Addr addr, size_t len) } bool -RemoteGDB::insertHardBreak(Addr addr, size_t len) +BaseRemoteGDB::insertHardBreak(Addr addr, size_t len) { if (len != sizeof(MachInst)) panic("invalid length\n"); @@ -751,7 +551,7 @@ RemoteGDB::insertHardBreak(Addr addr, size_t len) } bool -RemoteGDB::removeHardBreak(Addr addr, size_t len) +BaseRemoteGDB::removeHardBreak(Addr addr, size_t len) { if (len != sizeof(MachInst)) panic("invalid length\n"); @@ -772,7 +572,7 @@ RemoteGDB::removeHardBreak(Addr addr, size_t len) } const char * -break_type(char c) +BaseRemoteGDB::break_type(char c) { switch(c) { case '0': return "software breakpoint"; @@ -790,12 +590,12 @@ break_type(char c) // makes sense to use POSIX errno values, because that is what the // gdb/remote.c functions want to return. bool -RemoteGDB::trap(int type) +BaseRemoteGDB::trap(int type) { uint64_t val; size_t datalen, len; - char data[KGDB_BUFLEN + 1]; - char buffer[sizeof(gdbregs) * 2 + 256]; + char data[GDBPacketBufLen + 1]; + char buffer[gdbregs.size * 2 + 256]; const char *p; char command, subcmd; string var; @@ -823,7 +623,7 @@ RemoteGDB::trap(int type) active = true; else // Tell remote host that an exception has occurred. - snprintf((char *)buffer, sizeof(buffer), "S%02x", signal(type)); + snprintf((char *)buffer, sizeof(buffer), "S%02x", type); send(buffer); // Stick frame regs into our reg cache. @@ -837,24 +637,25 @@ RemoteGDB::trap(int type) p = data + 1; switch (command) { - case KGDB_SIGNAL: + case GDBSignal: // if this command came from a running gdb, answer it -- // the other guy has no way of knowing if we're in or out // of this loop when he issues a "remote-signal". - snprintf((char *)buffer, sizeof(buffer), "S%02x", signal(type)); + snprintf((char *)buffer, sizeof(buffer), + "S%02x", type); send(buffer); continue; - case KGDB_REG_R: - if (2 * sizeof(gdbregs) > sizeof(buffer)) + case GDBRegR: + if (2 * gdbregs.size > sizeof(buffer)) panic("buffer too small"); - mem2hex(buffer, gdbregs, sizeof(gdbregs)); + mem2hex(buffer, gdbregs.regs, gdbregs.size); send(buffer); continue; - case KGDB_REG_W: - p = hex2mem(gdbregs, p, sizeof(gdbregs)); + case GDBRegW: + p = hex2mem(gdbregs.regs, p, gdbregs.size); if (p == NULL || *p != '\0') send("E01"); else { @@ -864,7 +665,7 @@ RemoteGDB::trap(int type) continue; #if 0 - case KGDB_SET_REG: + case GDBSetReg: val = hex2i(&p); if (*p++ != '=') { send("E01"); @@ -875,14 +676,14 @@ RemoteGDB::trap(int type) continue; } - gdbregs[val] = hex2i(&p); + gdbregs.regs[val] = hex2i(&p); setregs(); send("OK"); continue; #endif - case KGDB_MEM_R: + case GDBMemR: val = hex2i(&p); if (*p++ != ',') { send("E02"); @@ -914,7 +715,7 @@ RemoteGDB::trap(int type) } continue; - case KGDB_MEM_W: + case GDBMemW: val = hex2i(&p); if (*p++ != ',') { send("E06"); @@ -944,7 +745,7 @@ RemoteGDB::trap(int type) send("E0B"); continue; - case KGDB_SET_THREAD: + case GDBSetThread: subcmd = *p++; val = hex2i(&p); if (val == 0) @@ -953,14 +754,14 @@ RemoteGDB::trap(int type) send("E01"); continue; - case KGDB_DETACH: - case KGDB_KILL: + case GDBDetach: + case GDBKill: active = false; clearSingleStep(); detach(); goto out; - case KGDB_ASYNC_CONT: + case GDBAsyncCont: subcmd = hex2i(&p); if (*p++ == ';') { val = hex2i(&p); @@ -970,7 +771,7 @@ RemoteGDB::trap(int type) clearSingleStep(); goto out; - case KGDB_CONT: + case GDBCont: if (p - data < datalen) { val = hex2i(&p); context->setPC(val); @@ -979,7 +780,7 @@ RemoteGDB::trap(int type) clearSingleStep(); goto out; - case KGDB_ASYNC_STEP: + case GDBAsyncStep: subcmd = hex2i(&p); if (*p++ == ';') { val = hex2i(&p); @@ -989,7 +790,7 @@ RemoteGDB::trap(int type) setSingleStep(); goto out; - case KGDB_STEP: + case GDBStep: if (p - data < datalen) { val = hex2i(&p); context->setPC(val); @@ -998,7 +799,7 @@ RemoteGDB::trap(int type) setSingleStep(); goto out; - case KGDB_CLR_HW_BKPT: + case GDBClrHwBkpt: subcmd = *p++; if (*p++ != ',') send("E0D"); val = hex2i(&p); @@ -1030,7 +831,7 @@ RemoteGDB::trap(int type) send(ret ? "OK" : "E0C"); continue; - case KGDB_SET_HW_BKPT: + case GDBSetHwBkpt: subcmd = *p++; if (*p++ != ',') send("E0D"); val = hex2i(&p); @@ -1062,7 +863,7 @@ RemoteGDB::trap(int type) send(ret ? "OK" : "E0C"); continue; - case KGDB_QUERY_VAR: + case GDBQueryVar: var = string(p, datalen - 1); if (var == "C") send("QC0"); @@ -1070,17 +871,17 @@ RemoteGDB::trap(int type) send(""); continue; - case KGDB_SET_BAUD: - case KGDB_SET_BREAK: - case KGDB_DEBUG: - case KGDB_CYCLE_STEP: - case KGDB_SIG_CYCLE_STEP: - case KGDB_READ_REG: - case KGDB_SET_VAR: - case KGDB_RESET: - case KGDB_THREAD_ALIVE: - case KGDB_TARGET_EXIT: - case KGDB_BINARY_DLOAD: + case GDBSetBaud: + case GDBSetBreak: + case GDBDebug: + case GDBCycleStep: + case GDBSigCycleStep: + case GDBReadReg: + case GDBSetVar: + case GDBReset: + case GDBThreadAlive: + case GDBTargetExit: + case GDBBinaryDload: // Unsupported command DPRINTF(GDBMisc, "Unsupported command: %s\n", gdb_command(command)); @@ -1106,7 +907,7 @@ RemoteGDB::trap(int type) // Convert a hex digit into an integer. // This returns -1 if the argument passed is no valid hex digit. int -digit2i(char c) +BaseRemoteGDB::digit2i(char c) { if (c >= '0' && c <= '9') return (c - '0'); @@ -1121,14 +922,14 @@ digit2i(char c) // Convert the low 4 bits of an integer into an hex digit. char -i2digit(int n) +BaseRemoteGDB::i2digit(int n) { return ("0123456789abcdef"[n & 0x0f]); } // Convert a byte array into an hex string. void -mem2hex(void *vdst, const void *vsrc, int len) +BaseRemoteGDB::mem2hex(void *vdst, const void *vsrc, int len) { char *dst = (char *)vdst; const char *src = (const char *)vsrc; @@ -1145,7 +946,7 @@ mem2hex(void *vdst, const void *vsrc, int len) // hex digit. If the string ends in the middle of a byte, NULL is // returned. const char * -hex2mem(void *vdst, const char *src, int maxlen) +BaseRemoteGDB::hex2mem(void *vdst, const char *src, int maxlen) { char *dst = (char *)vdst; int msb, lsb; @@ -1166,7 +967,7 @@ hex2mem(void *vdst, const char *src, int maxlen) // This returns a pointer to the character following the last valid // hex digit. Addr -hex2i(const char **srcp) +BaseRemoteGDB::hex2i(const char **srcp) { const char *src = *srcp; Addr r = 0; diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh index 8c3ce7572..65e4313eb 100644 --- a/src/base/remote_gdb.hh +++ b/src/base/remote_gdb.hh @@ -34,7 +34,6 @@ #include #include "arch/types.hh" -#include "base/kgdb.h" #include "cpu/pc_event.hh" #include "base/pollevent.hh" #include "base/socket.hh" @@ -44,22 +43,72 @@ class ThreadContext; class PhysicalMemory; class GDBListener; -class RemoteGDB + +enum GDBCommands +{ + GDBSignal = '?', // last signal + GDBSetBaud = 'b', // set baud (depracated) + GDBSetBreak = 'B', // set breakpoint (depracated) + GDBCont = 'c', // resume + GDBAsyncCont = 'C', // continue with signal + GDBDebug = 'd', // toggle debug flags (deprecated) + GDBDetach = 'D', // detach remote gdb + GDBRegR = 'g', // read general registers + GDBRegW = 'G', // write general registers + GDBSetThread = 'H', // set thread + GDBCycleStep = 'i', // step a single cycle + GDBSigCycleStep = 'I', // signal then cycle step + GDBKill = 'k', // kill program + GDBMemR = 'm', // read memory + GDBMemW = 'M', // write memory + GDBReadReg = 'p', // read register + GDBSetReg = 'P', // write register + GDBQueryVar = 'q', // query variable + GDBSetVar = 'Q', // set variable + GDBReset = 'r', // reset system. (Deprecated) + GDBStep = 's', // step + GDBAsyncStep = 'S', // signal and step + GDBThreadAlive = 'T', // find out if the thread is alive + GDBTargetExit = 'W', // target exited + GDBBinaryDload = 'X', // write memory + GDBClrHwBkpt = 'z', // remove breakpoint or watchpoint + GDBSetHwBkpt = 'Z' // insert breakpoint or watchpoint +}; + +const char GDBStart = '$'; +const char GDBEnd = '#'; +const char GDBGoodP = '+'; +const char GDBBadP = '-'; + +const int GDBPacketBufLen = 1024; + +class BaseRemoteGDB { - protected: - typedef TheISA::MachInst MachInst; private: friend void debugger(); friend class GDBListener; + //Helper functions + protected: + int digit2i(char); + char i2digit(int); + Addr hex2i(const char **); + //Address formats, break types, and gdb commands may change + //between architectures, so they're defined as virtual + //functions. + virtual void mem2hex(void *, const void *, int); + virtual const char * hex2mem(void *, const char *, int); + virtual const char * break_type(char c); + virtual const char * gdb_command(char cmd); + protected: class Event : public PollEvent { protected: - RemoteGDB *gdb; + BaseRemoteGDB *gdb; public: - Event(RemoteGDB *g, int fd, int e); + Event(BaseRemoteGDB *g, int fd, int e); void process(int revent); }; @@ -69,8 +118,8 @@ class RemoteGDB int number; protected: + //The socket commands come in through int fd; - uint64_t gdbregs[KGDB_NUMREGS]; protected: #ifdef notyet @@ -83,6 +132,23 @@ class RemoteGDB PhysicalMemory *pmem; ThreadContext *context; + protected: + class GdbRegCache + { + public: + GdbRegCache(size_t newSize) : regs(new uint64_t[newSize]), size(newSize) + {} + ~GdbRegCache() + { + delete [] regs; + } + + uint64_t * regs; + size_t size; + }; + + GdbRegCache gdbregs; + protected: uint8_t getbyte(); void putbyte(uint8_t b); @@ -92,15 +158,15 @@ class RemoteGDB protected: // Machine memory - bool read(Addr addr, size_t size, char *data); - bool write(Addr addr, size_t size, const char *data); + virtual bool read(Addr addr, size_t size, char *data); + virtual bool write(Addr addr, size_t size, const char *data); template T read(Addr addr); template void write(Addr addr, T data); public: - RemoteGDB(System *system, ThreadContext *context); - ~RemoteGDB(); + BaseRemoteGDB(System *system, ThreadContext *context, size_t cacheSize); + virtual ~BaseRemoteGDB(); void replaceThreadContext(ThreadContext *tc) { context = tc; } @@ -108,16 +174,15 @@ class RemoteGDB void detach(); bool isattached(); - bool acc(Addr addr, size_t len); - static int signal(int type); + virtual bool acc(Addr addr, size_t len) = 0; bool trap(int type); protected: - void getregs(); - void setregs(); + virtual void getregs() = 0; + virtual void setregs() = 0; - void clearSingleStep(); - void setSingleStep(); + virtual void clearSingleStep() = 0; + virtual void setSingleStep() = 0; PCEventQueue *getPcEventQueue(); @@ -125,13 +190,13 @@ class RemoteGDB class HardBreakpoint : public PCEvent { private: - RemoteGDB *gdb; + BaseRemoteGDB *gdb; public: int refcount; public: - HardBreakpoint(RemoteGDB *_gdb, Addr addr); + HardBreakpoint(BaseRemoteGDB *_gdb, Addr addr); std::string name() { return gdb->name() + ".hwbkpt"; } virtual void process(ThreadContext *tc); @@ -147,27 +212,13 @@ class RemoteGDB bool insertHardBreak(Addr addr, size_t len); bool removeHardBreak(Addr addr, size_t len); - protected: - struct TempBreakpoint { - Addr address; // set here - MachInst bkpt_inst; // saved instruction at bkpt - int init_count; // number of times to skip bkpt - int count; // current count - }; - - TempBreakpoint notTakenBkpt; - TempBreakpoint takenBkpt; - - void clearTempBreakpoint(TempBreakpoint &bkpt); - void setTempBreakpoint(TempBreakpoint &bkpt, Addr addr); - public: std::string name(); }; template inline T -RemoteGDB::read(Addr addr) +BaseRemoteGDB::read(Addr addr) { T temp; read(addr, sizeof(T), (char *)&temp); @@ -176,7 +227,7 @@ RemoteGDB::read(Addr addr) template inline void -RemoteGDB::write(Addr addr, T data) +BaseRemoteGDB::write(Addr addr, T data) { write(addr, sizeof(T), (const char *)&data); } class GDBListener @@ -197,11 +248,11 @@ class GDBListener protected: ListenSocket listener; - RemoteGDB *gdb; + BaseRemoteGDB *gdb; int port; public: - GDBListener(RemoteGDB *g, int p); + GDBListener(BaseRemoteGDB *g, int p); ~GDBListener(); void accept(); diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 4c39341aa..5ef6e27ea 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -45,7 +45,6 @@ #if FULL_SYSTEM #include "arch/tlb.hh" #include "arch/vtophys.hh" -#include "base/remote_gdb.hh" #include "sim/system.hh" #endif // FULL_SYSTEM diff --git a/src/sim/system.cc b/src/sim/system.cc index 11ae492b9..4b42d41fc 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -43,7 +43,7 @@ #include "sim/system.hh" #if FULL_SYSTEM #include "arch/vtophys.hh" -#include "base/remote_gdb.hh" +#include "arch/remote_gdb.hh" #include "kern/kernel_stats.hh" #endif diff --git a/src/sim/system.hh b/src/sim/system.hh index 827fe5c78..b3a67bf7a 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -56,7 +56,10 @@ class PhysicalMemory; #if FULL_SYSTEM class Platform; class GDBListener; -class RemoteGDB; +namespace TheISA +{ + class RemoteGDB; +} #endif class System : public SimObject @@ -157,7 +160,7 @@ class System : public SimObject #endif public: #if FULL_SYSTEM - std::vector remoteGDB; + std::vector remoteGDB; std::vector gdbListen; virtual bool breakpoint() = 0; #endif // FULL_SYSTEM -- cgit v1.2.3 From ef1a92eb9b372ffadb7985941797ba37b61beac5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 6 Nov 2006 18:30:28 -0500 Subject: Stub for SPARC interrupt handling object. --HG-- extra : convert_revision : 7257e3387c01e84e5a1018a9cdcc09a79edfa934 --- src/arch/sparc/interrupts.hh | 92 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/arch/sparc/interrupts.hh (limited to 'src') diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh new file mode 100644 index 000000000..0072f4184 --- /dev/null +++ b/src/arch/sparc/interrupts.hh @@ -0,0 +1,92 @@ +/* + * Copyright (c) 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: Gabe Black + */ + +#ifndef __ARCH_SPARC_INTERRUPT_HH__ +#define __ARCH_SPARC_INTERRUPT_HH__ + +#include "arch/sparc/faults.hh" + +namespace SparcISA +{ + class Interrupts + { + protected: + Fault interrupts[NumInterruptLevels]; + bool requested[NumInterruptLevels]; + + public: + Interrupts() + { + for(int x = 0; x < NumInterruptLevels; x++) + { + interrupts[x] = new InterruptLevelN(x); + requested[x] = false; + } + } + void post(int int_num, int index) + { + if(int_num < 0 || int_num >= NumInterruptLevels) + panic("int_num out of bounds\n"); + + requested[int_num] = true; + } + + void clear(int int_num, int index) + { + requested[int_num] = false; + } + + void clear_all() + { + for(int x = 0; x < NumInterruptLevels; x++) + requested[x] = false; + } + + bool check_interrupts(ThreadContext * tc) const + { + return true; + } + + Fault getInterrupt(ThreadContext * tc) + { + return NoFault; + } + + void serialize(std::ostream &os) + { + } + + void unserialize(Checkpoint *cp, const std::string §ion) + { + } + }; +} + +#endif // __ARCH_SPARC_INTERRUPT_HH__ -- cgit v1.2.3 From b04a2653f941fd8174760da156b601bf8a2de2ef Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 6 Nov 2006 19:09:23 -0500 Subject: Got rid of obsolete ivlb and ivle psuedo instructions. --HG-- extra : convert_revision : c3c2dd5a6e7181ad94194146d7fa2b33b21074fb --- src/arch/alpha/isa/decoder.isa | 6 ------ src/sim/pseudo_inst.cc | 12 ------------ 2 files changed, 18 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index be6f574a9..7014d4c22 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -795,12 +795,6 @@ decode OPCODE default Unknown::unknown() { 0x04: quiesceTime({{ R0 = AlphaPseudo::quiesceTime(xc->tcBase()); }}, IsNonSpeculative, IsUnverifiable); - 0x10: ivlb({{ - AlphaPseudo::ivlb(xc->tcBase()); - }}, No_OpClass, IsNonSpeculative); - 0x11: ivle({{ - AlphaPseudo::ivle(xc->tcBase()); - }}, No_OpClass, IsNonSpeculative); 0x20: m5exit_old({{ AlphaPseudo::m5exit_old(xc->tcBase()); }}, No_OpClass, IsNonSpeculative); diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index d913e159b..548d0c167 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -133,18 +133,6 @@ namespace AlphaPseudo return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns; } - void - ivlb(ThreadContext *tc) - { - if (tc->getKernelStats()) - tc->getKernelStats()->ivlb(); - } - - void - ivle(ThreadContext *tc) - { - } - void m5exit_old(ThreadContext *tc) { -- cgit v1.2.3 From 5b152b970be305efa860b202ed1a7de8fdfe374c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 6 Nov 2006 19:10:13 -0500 Subject: Got rid of stray alpha include --HG-- extra : convert_revision : eddd64dd9291d6656821fe6387aeab2f9ddbaf58 --- src/dev/uart8250.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/dev/uart8250.cc b/src/dev/uart8250.cc index 9051a26a2..ddee33695 100644 --- a/src/dev/uart8250.cc +++ b/src/dev/uart8250.cc @@ -35,7 +35,6 @@ #include #include -#include "arch/alpha/ev5.hh" #include "base/inifile.hh" #include "base/str.hh" // for to_number #include "base/trace.hh" -- cgit v1.2.3 From dd14c86ec8afb3a98d55a58eaafd8b85dd651bd6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 6 Nov 2006 19:45:00 -0500 Subject: Moved the tsunami devices into the dev/alpha directory. Other devices "generic" devices are dependent on some of those files. That will either need to change, or most likely those devices will have to be considered architecture dependent. --HG-- rename : src/dev/tsunami.cc => src/dev/alpha/tsunami.cc rename : src/dev/tsunami.hh => src/dev/alpha/tsunami.hh rename : src/dev/tsunami_cchip.cc => src/dev/alpha/tsunami_cchip.cc rename : src/dev/tsunami_cchip.hh => src/dev/alpha/tsunami_cchip.hh rename : src/dev/tsunami_io.cc => src/dev/alpha/tsunami_io.cc rename : src/dev/tsunami_io.hh => src/dev/alpha/tsunami_io.hh rename : src/dev/tsunami_pchip.cc => src/dev/alpha/tsunami_pchip.cc rename : src/dev/tsunami_pchip.hh => src/dev/alpha/tsunami_pchip.hh rename : src/dev/tsunamireg.h => src/dev/alpha/tsunamireg.h extra : convert_revision : ffbb6fd93341d2623a6932bf096019b8976da694 --- src/dev/SConscript | 5 - src/dev/alpha/SConscript | 50 +-- src/dev/alpha/tsunami.cc | 136 ++++++++ src/dev/alpha/tsunami.hh | 139 +++++++++ src/dev/alpha/tsunami_cchip.cc | 555 +++++++++++++++++++++++++++++++++ src/dev/alpha/tsunami_cchip.hh | 152 +++++++++ src/dev/alpha/tsunami_io.cc | 688 +++++++++++++++++++++++++++++++++++++++++ src/dev/alpha/tsunami_io.hh | 361 +++++++++++++++++++++ src/dev/alpha/tsunami_pchip.cc | 369 ++++++++++++++++++++++ src/dev/alpha/tsunami_pchip.hh | 105 +++++++ src/dev/alpha/tsunamireg.h | 173 +++++++++++ src/dev/ide_disk.cc | 4 +- src/dev/isa_fake.hh | 2 +- src/dev/pcidev.cc | 2 +- src/dev/tsunami.cc | 136 -------- src/dev/tsunami.hh | 139 --------- src/dev/tsunami_cchip.cc | 555 --------------------------------- src/dev/tsunami_cchip.hh | 152 --------- src/dev/tsunami_io.cc | 688 ----------------------------------------- src/dev/tsunami_io.hh | 361 --------------------- src/dev/tsunami_pchip.cc | 369 ---------------------- src/dev/tsunami_pchip.hh | 105 ------- src/dev/tsunamireg.h | 173 ----------- src/dev/uart8250.hh | 2 +- 24 files changed, 2708 insertions(+), 2713 deletions(-) create mode 100644 src/dev/alpha/tsunami.cc create mode 100644 src/dev/alpha/tsunami.hh create mode 100644 src/dev/alpha/tsunami_cchip.cc create mode 100644 src/dev/alpha/tsunami_cchip.hh create mode 100644 src/dev/alpha/tsunami_io.cc create mode 100644 src/dev/alpha/tsunami_io.hh create mode 100644 src/dev/alpha/tsunami_pchip.cc create mode 100644 src/dev/alpha/tsunami_pchip.hh create mode 100644 src/dev/alpha/tsunamireg.h delete mode 100644 src/dev/tsunami.cc delete mode 100644 src/dev/tsunami.hh delete mode 100644 src/dev/tsunami_cchip.cc delete mode 100644 src/dev/tsunami_cchip.hh delete mode 100644 src/dev/tsunami_io.cc delete mode 100644 src/dev/tsunami_io.hh delete mode 100644 src/dev/tsunami_pchip.cc delete mode 100644 src/dev/tsunami_pchip.hh delete mode 100644 src/dev/tsunamireg.h (limited to 'src') diff --git a/src/dev/SConscript b/src/dev/SConscript index 2b8ef28f5..75fca324a 100644 --- a/src/dev/SConscript +++ b/src/dev/SConscript @@ -68,11 +68,6 @@ sources += Split(''' platform.cc simconsole.cc simple_disk.cc - tsunami.cc - tsunami_cchip.cc - tsunami_io.cc - tsunami_fake.cc - tsunami_pchip.cc ''') # Let the target architecture define what additional sources it needs diff --git a/src/dev/alpha/SConscript b/src/dev/alpha/SConscript index b4b879385..304cd9ca9 100644 --- a/src/dev/alpha/SConscript +++ b/src/dev/alpha/SConscript @@ -36,32 +36,32 @@ Import('env') sources = Split(''' console.cc + tsunami.cc + tsunami_cchip.cc + tsunami_io.cc + tsunami_fake.cc + tsunami_pchip.cc ''') -# dev/baddev.cc -# dev/disk_image.cc -# dev/etherbus.cc -# dev/etherdump.cc -# dev/etherint.cc -# dev/etherlink.cc -# dev/etherpkt.cc -# dev/ethertap.cc -# dev/ide_ctrl.cc -# dev/ide_disk.cc -# dev/io_device.cc -# dev/isa_fake.cc -# dev/ns_gige.cc -# dev/pciconfigall.cc -# dev/pcidev.cc -# dev/pcifake.cc -# dev/pktfifo.cc -# dev/platform.cc -# dev/simconsole.cc -# dev/simple_disk.cc -# dev/tsunami.cc -# dev/tsunami_cchip.cc -# dev/tsunami_io.cc -# dev/tsunami_fake.cc -# dev/tsunami_pchip.cc +# baddev.cc +# disk_image.cc +# etherbus.cc +# etherdump.cc +# etherint.cc +# etherlink.cc +# etherpkt.cc +# ethertap.cc +# ide_ctrl.cc +# ide_disk.cc +# io_device.cc +# isa_fake.cc +# ns_gige.cc +# pciconfigall.cc +# pcidev.cc +# pcifake.cc +# pktfifo.cc +# platform.cc +# simconsole.cc +# simple_disk.cc # Convert file names to SCons File objects. This takes care of the # path relative to the top of the directory tree. diff --git a/src/dev/alpha/tsunami.cc b/src/dev/alpha/tsunami.cc new file mode 100644 index 000000000..608e88846 --- /dev/null +++ b/src/dev/alpha/tsunami.cc @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2004-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: Ali Saidi + */ + +/** @file + * Implementation of Tsunami platform. + */ + +#include +#include +#include + +#include "cpu/intr_control.hh" +#include "dev/simconsole.hh" +#include "dev/alpha/tsunami_cchip.hh" +#include "dev/alpha/tsunami_pchip.hh" +#include "dev/alpha/tsunami_io.hh" +#include "dev/alpha/tsunami.hh" +#include "sim/builder.hh" +#include "sim/system.hh" + +using namespace std; +//Should this be AlphaISA? +using namespace TheISA; + +Tsunami::Tsunami(const string &name, System *s, IntrControl *ic) + : Platform(name, ic), system(s) +{ + // set the back pointer from the system to myself + system->platform = this; + + for (int i = 0; i < Tsunami::Max_CPUs; i++) + intr_sum_type[i] = 0; +} + +Tick +Tsunami::intrFrequency() +{ + return io->frequency(); +} + +void +Tsunami::postConsoleInt() +{ + io->postPIC(0x10); +} + +void +Tsunami::clearConsoleInt() +{ + io->clearPIC(0x10); +} + +void +Tsunami::postPciInt(int line) +{ + cchip->postDRIR(line); +} + +void +Tsunami::clearPciInt(int line) +{ + cchip->clearDRIR(line); +} + +Addr +Tsunami::pciToDma(Addr pciAddr) const +{ + return pchip->translatePciToDma(pciAddr); +} + + +Addr +Tsunami::calcConfigAddr(int bus, int dev, int func) +{ + return pchip->calcConfigAddr(bus, dev, func); +} + +void +Tsunami::serialize(std::ostream &os) +{ + SERIALIZE_ARRAY(intr_sum_type, Tsunami::Max_CPUs); +} + +void +Tsunami::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ARRAY(intr_sum_type, Tsunami::Max_CPUs); +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tsunami) + + SimObjectParam system; + SimObjectParam intrctrl; + +END_DECLARE_SIM_OBJECT_PARAMS(Tsunami) + +BEGIN_INIT_SIM_OBJECT_PARAMS(Tsunami) + + INIT_PARAM(system, "system"), + INIT_PARAM(intrctrl, "interrupt controller") + +END_INIT_SIM_OBJECT_PARAMS(Tsunami) + +CREATE_SIM_OBJECT(Tsunami) +{ + return new Tsunami(getInstanceName(), system, intrctrl); +} + +REGISTER_SIM_OBJECT("Tsunami", Tsunami) diff --git a/src/dev/alpha/tsunami.hh b/src/dev/alpha/tsunami.hh new file mode 100644 index 000000000..6fbfac851 --- /dev/null +++ b/src/dev/alpha/tsunami.hh @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2004-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: Ali Saidi + */ + +/** + * @file + * Declaration of top level class for the Tsunami chipset. This class just + * retains pointers to all its children so the children can communicate. + */ + +#ifndef __DEV_TSUNAMI_HH__ +#define __DEV_TSUNAMI_HH__ + +#include "dev/platform.hh" + +class IdeController; +class TsunamiCChip; +class TsunamiPChip; +class TsunamiIO; +class System; + +/** + * Top level class for Tsunami Chipset emulation. + * This structure just contains pointers to all the + * children so the children can commnicate to do the + * read work + */ + +class Tsunami : public Platform +{ + public: + /** Max number of CPUs in a Tsunami */ + static const int Max_CPUs = 64; + + /** Pointer to the system */ + System *system; + + /** Pointer to the TsunamiIO device which has the RTC */ + TsunamiIO *io; + + /** Pointer to the Tsunami CChip. + * The chip contains some configuration information and + * all the interrupt mask and status registers + */ + TsunamiCChip *cchip; + + /** Pointer to the Tsunami PChip. + * The pchip is the interface to the PCI bus, in our case + * it does not have to do much. + */ + TsunamiPChip *pchip; + + int intr_sum_type[Tsunami::Max_CPUs]; + int ipi_pending[Tsunami::Max_CPUs]; + + public: + /** + * Constructor for the Tsunami Class. + * @param name name of the object + * @param s system the object belongs to + * @param intctrl pointer to the interrupt controller + */ + Tsunami(const std::string &name, System *s, IntrControl *intctrl); + + /** + * Return the interrupting frequency to AlphaAccess + * @return frequency of RTC interrupts + */ + virtual Tick intrFrequency(); + + /** + * Cause the cpu to post a serial interrupt to the CPU. + */ + virtual void postConsoleInt(); + + /** + * Clear a posted CPU interrupt (id=55) + */ + virtual void clearConsoleInt(); + + /** + * Cause the chipset to post a cpi interrupt to the CPU. + */ + virtual void postPciInt(int line); + + /** + * Clear a posted PCI->CPU interrupt + */ + virtual void clearPciInt(int line); + + + virtual Addr pciToDma(Addr pciAddr) const; + + /** + * Calculate the configuration address given a bus/dev/func. + */ + virtual Addr calcConfigAddr(int bus, int dev, int func); + + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ + virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +#endif // __DEV_TSUNAMI_HH__ diff --git a/src/dev/alpha/tsunami_cchip.cc b/src/dev/alpha/tsunami_cchip.cc new file mode 100644 index 000000000..924e1d462 --- /dev/null +++ b/src/dev/alpha/tsunami_cchip.cc @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2004-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: Ali Saidi + * Ron Dreslinski + */ + +/** @file + * Emulation of the Tsunami CChip CSRs + */ + +#include +#include +#include + +#include "arch/alpha/ev5.hh" +#include "base/trace.hh" +#include "cpu/intr_control.hh" +#include "cpu/thread_context.hh" +#include "dev/alpha/tsunami.hh" +#include "dev/alpha/tsunami_cchip.hh" +#include "dev/alpha/tsunamireg.h" +#include "mem/packet.hh" +#include "mem/packet_access.hh" +#include "mem/port.hh" +#include "sim/builder.hh" +#include "sim/system.hh" + +using namespace std; +//Should this be AlphaISA? +using namespace TheISA; + +TsunamiCChip::TsunamiCChip(Params *p) + : BasicPioDevice(p), tsunami(p->tsunami) +{ + pioSize = 0xfffffff; + + drir = 0; + ipint = 0; + itint = 0; + + for (int x = 0; x < Tsunami::Max_CPUs; x++) + { + dim[x] = 0; + dir[x] = 0; + } + + //Put back pointer in tsunami + tsunami->cchip = this; +} + +Tick +TsunamiCChip::read(PacketPtr pkt) +{ + DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize()); + + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + + Addr regnum = (pkt->getAddr() - pioAddr) >> 6; + Addr daddr = (pkt->getAddr() - pioAddr); + + pkt->allocate(); + switch (pkt->getSize()) { + + case sizeof(uint64_t): + if (daddr & TSDEV_CC_BDIMS) + { + pkt->set(dim[(daddr >> 4) & 0x3F]); + break; + } + + if (daddr & TSDEV_CC_BDIRS) + { + pkt->set(dir[(daddr >> 4) & 0x3F]); + break; + } + + switch(regnum) { + case TSDEV_CC_CSR: + pkt->set(0x0); + break; + case TSDEV_CC_MTR: + panic("TSDEV_CC_MTR not implemeted\n"); + break; + case TSDEV_CC_MISC: + pkt->set((ipint << 8) & 0xF | (itint << 4) & 0xF | + (pkt->req->getCpuNum() & 0x3)); + break; + case TSDEV_CC_AAR0: + case TSDEV_CC_AAR1: + case TSDEV_CC_AAR2: + case TSDEV_CC_AAR3: + pkt->set(0); + break; + case TSDEV_CC_DIM0: + pkt->set(dim[0]); + break; + case TSDEV_CC_DIM1: + pkt->set(dim[1]); + break; + case TSDEV_CC_DIM2: + pkt->set(dim[2]); + break; + case TSDEV_CC_DIM3: + pkt->set(dim[3]); + break; + case TSDEV_CC_DIR0: + pkt->set(dir[0]); + break; + case TSDEV_CC_DIR1: + pkt->set(dir[1]); + break; + case TSDEV_CC_DIR2: + pkt->set(dir[2]); + break; + case TSDEV_CC_DIR3: + pkt->set(dir[3]); + break; + case TSDEV_CC_DRIR: + pkt->set(drir); + break; + case TSDEV_CC_PRBEN: + panic("TSDEV_CC_PRBEN not implemented\n"); + break; + case TSDEV_CC_IIC0: + case TSDEV_CC_IIC1: + case TSDEV_CC_IIC2: + case TSDEV_CC_IIC3: + panic("TSDEV_CC_IICx not implemented\n"); + break; + case TSDEV_CC_MPR0: + case TSDEV_CC_MPR1: + case TSDEV_CC_MPR2: + case TSDEV_CC_MPR3: + panic("TSDEV_CC_MPRx not implemented\n"); + break; + case TSDEV_CC_IPIR: + pkt->set(ipint); + break; + case TSDEV_CC_ITIR: + pkt->set(itint); + break; + default: + panic("default in cchip read reached, accessing 0x%x\n"); + } // uint64_t + + break; + case sizeof(uint32_t): + case sizeof(uint16_t): + case sizeof(uint8_t): + default: + panic("invalid access size(?) for tsunami register!\n"); + } + DPRINTF(Tsunami, "Tsunami CChip: read regnum=%#x size=%d data=%lld\n", + regnum, pkt->getSize(), pkt->get()); + + pkt->result = Packet::Success; + return pioDelay; +} + +Tick +TsunamiCChip::write(PacketPtr pkt) +{ + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + Addr daddr = pkt->getAddr() - pioAddr; + Addr regnum = (pkt->getAddr() - pioAddr) >> 6 ; + + + assert(pkt->getSize() == sizeof(uint64_t)); + + DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt->getAddr(), pkt->get()); + + bool supportedWrite = false; + + + if (daddr & TSDEV_CC_BDIMS) + { + int number = (daddr >> 4) & 0x3F; + + uint64_t bitvector; + uint64_t olddim; + uint64_t olddir; + + olddim = dim[number]; + olddir = dir[number]; + dim[number] = pkt->get(); + dir[number] = dim[number] & drir; + for(int x = 0; x < Tsunami::Max_CPUs; x++) + { + bitvector = ULL(1) << x; + // Figure out which bits have changed + if ((dim[number] & bitvector) != (olddim & bitvector)) + { + // The bit is now set and it wasn't before (set) + if((dim[number] & bitvector) && (dir[number] & bitvector)) + { + tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "dim write resulting in posting dir" + " interrupt to cpu %d\n", number); + } + else if ((olddir & bitvector) && + !(dir[number] & bitvector)) + { + // The bit was set and now its now clear and + // we were interrupting on that bit before + tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "dim write resulting in clear" + " dir interrupt to cpu %d\n", number); + + } + + + } + } + } else { + switch(regnum) { + case TSDEV_CC_CSR: + panic("TSDEV_CC_CSR write\n"); + case TSDEV_CC_MTR: + panic("TSDEV_CC_MTR write not implemented\n"); + case TSDEV_CC_MISC: + uint64_t ipreq; + ipreq = (pkt->get() >> 12) & 0xF; + //If it is bit 12-15, this is an IPI post + if (ipreq) { + reqIPI(ipreq); + supportedWrite = true; + } + + //If it is bit 8-11, this is an IPI clear + uint64_t ipintr; + ipintr = (pkt->get() >> 8) & 0xF; + if (ipintr) { + clearIPI(ipintr); + supportedWrite = true; + } + + //If it is the 4-7th bit, clear the RTC interrupt + uint64_t itintr; + itintr = (pkt->get() >> 4) & 0xF; + if (itintr) { + clearITI(itintr); + supportedWrite = true; + } + + // ignore NXMs + if (pkt->get() & 0x10000000) + supportedWrite = true; + + if(!supportedWrite) + panic("TSDEV_CC_MISC write not implemented\n"); + + break; + case TSDEV_CC_AAR0: + case TSDEV_CC_AAR1: + case TSDEV_CC_AAR2: + case TSDEV_CC_AAR3: + panic("TSDEV_CC_AARx write not implemeted\n"); + case TSDEV_CC_DIM0: + case TSDEV_CC_DIM1: + case TSDEV_CC_DIM2: + case TSDEV_CC_DIM3: + int number; + if(regnum == TSDEV_CC_DIM0) + number = 0; + else if(regnum == TSDEV_CC_DIM1) + number = 1; + else if(regnum == TSDEV_CC_DIM2) + number = 2; + else + number = 3; + + uint64_t bitvector; + uint64_t olddim; + uint64_t olddir; + + olddim = dim[number]; + olddir = dir[number]; + dim[number] = pkt->get(); + dir[number] = dim[number] & drir; + for(int x = 0; x < 64; x++) + { + bitvector = ULL(1) << x; + // Figure out which bits have changed + if ((dim[number] & bitvector) != (olddim & bitvector)) + { + // The bit is now set and it wasn't before (set) + if((dim[number] & bitvector) && (dir[number] & bitvector)) + { + tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); + } + else if ((olddir & bitvector) && + !(dir[number] & bitvector)) + { + // The bit was set and now its now clear and + // we were interrupting on that bit before + tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "dim write resulting in clear" + " dir interrupt to cpu %d\n", + x); + + } + + + } + } + break; + case TSDEV_CC_DIR0: + case TSDEV_CC_DIR1: + case TSDEV_CC_DIR2: + case TSDEV_CC_DIR3: + panic("TSDEV_CC_DIR write not implemented\n"); + case TSDEV_CC_DRIR: + panic("TSDEV_CC_DRIR write not implemented\n"); + case TSDEV_CC_PRBEN: + panic("TSDEV_CC_PRBEN write not implemented\n"); + case TSDEV_CC_IIC0: + case TSDEV_CC_IIC1: + case TSDEV_CC_IIC2: + case TSDEV_CC_IIC3: + panic("TSDEV_CC_IICx write not implemented\n"); + case TSDEV_CC_MPR0: + case TSDEV_CC_MPR1: + case TSDEV_CC_MPR2: + case TSDEV_CC_MPR3: + panic("TSDEV_CC_MPRx write not implemented\n"); + case TSDEV_CC_IPIR: + clearIPI(pkt->get()); + break; + case TSDEV_CC_ITIR: + clearITI(pkt->get()); + break; + case TSDEV_CC_IPIQ: + reqIPI(pkt->get()); + break; + default: + panic("default in cchip read reached, accessing 0x%x\n"); + } // swtich(regnum) + } // not BIG_TSUNAMI write + pkt->result = Packet::Success; + return pioDelay; +} + +void +TsunamiCChip::clearIPI(uint64_t ipintr) +{ + int numcpus = tsunami->intrctrl->cpu->system->threadContexts.size(); + assert(numcpus <= Tsunami::Max_CPUs); + + if (ipintr) { + for (int cpunum=0; cpunum < numcpus; cpunum++) { + // Check each cpu bit + uint64_t cpumask = ULL(1) << cpunum; + if (ipintr & cpumask) { + // Check if there is a pending ipi + if (ipint & cpumask) { + ipint &= ~cpumask; + tsunami->intrctrl->clear(cpunum, TheISA::INTLEVEL_IRQ3, 0); + DPRINTF(IPI, "clear IPI IPI cpu=%d\n", cpunum); + } + else + warn("clear IPI for CPU=%d, but NO IPI\n", cpunum); + } + } + } + else + panic("Big IPI Clear, but not processors indicated\n"); +} + +void +TsunamiCChip::clearITI(uint64_t itintr) +{ + int numcpus = tsunami->intrctrl->cpu->system->threadContexts.size(); + assert(numcpus <= Tsunami::Max_CPUs); + + if (itintr) { + for (int i=0; i < numcpus; i++) { + uint64_t cpumask = ULL(1) << i; + if (itintr & cpumask & itint) { + tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ2, 0); + itint &= ~cpumask; + DPRINTF(Tsunami, "clearing rtc interrupt to cpu=%d\n", i); + } + } + } + else + panic("Big ITI Clear, but not processors indicated\n"); +} + +void +TsunamiCChip::reqIPI(uint64_t ipreq) +{ + int numcpus = tsunami->intrctrl->cpu->system->threadContexts.size(); + assert(numcpus <= Tsunami::Max_CPUs); + + if (ipreq) { + for (int cpunum=0; cpunum < numcpus; cpunum++) { + // Check each cpu bit + uint64_t cpumask = ULL(1) << cpunum; + if (ipreq & cpumask) { + // Check if there is already an ipi (bits 8:11) + if (!(ipint & cpumask)) { + ipint |= cpumask; + tsunami->intrctrl->post(cpunum, TheISA::INTLEVEL_IRQ3, 0); + DPRINTF(IPI, "send IPI cpu=%d\n", cpunum); + } + else + warn("post IPI for CPU=%d, but IPI already\n", cpunum); + } + } + } + else + panic("Big IPI Request, but not processors indicated\n"); +} + + +void +TsunamiCChip::postRTC() +{ + int size = tsunami->intrctrl->cpu->system->threadContexts.size(); + assert(size <= Tsunami::Max_CPUs); + + for (int i = 0; i < size; i++) { + uint64_t cpumask = ULL(1) << i; + if (!(cpumask & itint)) { + itint |= cpumask; + tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0); + DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i); + } + } + +} + +void +TsunamiCChip::postDRIR(uint32_t interrupt) +{ + uint64_t bitvector = ULL(1) << interrupt; + uint64_t size = tsunami->intrctrl->cpu->system->threadContexts.size(); + assert(size <= Tsunami::Max_CPUs); + drir |= bitvector; + + for(int i=0; i < size; i++) { + dir[i] = dim[i] & drir; + if (dim[i] & bitvector) { + tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt); + DPRINTF(Tsunami, "posting dir interrupt to cpu %d," + "interrupt %d\n",i, interrupt); + } + } +} + +void +TsunamiCChip::clearDRIR(uint32_t interrupt) +{ + uint64_t bitvector = ULL(1) << interrupt; + uint64_t size = tsunami->intrctrl->cpu->system->threadContexts.size(); + assert(size <= Tsunami::Max_CPUs); + + if (drir & bitvector) + { + drir &= ~bitvector; + for(int i=0; i < size; i++) { + if (dir[i] & bitvector) { + tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt); + DPRINTF(Tsunami, "clearing dir interrupt to cpu %d," + "interrupt %d\n",i, interrupt); + + } + dir[i] = dim[i] & drir; + } + } + else + DPRINTF(Tsunami, "Spurrious clear? interrupt %d\n", interrupt); +} + + +void +TsunamiCChip::serialize(std::ostream &os) +{ + SERIALIZE_ARRAY(dim, Tsunami::Max_CPUs); + SERIALIZE_ARRAY(dir, Tsunami::Max_CPUs); + SERIALIZE_SCALAR(ipint); + SERIALIZE_SCALAR(itint); + SERIALIZE_SCALAR(drir); +} + +void +TsunamiCChip::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ARRAY(dim, Tsunami::Max_CPUs); + UNSERIALIZE_ARRAY(dir, Tsunami::Max_CPUs); + UNSERIALIZE_SCALAR(ipint); + UNSERIALIZE_SCALAR(itint); + UNSERIALIZE_SCALAR(drir); +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) + + Param pio_addr; + Param pio_latency; + SimObjectParam platform; + SimObjectParam system; + SimObjectParam tsunami; + +END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) + +BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) + + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object"), + INIT_PARAM(tsunami, "Tsunami") + +END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) + +CREATE_SIM_OBJECT(TsunamiCChip) +{ + TsunamiCChip::Params *p = new TsunamiCChip::Params; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + p->tsunami = tsunami; + return new TsunamiCChip(p); +} + +REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip) diff --git a/src/dev/alpha/tsunami_cchip.hh b/src/dev/alpha/tsunami_cchip.hh new file mode 100644 index 000000000..004c3cd29 --- /dev/null +++ b/src/dev/alpha/tsunami_cchip.hh @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2004-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: Ali Saidi + */ + +/** @file + * Emulation of the Tsunami CChip CSRs + */ + +#ifndef __TSUNAMI_CCHIP_HH__ +#define __TSUNAMI_CCHIP_HH__ + +#include "dev/alpha/tsunami.hh" +#include "base/range.hh" +#include "dev/io_device.hh" + + +/** + * Tsunami CChip CSR Emulation. This device includes all the interrupt + * handling code for the chipset. + */ +class TsunamiCChip : public BasicPioDevice +{ + protected: + /** + * pointer to the tsunami object. + * This is our access to all the other tsunami + * devices. + */ + Tsunami *tsunami; + + /** + * The dims are device interrupt mask registers. + * One exists for each CPU, the DRIR X DIM = DIR + */ + uint64_t dim[Tsunami::Max_CPUs]; + + /** + * The dirs are device interrupt registers. + * One exists for each CPU, the DRIR X DIM = DIR + */ + uint64_t dir[Tsunami::Max_CPUs]; + + /** + * This register contains bits for each PCI interrupt + * that can occur. + */ + uint64_t drir; + + /** Indicator of which CPUs have an IPI interrupt */ + uint64_t ipint; + + /** Indicator of which CPUs have an RTC interrupt */ + uint64_t itint; + + public: + struct Params : public BasicPioDevice::Params + { + Tsunami *tsunami; + }; + protected: + const Params *params() const {return (const Params *)_params; } + + public: + /** + * Initialize the Tsunami CChip by setting all of the + * device register to 0. + * @param p params struct + */ + TsunamiCChip(Params *p); + + virtual Tick read(PacketPtr pkt); + + virtual Tick write(PacketPtr pkt); + + /** + * post an RTC interrupt to the CPU + */ + void postRTC(); + + /** + * post an interrupt to the CPU. + * @param interrupt the interrupt number to post (0-64) + */ + void postDRIR(uint32_t interrupt); + + /** + * clear an interrupt previously posted to the CPU. + * @param interrupt the interrupt number to post (0-64) + */ + void clearDRIR(uint32_t interrupt); + + /** + * post an ipi interrupt to the CPU. + * @param ipintr the cpu number to clear(bitvector) + */ + void clearIPI(uint64_t ipintr); + + /** + * clear a timer interrupt previously posted to the CPU. + * @param itintr the cpu number to clear(bitvector) + */ + void clearITI(uint64_t itintr); + + /** + * request an interrupt be posted to the CPU. + * @param ipreq the cpu number to interrupt(bitvector) + */ + void reqIPI(uint64_t ipreq); + + + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ + virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + virtual void unserialize(Checkpoint *cp, const std::string §ion); + +}; + +#endif // __TSUNAMI_CCHIP_HH__ diff --git a/src/dev/alpha/tsunami_io.cc b/src/dev/alpha/tsunami_io.cc new file mode 100644 index 000000000..def214a95 --- /dev/null +++ b/src/dev/alpha/tsunami_io.cc @@ -0,0 +1,688 @@ +/* + * Copyright (c) 2004-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: Ali Saidi + * Andrew Schultz + * Miguel Serrano + */ + +/** @file + * Tsunami I/O including PIC, PIT, RTC, DMA + */ + +#include + +#include +#include +#include + +#include "base/trace.hh" +#include "dev/pitreg.h" +#include "dev/rtcreg.h" +#include "dev/alpha/tsunami_cchip.hh" +#include "dev/alpha/tsunami.hh" +#include "dev/alpha/tsunami_io.hh" +#include "dev/alpha/tsunamireg.h" +#include "mem/packet.hh" +#include "mem/packet_access.hh" +#include "mem/port.hh" +#include "sim/builder.hh" +#include "sim/system.hh" + +using namespace std; +//Should this be AlphaISA? +using namespace TheISA; + +TsunamiIO::RTC::RTC(const string &name, Tsunami* t, Tick i) + : _name(name), event(t, i), addr(0) +{ + memset(clock_data, 0, sizeof(clock_data)); + stat_regA = RTCA_32768HZ | RTCA_1024HZ; + stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR; +} + +void +TsunamiIO::RTC::set_time(time_t t) +{ + struct tm tm; + gmtime_r(&t, &tm); + + sec = tm.tm_sec; + min = tm.tm_min; + hour = tm.tm_hour; + wday = tm.tm_wday + 1; + mday = tm.tm_mday; + mon = tm.tm_mon + 1; + year = tm.tm_year; + + DPRINTFN("Real-time clock set to %s", asctime(&tm)); +} + +void +TsunamiIO::RTC::writeAddr(const uint8_t data) +{ + if (data <= RTC_STAT_REGD) + addr = data; + else + panic("RTC addresses over 0xD are not implemented.\n"); +} + +void +TsunamiIO::RTC::writeData(const uint8_t data) +{ + if (addr < RTC_STAT_REGA) + clock_data[addr] = data; + else { + switch (addr) { + case RTC_STAT_REGA: + if (data != (RTCA_32768HZ | RTCA_1024HZ)) + panic("Unimplemented RTC register A value write!\n"); + stat_regA = data; + break; + case RTC_STAT_REGB: + if ((data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR)) + panic("Write to RTC reg B bits that are not implemented!\n"); + + if (data & RTCB_PRDC_IE) { + if (!event.scheduled()) + event.scheduleIntr(); + } else { + if (event.scheduled()) + event.deschedule(); + } + stat_regB = data; + break; + case RTC_STAT_REGC: + case RTC_STAT_REGD: + panic("RTC status registers C and D are not implemented.\n"); + break; + } + } +} + +uint8_t +TsunamiIO::RTC::readData() +{ + if (addr < RTC_STAT_REGA) + return clock_data[addr]; + else { + switch (addr) { + case RTC_STAT_REGA: + // toggle UIP bit for linux + stat_regA ^= RTCA_UIP; + return stat_regA; + break; + case RTC_STAT_REGB: + return stat_regB; + break; + case RTC_STAT_REGC: + case RTC_STAT_REGD: + return 0x00; + break; + default: + panic("Shouldn't be here"); + } + } +} + +void +TsunamiIO::RTC::serialize(const string &base, ostream &os) +{ + paramOut(os, base + ".addr", addr); + arrayParamOut(os, base + ".clock_data", clock_data, sizeof(clock_data)); + paramOut(os, base + ".stat_regA", stat_regA); + paramOut(os, base + ".stat_regB", stat_regB); +} + +void +TsunamiIO::RTC::unserialize(const string &base, Checkpoint *cp, + const string §ion) +{ + paramIn(cp, section, base + ".addr", addr); + arrayParamIn(cp, section, base + ".clock_data", clock_data, + sizeof(clock_data)); + paramIn(cp, section, base + ".stat_regA", stat_regA); + paramIn(cp, section, base + ".stat_regB", stat_regB); + + // We're not unserializing the event here, but we need to + // rescehedule the event since curTick was moved forward by the + // checkpoint + event.reschedule(curTick + event.interval); +} + +TsunamiIO::RTC::RTCEvent::RTCEvent(Tsunami*t, Tick i) + : Event(&mainEventQueue), tsunami(t), interval(i) +{ + DPRINTF(MC146818, "RTC Event Initilizing\n"); + schedule(curTick + interval); +} + +void +TsunamiIO::RTC::RTCEvent::scheduleIntr() +{ + schedule(curTick + interval); +} + +void +TsunamiIO::RTC::RTCEvent::process() +{ + DPRINTF(MC146818, "RTC Timer Interrupt\n"); + schedule(curTick + interval); + //Actually interrupt the processor here + tsunami->cchip->postRTC(); +} + +const char * +TsunamiIO::RTC::RTCEvent::description() +{ + return "tsunami RTC interrupt"; +} + +TsunamiIO::PITimer::PITimer(const string &name) + : _name(name), counter0(name + ".counter0"), counter1(name + ".counter1"), + counter2(name + ".counter2") +{ + counter[0] = &counter0; + counter[1] = &counter0; + counter[2] = &counter0; +} + +void +TsunamiIO::PITimer::writeControl(const uint8_t data) +{ + int rw; + int sel; + + sel = GET_CTRL_SEL(data); + + if (sel == PIT_READ_BACK) + panic("PITimer Read-Back Command is not implemented.\n"); + + rw = GET_CTRL_RW(data); + + if (rw == PIT_RW_LATCH_COMMAND) + counter[sel]->latchCount(); + else { + counter[sel]->setRW(rw); + counter[sel]->setMode(GET_CTRL_MODE(data)); + counter[sel]->setBCD(GET_CTRL_BCD(data)); + } +} + +void +TsunamiIO::PITimer::serialize(const string &base, ostream &os) +{ + // serialize the counters + counter0.serialize(base + ".counter0", os); + counter1.serialize(base + ".counter1", os); + counter2.serialize(base + ".counter2", os); +} + +void +TsunamiIO::PITimer::unserialize(const string &base, Checkpoint *cp, + const string §ion) +{ + // unserialze the counters + counter0.unserialize(base + ".counter0", cp, section); + counter1.unserialize(base + ".counter1", cp, section); + counter2.unserialize(base + ".counter2", cp, section); +} + +TsunamiIO::PITimer::Counter::Counter(const string &name) + : _name(name), event(this), count(0), latched_count(0), period(0), + mode(0), output_high(false), latch_on(false), read_byte(LSB), + write_byte(LSB) +{ + +} + +void +TsunamiIO::PITimer::Counter::latchCount() +{ + // behave like a real latch + if(!latch_on) { + latch_on = true; + read_byte = LSB; + latched_count = count; + } +} + +uint8_t +TsunamiIO::PITimer::Counter::read() +{ + if (latch_on) { + switch (read_byte) { + case LSB: + read_byte = MSB; + return (uint8_t)latched_count; + break; + case MSB: + read_byte = LSB; + latch_on = false; + return latched_count >> 8; + break; + default: + panic("Shouldn't be here"); + } + } else { + switch (read_byte) { + case LSB: + read_byte = MSB; + return (uint8_t)count; + break; + case MSB: + read_byte = LSB; + return count >> 8; + break; + default: + panic("Shouldn't be here"); + } + } +} + +void +TsunamiIO::PITimer::Counter::write(const uint8_t data) +{ + switch (write_byte) { + case LSB: + count = (count & 0xFF00) | data; + + if (event.scheduled()) + event.deschedule(); + output_high = false; + write_byte = MSB; + break; + + case MSB: + count = (count & 0x00FF) | (data << 8); + period = count; + + if (period > 0) { + DPRINTF(Tsunami, "Timer set to curTick + %d\n", + count * event.interval); + event.schedule(curTick + count * event.interval); + } + write_byte = LSB; + break; + } +} + +void +TsunamiIO::PITimer::Counter::setRW(int rw_val) +{ + if (rw_val != PIT_RW_16BIT) + panic("Only LSB/MSB read/write is implemented.\n"); +} + +void +TsunamiIO::PITimer::Counter::setMode(int mode_val) +{ + if(mode_val != PIT_MODE_INTTC && mode_val != PIT_MODE_RATEGEN && + mode_val != PIT_MODE_SQWAVE) + panic("PIT mode %#x is not implemented: \n", mode_val); + + mode = mode_val; +} + +void +TsunamiIO::PITimer::Counter::setBCD(int bcd_val) +{ + if (bcd_val != PIT_BCD_FALSE) + panic("PITimer does not implement BCD counts.\n"); +} + +bool +TsunamiIO::PITimer::Counter::outputHigh() +{ + return output_high; +} + +void +TsunamiIO::PITimer::Counter::serialize(const string &base, ostream &os) +{ + paramOut(os, base + ".count", count); + paramOut(os, base + ".latched_count", latched_count); + paramOut(os, base + ".period", period); + paramOut(os, base + ".mode", mode); + paramOut(os, base + ".output_high", output_high); + paramOut(os, base + ".latch_on", latch_on); + paramOut(os, base + ".read_byte", read_byte); + paramOut(os, base + ".write_byte", write_byte); + + Tick event_tick = 0; + if (event.scheduled()) + event_tick = event.when(); + paramOut(os, base + ".event_tick", event_tick); +} + +void +TsunamiIO::PITimer::Counter::unserialize(const string &base, Checkpoint *cp, + const string §ion) +{ + paramIn(cp, section, base + ".count", count); + paramIn(cp, section, base + ".latched_count", latched_count); + paramIn(cp, section, base + ".period", period); + paramIn(cp, section, base + ".mode", mode); + paramIn(cp, section, base + ".output_high", output_high); + paramIn(cp, section, base + ".latch_on", latch_on); + paramIn(cp, section, base + ".read_byte", read_byte); + paramIn(cp, section, base + ".write_byte", write_byte); + + Tick event_tick; + paramIn(cp, section, base + ".event_tick", event_tick); + if (event_tick) + event.schedule(event_tick); +} + +TsunamiIO::PITimer::Counter::CounterEvent::CounterEvent(Counter* c_ptr) + : Event(&mainEventQueue) +{ + interval = (Tick)(Clock::Float::s / 1193180.0); + counter = c_ptr; +} + +void +TsunamiIO::PITimer::Counter::CounterEvent::process() +{ + DPRINTF(Tsunami, "Timer Interrupt\n"); + switch (counter->mode) { + case PIT_MODE_INTTC: + counter->output_high = true; + case PIT_MODE_RATEGEN: + case PIT_MODE_SQWAVE: + break; + default: + panic("Unimplemented PITimer mode.\n"); + } +} + +const char * +TsunamiIO::PITimer::Counter::CounterEvent::description() +{ + return "tsunami 8254 Interval timer"; +} + +TsunamiIO::TsunamiIO(Params *p) + : BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"), + rtc(p->name + ".rtc", p->tsunami, p->frequency) +{ + pioSize = 0xff; + + // set the back pointer from tsunami to myself + tsunami->io = this; + + timerData = 0; + rtc.set_time(p->init_time == 0 ? time(NULL) : p->init_time); + picr = 0; + picInterrupting = false; +} + +Tick +TsunamiIO::frequency() const +{ + return Clock::Frequency / params()->frequency; +} + +Tick +TsunamiIO::read(PacketPtr pkt) +{ + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + + Addr daddr = pkt->getAddr() - pioAddr; + + DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt->getAddr(), + pkt->getSize(), daddr); + + pkt->allocate(); + + if (pkt->getSize() == sizeof(uint8_t)) { + switch(daddr) { + // PIC1 mask read + case TSDEV_PIC1_MASK: + pkt->set(~mask1); + break; + case TSDEV_PIC2_MASK: + pkt->set(~mask2); + break; + case TSDEV_PIC1_ISR: + // !!! If this is modified 64bit case needs to be too + // Pal code has to do a 64 bit physical read because there is + // no load physical byte instruction + pkt->set(picr); + break; + case TSDEV_PIC2_ISR: + // PIC2 not implemnted... just return 0 + pkt->set(0x00); + break; + case TSDEV_TMR0_DATA: + pkt->set(pitimer.counter0.read()); + break; + case TSDEV_TMR1_DATA: + pkt->set(pitimer.counter1.read()); + break; + case TSDEV_TMR2_DATA: + pkt->set(pitimer.counter2.read()); + break; + case TSDEV_RTC_DATA: + pkt->set(rtc.readData()); + break; + case TSDEV_CTRL_PORTB: + if (pitimer.counter2.outputHigh()) + pkt->set(PORTB_SPKR_HIGH); + else + pkt->set(0x00); + break; + default: + panic("I/O Read - va%#x size %d\n", pkt->getAddr(), pkt->getSize()); + } + } else if (pkt->getSize() == sizeof(uint64_t)) { + if (daddr == TSDEV_PIC1_ISR) + pkt->set(picr); + else + panic("I/O Read - invalid addr - va %#x size %d\n", + pkt->getAddr(), pkt->getSize()); + } else { + panic("I/O Read - invalid size - va %#x size %d\n", pkt->getAddr(), pkt->getSize()); + } + pkt->result = Packet::Success; + return pioDelay; +} + +Tick +TsunamiIO::write(PacketPtr pkt) +{ + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + Addr daddr = pkt->getAddr() - pioAddr; + + DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n", + pkt->getAddr(), pkt->getSize(), pkt->getAddr() & 0xfff, (uint32_t)pkt->get()); + + assert(pkt->getSize() == sizeof(uint8_t)); + + switch(daddr) { + case TSDEV_PIC1_MASK: + mask1 = ~(pkt->get()); + if ((picr & mask1) && !picInterrupting) { + picInterrupting = true; + tsunami->cchip->postDRIR(55); + DPRINTF(Tsunami, "posting pic interrupt to cchip\n"); + } + if ((!(picr & mask1)) && picInterrupting) { + picInterrupting = false; + tsunami->cchip->clearDRIR(55); + DPRINTF(Tsunami, "clearing pic interrupt\n"); + } + break; + case TSDEV_PIC2_MASK: + mask2 = pkt->get(); + //PIC2 Not implemented to interrupt + break; + case TSDEV_PIC1_ACK: + // clear the interrupt on the PIC + picr &= ~(1 << (pkt->get() & 0xF)); + if (!(picr & mask1)) + tsunami->cchip->clearDRIR(55); + break; + case TSDEV_DMA1_MODE: + mode1 = pkt->get(); + break; + case TSDEV_DMA2_MODE: + mode2 = pkt->get(); + break; + case TSDEV_TMR0_DATA: + pitimer.counter0.write(pkt->get()); + break; + case TSDEV_TMR1_DATA: + pitimer.counter1.write(pkt->get()); + break; + case TSDEV_TMR2_DATA: + pitimer.counter2.write(pkt->get()); + break; + case TSDEV_TMR_CTRL: + pitimer.writeControl(pkt->get()); + break; + case TSDEV_RTC_ADDR: + rtc.writeAddr(pkt->get()); + break; + case TSDEV_RTC_DATA: + rtc.writeData(pkt->get()); + break; + case TSDEV_KBD: + case TSDEV_DMA1_CMND: + case TSDEV_DMA2_CMND: + case TSDEV_DMA1_MMASK: + case TSDEV_DMA2_MMASK: + case TSDEV_PIC2_ACK: + case TSDEV_DMA1_RESET: + case TSDEV_DMA2_RESET: + case TSDEV_DMA1_MASK: + case TSDEV_DMA2_MASK: + case TSDEV_CTRL_PORTB: + break; + default: + panic("I/O Write - va%#x size %d data %#x\n", pkt->getAddr(), pkt->getSize(), pkt->get()); + } + + pkt->result = Packet::Success; + return pioDelay; +} + +void +TsunamiIO::postPIC(uint8_t bitvector) +{ + //PIC2 Is not implemented, because nothing of interest there + picr |= bitvector; + if (picr & mask1) { + tsunami->cchip->postDRIR(55); + DPRINTF(Tsunami, "posting pic interrupt to cchip\n"); + } +} + +void +TsunamiIO::clearPIC(uint8_t bitvector) +{ + //PIC2 Is not implemented, because nothing of interest there + picr &= ~bitvector; + if (!(picr & mask1)) { + tsunami->cchip->clearDRIR(55); + DPRINTF(Tsunami, "clearing pic interrupt to cchip\n"); + } +} + +void +TsunamiIO::serialize(ostream &os) +{ + SERIALIZE_SCALAR(timerData); + SERIALIZE_SCALAR(mask1); + SERIALIZE_SCALAR(mask2); + SERIALIZE_SCALAR(mode1); + SERIALIZE_SCALAR(mode2); + SERIALIZE_SCALAR(picr); + SERIALIZE_SCALAR(picInterrupting); + + // Serialize the timers + pitimer.serialize("pitimer", os); + rtc.serialize("rtc", os); +} + +void +TsunamiIO::unserialize(Checkpoint *cp, const string §ion) +{ + UNSERIALIZE_SCALAR(timerData); + UNSERIALIZE_SCALAR(mask1); + UNSERIALIZE_SCALAR(mask2); + UNSERIALIZE_SCALAR(mode1); + UNSERIALIZE_SCALAR(mode2); + UNSERIALIZE_SCALAR(picr); + UNSERIALIZE_SCALAR(picInterrupting); + + // Unserialize the timers + pitimer.unserialize("pitimer", cp, section); + rtc.unserialize("rtc", cp, section); +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) + + Param pio_addr; + Param pio_latency; + Param frequency; + SimObjectParam platform; + SimObjectParam system; + Param time; + SimObjectParam tsunami; + +END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) + +BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO) + + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(frequency, "clock interrupt frequency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object"), + INIT_PARAM(time, "System time to use (0 for actual time"), + INIT_PARAM(tsunami, "Tsunami") + +END_INIT_SIM_OBJECT_PARAMS(TsunamiIO) + +CREATE_SIM_OBJECT(TsunamiIO) +{ + TsunamiIO::Params *p = new TsunamiIO::Params; + p->frequency = frequency; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + p->init_time = time; + p->tsunami = tsunami; + return new TsunamiIO(p); +} + +REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO) diff --git a/src/dev/alpha/tsunami_io.hh b/src/dev/alpha/tsunami_io.hh new file mode 100644 index 000000000..54acefc25 --- /dev/null +++ b/src/dev/alpha/tsunami_io.hh @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2004-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: Ali Saidi + * Andrew Schultz + * Miguel Serrano + */ + +/** @file + * Tsunami I/O Space mapping including RTC/timer interrupts + */ + +#ifndef __DEV_TSUNAMI_IO_HH__ +#define __DEV_TSUNAMI_IO_HH__ + +#include "dev/io_device.hh" +#include "base/range.hh" +#include "dev/alpha/tsunami.hh" +#include "sim/eventq.hh" + +/** + * Tsunami I/O device is a catch all for all the south bridge stuff we care + * to implement. + */ +class TsunamiIO : public BasicPioDevice +{ + private: + struct tm tm; + + protected: + /** Real-Time Clock (MC146818) */ + class RTC + { + private: + /** Event for RTC periodic interrupt */ + struct RTCEvent : public Event + { + /** A pointer back to tsunami to create interrupt the processor. */ + Tsunami* tsunami; + Tick interval; + + RTCEvent(Tsunami* t, Tick i); + + /** Schedule the RTC periodic interrupt */ + void scheduleIntr(); + + /** Event process to occur at interrupt*/ + virtual void process(); + + /** Event description */ + virtual const char *description(); + }; + + private: + std::string _name; + const std::string &name() const { return _name; } + + /** RTC periodic interrupt event */ + RTCEvent event; + + /** Current RTC register address/index */ + int addr; + + /** Data for real-time clock function */ + union { + uint8_t clock_data[10]; + + struct { + uint8_t sec; + uint8_t sec_alrm; + uint8_t min; + uint8_t min_alrm; + uint8_t hour; + uint8_t hour_alrm; + uint8_t wday; + uint8_t mday; + uint8_t mon; + uint8_t year; + }; + }; + + /** RTC status register A */ + uint8_t stat_regA; + + /** RTC status register B */ + uint8_t stat_regB; + + public: + RTC(const std::string &name, Tsunami* t, Tick i); + + /** Set the initial RTC time/date */ + void set_time(time_t t); + + /** RTC address port: write address of RTC RAM data to access */ + void writeAddr(const uint8_t data); + + /** RTC write data */ + void writeData(const uint8_t data); + + /** RTC read data */ + uint8_t readData(); + + /** + * Serialize this object to the given output stream. + * @param base The base name of the counter object. + * @param os The stream to serialize to. + */ + void serialize(const std::string &base, std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param base The base name of the counter object. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + void unserialize(const std::string &base, Checkpoint *cp, + const std::string §ion); + }; + + /** Programmable Interval Timer (Intel 8254) */ + class PITimer + { + /** Counter element for PIT */ + class Counter + { + /** Event for counter interrupt */ + class CounterEvent : public Event + { + private: + /** Pointer back to Counter */ + Counter* counter; + Tick interval; + + public: + CounterEvent(Counter*); + + /** Event process */ + virtual void process(); + + /** Event description */ + virtual const char *description(); + + friend class Counter; + }; + + private: + std::string _name; + const std::string &name() const { return _name; } + + CounterEvent event; + + /** Current count value */ + uint16_t count; + + /** Latched count */ + uint16_t latched_count; + + /** Interrupt period */ + uint16_t period; + + /** Current mode of operation */ + uint8_t mode; + + /** Output goes high when the counter reaches zero */ + bool output_high; + + /** State of the count latch */ + bool latch_on; + + /** Set of values for read_byte and write_byte */ + enum {LSB, MSB}; + + /** Determine which byte of a 16-bit count value to read/write */ + uint8_t read_byte, write_byte; + + public: + Counter(const std::string &name); + + /** Latch the current count (if one is not already latched) */ + void latchCount(); + + /** Set the read/write mode */ + void setRW(int rw_val); + + /** Set operational mode */ + void setMode(int mode_val); + + /** Set count encoding */ + void setBCD(int bcd_val); + + /** Read a count byte */ + uint8_t read(); + + /** Write a count byte */ + void write(const uint8_t data); + + /** Is the output high? */ + bool outputHigh(); + + /** + * Serialize this object to the given output stream. + * @param base The base name of the counter object. + * @param os The stream to serialize to. + */ + void serialize(const std::string &base, std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param base The base name of the counter object. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + void unserialize(const std::string &base, Checkpoint *cp, + const std::string §ion); + }; + + private: + std::string _name; + const std::string &name() const { return _name; } + + /** PIT has three seperate counters */ + Counter *counter[3]; + + public: + /** Public way to access individual counters (avoid array accesses) */ + Counter counter0; + Counter counter1; + Counter counter2; + + PITimer(const std::string &name); + + /** Write control word */ + void writeControl(const uint8_t data); + + /** + * Serialize this object to the given output stream. + * @param base The base name of the counter object. + * @param os The stream to serialize to. + */ + void serialize(const std::string &base, std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param base The base name of the counter object. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + void unserialize(const std::string &base, Checkpoint *cp, + const std::string §ion); + }; + + /** Mask of the PIC1 */ + uint8_t mask1; + + /** Mask of the PIC2 */ + uint8_t mask2; + + /** Mode of PIC1. Not used for anything */ + uint8_t mode1; + + /** Mode of PIC2. Not used for anything */ + uint8_t mode2; + + /** Raw PIC interrupt register before masking */ + uint8_t picr; //Raw PIC interrput register + + /** Is the pic interrupting right now or not. */ + bool picInterrupting; + + /** A pointer to the Tsunami device which be belong to */ + Tsunami *tsunami; + + /** Intel 8253 Periodic Interval Timer */ + PITimer pitimer; + + RTC rtc; + + /** The interval is set via two writes to the PIT. + * This variable contains a flag as to how many writes have happened, and + * the time so far. + */ + uint16_t timerData; + + public: + /** + * Return the freqency of the RTC + * @return interrupt rate of the RTC + */ + Tick frequency() const; + + struct Params : public BasicPioDevice::Params + { + Tick frequency; + Tsunami *tsunami; + time_t init_time; + }; + protected: + const Params *params() const { return (const Params*)_params; } + + public: + /** + * Initialize all the data for devices supported by Tsunami I/O. + * @param p pointer to Params struct + */ + TsunamiIO(Params *p); + + virtual Tick read(PacketPtr pkt); + virtual Tick write(PacketPtr pkt); + + /** + * Post an PIC interrupt to the CPU via the CChip + * @param bitvector interrupt to post. + */ + void postPIC(uint8_t bitvector); + + /** + * Clear a posted interrupt + * @param bitvector interrupt to clear + */ + void clearPIC(uint8_t bitvector); + + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ + virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + virtual void unserialize(Checkpoint *cp, const std::string §ion); + +}; + +#endif // __DEV_TSUNAMI_IO_HH__ diff --git a/src/dev/alpha/tsunami_pchip.cc b/src/dev/alpha/tsunami_pchip.cc new file mode 100644 index 000000000..94a7f96e5 --- /dev/null +++ b/src/dev/alpha/tsunami_pchip.cc @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2004-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: Ali Saidi + * Andrew Schultz + */ + +/** @file + * Tsunami PChip (pci) + */ + +#include +#include +#include + +#include "base/trace.hh" +#include "dev/alpha/tsunami_pchip.hh" +#include "dev/alpha/tsunamireg.h" +#include "dev/alpha/tsunami.hh" +#include "mem/packet.hh" +#include "mem/packet_access.hh" +#include "sim/builder.hh" +#include "sim/system.hh" + +using namespace std; +//Should this be AlphaISA? +using namespace TheISA; + +TsunamiPChip::TsunamiPChip(Params *p) +: BasicPioDevice(p) +{ + pioSize = 0xfff; + + for (int i = 0; i < 4; i++) { + wsba[i] = 0; + wsm[i] = 0; + tba[i] = 0; + } + + // initialize pchip control register + pctl = (ULL(0x1) << 20) | (ULL(0x1) << 32) | (ULL(0x2) << 36); + + //Set back pointer in tsunami + p->tsunami->pchip = this; +} + +Tick +TsunamiPChip::read(PacketPtr pkt) +{ + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + + pkt->allocate(); + Addr daddr = (pkt->getAddr() - pioAddr) >> 6;; + assert(pkt->getSize() == sizeof(uint64_t)); + + + DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize()); + + switch(daddr) { + case TSDEV_PC_WSBA0: + pkt->set(wsba[0]); + break; + case TSDEV_PC_WSBA1: + pkt->set(wsba[1]); + break; + case TSDEV_PC_WSBA2: + pkt->set(wsba[2]); + break; + case TSDEV_PC_WSBA3: + pkt->set(wsba[3]); + break; + case TSDEV_PC_WSM0: + pkt->set(wsm[0]); + break; + case TSDEV_PC_WSM1: + pkt->set(wsm[1]); + break; + case TSDEV_PC_WSM2: + pkt->set(wsm[2]); + break; + case TSDEV_PC_WSM3: + pkt->set(wsm[3]); + break; + case TSDEV_PC_TBA0: + pkt->set(tba[0]); + break; + case TSDEV_PC_TBA1: + pkt->set(tba[1]); + break; + case TSDEV_PC_TBA2: + pkt->set(tba[2]); + break; + case TSDEV_PC_TBA3: + pkt->set(tba[3]); + break; + case TSDEV_PC_PCTL: + pkt->set(pctl); + break; + case TSDEV_PC_PLAT: + panic("PC_PLAT not implemented\n"); + case TSDEV_PC_RES: + panic("PC_RES not implemented\n"); + case TSDEV_PC_PERROR: + pkt->set((uint64_t)0x00); + break; + case TSDEV_PC_PERRMASK: + pkt->set((uint64_t)0x00); + break; + case TSDEV_PC_PERRSET: + panic("PC_PERRSET not implemented\n"); + case TSDEV_PC_TLBIV: + panic("PC_TLBIV not implemented\n"); + case TSDEV_PC_TLBIA: + pkt->set((uint64_t)0x00); // shouldn't be readable, but linux + break; + case TSDEV_PC_PMONCTL: + panic("PC_PMONCTL not implemented\n"); + case TSDEV_PC_PMONCNT: + panic("PC_PMONCTN not implemented\n"); + default: + panic("Default in PChip Read reached reading 0x%x\n", daddr); + } + pkt->result = Packet::Success; + return pioDelay; + +} + +Tick +TsunamiPChip::write(PacketPtr pkt) +{ + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + Addr daddr = (pkt->getAddr() - pioAddr) >> 6; + + assert(pkt->getSize() == sizeof(uint64_t)); + + DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize()); + + switch(daddr) { + case TSDEV_PC_WSBA0: + wsba[0] = pkt->get(); + break; + case TSDEV_PC_WSBA1: + wsba[1] = pkt->get(); + break; + case TSDEV_PC_WSBA2: + wsba[2] = pkt->get(); + break; + case TSDEV_PC_WSBA3: + wsba[3] = pkt->get(); + break; + case TSDEV_PC_WSM0: + wsm[0] = pkt->get(); + break; + case TSDEV_PC_WSM1: + wsm[1] = pkt->get(); + break; + case TSDEV_PC_WSM2: + wsm[2] = pkt->get(); + break; + case TSDEV_PC_WSM3: + wsm[3] = pkt->get(); + break; + case TSDEV_PC_TBA0: + tba[0] = pkt->get(); + break; + case TSDEV_PC_TBA1: + tba[1] = pkt->get(); + break; + case TSDEV_PC_TBA2: + tba[2] = pkt->get(); + break; + case TSDEV_PC_TBA3: + tba[3] = pkt->get(); + break; + case TSDEV_PC_PCTL: + pctl = pkt->get(); + break; + case TSDEV_PC_PLAT: + panic("PC_PLAT not implemented\n"); + case TSDEV_PC_RES: + panic("PC_RES not implemented\n"); + case TSDEV_PC_PERROR: + break; + case TSDEV_PC_PERRMASK: + panic("PC_PERRMASK not implemented\n"); + case TSDEV_PC_PERRSET: + panic("PC_PERRSET not implemented\n"); + case TSDEV_PC_TLBIV: + panic("PC_TLBIV not implemented\n"); + case TSDEV_PC_TLBIA: + break; // value ignored, supposted to invalidate SG TLB + case TSDEV_PC_PMONCTL: + panic("PC_PMONCTL not implemented\n"); + case TSDEV_PC_PMONCNT: + panic("PC_PMONCTN not implemented\n"); + default: + panic("Default in PChip write reached reading 0x%x\n", daddr); + + } // uint64_t + + pkt->result = Packet::Success; + return pioDelay; +} + +#define DMA_ADDR_MASK ULL(0x3ffffffff) + +Addr +TsunamiPChip::translatePciToDma(Addr busAddr) +{ + // compare the address to the window base registers + uint64_t tbaMask = 0; + uint64_t baMask = 0; + + uint64_t windowMask = 0; + uint64_t windowBase = 0; + + uint64_t pteEntry = 0; + + Addr pteAddr; + Addr dmaAddr; + +#if 0 + DPRINTF(IdeDisk, "Translation for bus address: %#x\n", busAddr); + for (int i = 0; i < 4; i++) { + DPRINTF(IdeDisk, "(%d) base:%#x mask:%#x\n", + i, wsba[i], wsm[i]); + + windowBase = wsba[i]; + windowMask = ~wsm[i] & (ULL(0xfff) << 20); + + if ((busAddr & windowMask) == (windowBase & windowMask)) { + DPRINTF(IdeDisk, "Would have matched %d (wb:%#x wm:%#x --> ba&wm:%#x wb&wm:%#x)\n", + i, windowBase, windowMask, (busAddr & windowMask), + (windowBase & windowMask)); + } + } +#endif + + for (int i = 0; i < 4; i++) { + + windowBase = wsba[i]; + windowMask = ~wsm[i] & (ULL(0xfff) << 20); + + if ((busAddr & windowMask) == (windowBase & windowMask)) { + + if (wsba[i] & 0x1) { // see if enabled + if (wsba[i] & 0x2) { // see if SG bit is set + /** @todo + This currently is faked by just doing a direct + read from memory, however, to be realistic, this + needs to actually do a bus transaction. The process + is explained in the tsunami documentation on page + 10-12 and basically munges the address to look up a + PTE from a table in memory and then uses that mapping + to create an address for the SG page + */ + + tbaMask = ~(((wsm[i] & (ULL(0xfff) << 20)) >> 10) | ULL(0x3ff)); + baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13); + pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10); + + pioPort->readBlob(pteAddr, (uint8_t*)&pteEntry, sizeof(uint64_t)); + + dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff)); + + } else { + baMask = (wsm[i] & (ULL(0xfff) << 20)) | ULL(0xfffff); + tbaMask = ~baMask; + dmaAddr = (tba[i] & tbaMask) | (busAddr & baMask); + } + + return (dmaAddr & DMA_ADDR_MASK); + } + } + } + + // if no match was found, then return the original address + return busAddr; +} +Addr +TsunamiPChip::calcConfigAddr(int bus, int dev, int func) +{ + assert(func < 8); + assert(dev < 32); + assert(bus == 0); + + return TsunamiPciBus0Config | (func << 8) | (dev << 11); +} + + + +void +TsunamiPChip::serialize(std::ostream &os) +{ + SERIALIZE_SCALAR(pctl); + SERIALIZE_ARRAY(wsba, 4); + SERIALIZE_ARRAY(wsm, 4); + SERIALIZE_ARRAY(tba, 4); +} + +void +TsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(pctl); + UNSERIALIZE_ARRAY(wsba, 4); + UNSERIALIZE_ARRAY(wsm, 4); + UNSERIALIZE_ARRAY(tba, 4); +} + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) + + Param pio_addr; + Param pio_latency; + SimObjectParam platform; + SimObjectParam system; + SimObjectParam tsunami; + +END_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) + +BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) + + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object"), + INIT_PARAM(tsunami, "Tsunami") + +END_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) + +CREATE_SIM_OBJECT(TsunamiPChip) +{ + TsunamiPChip::Params *p = new TsunamiPChip::Params; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + p->tsunami = tsunami; + return new TsunamiPChip(p); +} + +REGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip) diff --git a/src/dev/alpha/tsunami_pchip.hh b/src/dev/alpha/tsunami_pchip.hh new file mode 100644 index 000000000..1632a36d4 --- /dev/null +++ b/src/dev/alpha/tsunami_pchip.hh @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2004-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: Ali Saidi + */ + +/** @file + * Tsunami PCI interface CSRs + */ + +#ifndef __TSUNAMI_PCHIP_HH__ +#define __TSUNAMI_PCHIP_HH__ + +#include "dev/alpha/tsunami.hh" +#include "base/range.hh" +#include "dev/io_device.hh" + +/** + * A very simple implementation of the Tsunami PCI interface chips. + */ +class TsunamiPChip : public BasicPioDevice +{ + protected: + + static const Addr TsunamiPciBus0Config = ULL(0x801fe000000); + + /** Pchip control register */ + uint64_t pctl; + + /** Window Base addresses */ + uint64_t wsba[4]; + + /** Window masks */ + uint64_t wsm[4]; + + /** Translated Base Addresses */ + uint64_t tba[4]; + + public: + struct Params : public BasicPioDevice::Params + { + Tsunami *tsunami; + }; + protected: + const Params *params() const { return (const Params*)_params; } + + public: + /** + * Register the PChip with the mmu and init all wsba, wsm, and tba to 0 + * @param p pointer to the parameters struct + */ + TsunamiPChip(Params *p); + + /** + * Translate a PCI bus address to a memory address for DMA. + * @todo Andrew says this needs to be fixed. What's wrong with it? + * @param busAddr PCI address to translate. + * @return memory system address + */ + Addr translatePciToDma(Addr busAddr); + + Addr calcConfigAddr(int bus, int dev, int func); + + virtual Tick read(PacketPtr pkt); + virtual Tick write(PacketPtr pkt); + + /** + * Serialize this object to the given output stream. + * @param os The stream to serialize to. + */ + virtual void serialize(std::ostream &os); + + /** + * Reconstruct the state of this object from a checkpoint. + * @param cp The checkpoint use. + * @param section The section name of this object + */ + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +#endif // __TSUNAMI_PCHIP_HH__ diff --git a/src/dev/alpha/tsunamireg.h b/src/dev/alpha/tsunamireg.h new file mode 100644 index 000000000..d603972be --- /dev/null +++ b/src/dev/alpha/tsunamireg.h @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2004-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: Ali Saidi + */ + +/** @file + * List of Tsunami CSRs + */ + +#ifndef __TSUNAMIREG_H__ +#define __TSUNAMIREG_H__ + +#define ALPHA_K0SEG_BASE ULL(0xfffffc0000000000) + +// CChip Registers +#define TSDEV_CC_CSR 0x00 +#define TSDEV_CC_MTR 0x01 +#define TSDEV_CC_MISC 0x02 + +#define TSDEV_CC_AAR0 0x04 +#define TSDEV_CC_AAR1 0x05 +#define TSDEV_CC_AAR2 0x06 +#define TSDEV_CC_AAR3 0x07 +#define TSDEV_CC_DIM0 0x08 +#define TSDEV_CC_DIM1 0x09 +#define TSDEV_CC_DIR0 0x0A +#define TSDEV_CC_DIR1 0x0B +#define TSDEV_CC_DRIR 0x0C +#define TSDEV_CC_PRBEN 0x0D +#define TSDEV_CC_IIC0 0x0E +#define TSDEV_CC_IIC1 0x0F +#define TSDEV_CC_MPR0 0x10 +#define TSDEV_CC_MPR1 0x11 +#define TSDEV_CC_MPR2 0x12 +#define TSDEV_CC_MPR3 0x13 + +#define TSDEV_CC_DIM2 0x18 +#define TSDEV_CC_DIM3 0x19 +#define TSDEV_CC_DIR2 0x1A +#define TSDEV_CC_DIR3 0x1B +#define TSDEV_CC_IIC2 0x1C +#define TSDEV_CC_IIC3 0x1D + +// BigTsunami Registers +#define TSDEV_CC_BDIMS 0x1000000 +#define TSDEV_CC_BDIRS 0x2000000 +#define TSDEV_CC_IPIQ 0x20 //0xf01a000800 +#define TSDEV_CC_IPIR 0x21 //0xf01a000840 +#define TSDEV_CC_ITIR 0x22 //0xf01a000880 + + +// PChip Registers +#define TSDEV_PC_WSBA0 0x00 +#define TSDEV_PC_WSBA1 0x01 +#define TSDEV_PC_WSBA2 0x02 +#define TSDEV_PC_WSBA3 0x03 +#define TSDEV_PC_WSM0 0x04 +#define TSDEV_PC_WSM1 0x05 +#define TSDEV_PC_WSM2 0x06 +#define TSDEV_PC_WSM3 0x07 +#define TSDEV_PC_TBA0 0x08 +#define TSDEV_PC_TBA1 0x09 +#define TSDEV_PC_TBA2 0x0A +#define TSDEV_PC_TBA3 0x0B +#define TSDEV_PC_PCTL 0x0C +#define TSDEV_PC_PLAT 0x0D +#define TSDEV_PC_RES 0x0E +#define TSDEV_PC_PERROR 0x0F +#define TSDEV_PC_PERRMASK 0x10 +#define TSDEV_PC_PERRSET 0x11 +#define TSDEV_PC_TLBIV 0x12 +#define TSDEV_PC_TLBIA 0x13 +#define TSDEV_PC_PMONCTL 0x14 +#define TSDEV_PC_PMONCNT 0x15 + +#define TSDEV_PC_SPST 0x20 + + +// DChip Registers +#define TSDEV_DC_DSC 0x20 +#define TSDEV_DC_STR 0x21 +#define TSDEV_DC_DREV 0x22 +#define TSDEV_DC_DSC2 0x23 + +// I/O Ports +#define TSDEV_PIC1_MASK 0x21 +#define TSDEV_PIC2_MASK 0xA1 +#define TSDEV_PIC1_ISR 0x20 +#define TSDEV_PIC2_ISR 0xA0 +#define TSDEV_PIC1_ACK 0x20 +#define TSDEV_PIC2_ACK 0xA0 +#define TSDEV_DMA1_RESET 0x0D +#define TSDEV_DMA2_RESET 0xDA +#define TSDEV_DMA1_MODE 0x0B +#define TSDEV_DMA2_MODE 0xD6 +#define TSDEV_DMA1_MASK 0x0A +#define TSDEV_DMA2_MASK 0xD4 +#define TSDEV_CTRL_PORTB 0x61 +#define TSDEV_TMR0_DATA 0x40 +#define TSDEV_TMR1_DATA 0x41 +#define TSDEV_TMR2_DATA 0x42 +#define TSDEV_TMR_CTRL 0x43 +#define TSDEV_KBD 0x64 +#define TSDEV_DMA1_CMND 0x08 +#define TSDEV_DMA1_STAT TSDEV_DMA1_CMND +#define TSDEV_DMA2_CMND 0xD0 +#define TSDEV_DMA2_STAT TSDEV_DMA2_CMND +#define TSDEV_DMA1_MMASK 0x0F +#define TSDEV_DMA2_MMASK 0xDE + +/* Added for keyboard accesses */ +#define TSDEV_KBD 0x64 + +/* Added for ATA PCI DMA */ +#define ATA_PCI_DMA 0x00 +#define ATA_PCI_DMA2 0x02 +#define ATA_PCI_DMA3 0x16 +#define ATA_PCI_DMA4 0x17 +#define ATA_PCI_DMA5 0x1a +#define ATA_PCI_DMA6 0x11 +#define ATA_PCI_DMA7 0x14 + +#define TSDEV_RTC_ADDR 0x70 +#define TSDEV_RTC_DATA 0x71 + +#define PCHIP_PCI0_MEMORY ULL(0x00000000000) +#define PCHIP_PCI0_IO ULL(0x001FC000000) +#define TSUNAMI_UNCACHABLE_BIT ULL(0x80000000000) +#define TSUNAMI_PCI0_MEMORY TSUNAMI_UNCACHABLE_BIT + PCHIP_PCI0_MEMORY +#define TSUNAMI_PCI0_IO TSUNAMI_UNCACHABLE_BIT + PCHIP_PCI0_IO + + +// UART Defines +#define UART_IER_RDI 0x01 +#define UART_IER_THRI 0x02 +#define UART_IER_RLSI 0x04 + + +#define UART_LSR_TEMT 0x40 +#define UART_LSR_THRE 0x20 +#define UART_LSR_DR 0x01 + +#define UART_MCR_LOOP 0x10 + +// System Control PortB Status Bits +#define PORTB_SPKR_HIGH 0x20 + +#endif // __TSUNAMIREG_H__ diff --git a/src/dev/ide_disk.cc b/src/dev/ide_disk.cc index 5d3346b1e..5083c9c8d 100644 --- a/src/dev/ide_disk.cc +++ b/src/dev/ide_disk.cc @@ -44,8 +44,8 @@ #include "dev/disk_image.hh" #include "dev/ide_disk.hh" #include "dev/ide_ctrl.hh" -#include "dev/tsunami.hh" -#include "dev/tsunami_pchip.hh" +#include "dev/alpha/tsunami.hh" +#include "dev/alpha/tsunami_pchip.hh" #include "sim/builder.hh" #include "sim/sim_object.hh" #include "sim/root.hh" diff --git a/src/dev/isa_fake.hh b/src/dev/isa_fake.hh index 6665f1a78..c781d1ba6 100644 --- a/src/dev/isa_fake.hh +++ b/src/dev/isa_fake.hh @@ -38,7 +38,7 @@ #include "base/range.hh" #include "dev/io_device.hh" -#include "dev/tsunami.hh" +#include "dev/alpha/tsunami.hh" #include "mem/packet.hh" /** diff --git a/src/dev/pcidev.cc b/src/dev/pcidev.cc index 8c0d03817..383fc494f 100644 --- a/src/dev/pcidev.cc +++ b/src/dev/pcidev.cc @@ -45,7 +45,7 @@ #include "base/trace.hh" #include "dev/pciconfigall.hh" #include "dev/pcidev.hh" -#include "dev/tsunamireg.h" +#include "dev/alpha/tsunamireg.h" #include "mem/packet.hh" #include "mem/packet_access.hh" #include "sim/builder.hh" diff --git a/src/dev/tsunami.cc b/src/dev/tsunami.cc deleted file mode 100644 index 8e740a72f..000000000 --- a/src/dev/tsunami.cc +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2004-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: Ali Saidi - */ - -/** @file - * Implementation of Tsunami platform. - */ - -#include -#include -#include - -#include "cpu/intr_control.hh" -#include "dev/simconsole.hh" -#include "dev/tsunami_cchip.hh" -#include "dev/tsunami_pchip.hh" -#include "dev/tsunami_io.hh" -#include "dev/tsunami.hh" -#include "sim/builder.hh" -#include "sim/system.hh" - -using namespace std; -//Should this be AlphaISA? -using namespace TheISA; - -Tsunami::Tsunami(const string &name, System *s, IntrControl *ic) - : Platform(name, ic), system(s) -{ - // set the back pointer from the system to myself - system->platform = this; - - for (int i = 0; i < Tsunami::Max_CPUs; i++) - intr_sum_type[i] = 0; -} - -Tick -Tsunami::intrFrequency() -{ - return io->frequency(); -} - -void -Tsunami::postConsoleInt() -{ - io->postPIC(0x10); -} - -void -Tsunami::clearConsoleInt() -{ - io->clearPIC(0x10); -} - -void -Tsunami::postPciInt(int line) -{ - cchip->postDRIR(line); -} - -void -Tsunami::clearPciInt(int line) -{ - cchip->clearDRIR(line); -} - -Addr -Tsunami::pciToDma(Addr pciAddr) const -{ - return pchip->translatePciToDma(pciAddr); -} - - -Addr -Tsunami::calcConfigAddr(int bus, int dev, int func) -{ - return pchip->calcConfigAddr(bus, dev, func); -} - -void -Tsunami::serialize(std::ostream &os) -{ - SERIALIZE_ARRAY(intr_sum_type, Tsunami::Max_CPUs); -} - -void -Tsunami::unserialize(Checkpoint *cp, const std::string §ion) -{ - UNSERIALIZE_ARRAY(intr_sum_type, Tsunami::Max_CPUs); -} - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tsunami) - - SimObjectParam system; - SimObjectParam intrctrl; - -END_DECLARE_SIM_OBJECT_PARAMS(Tsunami) - -BEGIN_INIT_SIM_OBJECT_PARAMS(Tsunami) - - INIT_PARAM(system, "system"), - INIT_PARAM(intrctrl, "interrupt controller") - -END_INIT_SIM_OBJECT_PARAMS(Tsunami) - -CREATE_SIM_OBJECT(Tsunami) -{ - return new Tsunami(getInstanceName(), system, intrctrl); -} - -REGISTER_SIM_OBJECT("Tsunami", Tsunami) diff --git a/src/dev/tsunami.hh b/src/dev/tsunami.hh deleted file mode 100644 index 6fbfac851..000000000 --- a/src/dev/tsunami.hh +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2004-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: Ali Saidi - */ - -/** - * @file - * Declaration of top level class for the Tsunami chipset. This class just - * retains pointers to all its children so the children can communicate. - */ - -#ifndef __DEV_TSUNAMI_HH__ -#define __DEV_TSUNAMI_HH__ - -#include "dev/platform.hh" - -class IdeController; -class TsunamiCChip; -class TsunamiPChip; -class TsunamiIO; -class System; - -/** - * Top level class for Tsunami Chipset emulation. - * This structure just contains pointers to all the - * children so the children can commnicate to do the - * read work - */ - -class Tsunami : public Platform -{ - public: - /** Max number of CPUs in a Tsunami */ - static const int Max_CPUs = 64; - - /** Pointer to the system */ - System *system; - - /** Pointer to the TsunamiIO device which has the RTC */ - TsunamiIO *io; - - /** Pointer to the Tsunami CChip. - * The chip contains some configuration information and - * all the interrupt mask and status registers - */ - TsunamiCChip *cchip; - - /** Pointer to the Tsunami PChip. - * The pchip is the interface to the PCI bus, in our case - * it does not have to do much. - */ - TsunamiPChip *pchip; - - int intr_sum_type[Tsunami::Max_CPUs]; - int ipi_pending[Tsunami::Max_CPUs]; - - public: - /** - * Constructor for the Tsunami Class. - * @param name name of the object - * @param s system the object belongs to - * @param intctrl pointer to the interrupt controller - */ - Tsunami(const std::string &name, System *s, IntrControl *intctrl); - - /** - * Return the interrupting frequency to AlphaAccess - * @return frequency of RTC interrupts - */ - virtual Tick intrFrequency(); - - /** - * Cause the cpu to post a serial interrupt to the CPU. - */ - virtual void postConsoleInt(); - - /** - * Clear a posted CPU interrupt (id=55) - */ - virtual void clearConsoleInt(); - - /** - * Cause the chipset to post a cpi interrupt to the CPU. - */ - virtual void postPciInt(int line); - - /** - * Clear a posted PCI->CPU interrupt - */ - virtual void clearPciInt(int line); - - - virtual Addr pciToDma(Addr pciAddr) const; - - /** - * Calculate the configuration address given a bus/dev/func. - */ - virtual Addr calcConfigAddr(int bus, int dev, int func); - - /** - * Serialize this object to the given output stream. - * @param os The stream to serialize to. - */ - virtual void serialize(std::ostream &os); - - /** - * Reconstruct the state of this object from a checkpoint. - * @param cp The checkpoint use. - * @param section The section name of this object - */ - virtual void unserialize(Checkpoint *cp, const std::string §ion); -}; - -#endif // __DEV_TSUNAMI_HH__ diff --git a/src/dev/tsunami_cchip.cc b/src/dev/tsunami_cchip.cc deleted file mode 100644 index 74a68566c..000000000 --- a/src/dev/tsunami_cchip.cc +++ /dev/null @@ -1,555 +0,0 @@ -/* - * Copyright (c) 2004-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: Ali Saidi - * Ron Dreslinski - */ - -/** @file - * Emulation of the Tsunami CChip CSRs - */ - -#include -#include -#include - -#include "arch/alpha/ev5.hh" -#include "base/trace.hh" -#include "cpu/intr_control.hh" -#include "cpu/thread_context.hh" -#include "dev/tsunami.hh" -#include "dev/tsunami_cchip.hh" -#include "dev/tsunamireg.h" -#include "mem/packet.hh" -#include "mem/packet_access.hh" -#include "mem/port.hh" -#include "sim/builder.hh" -#include "sim/system.hh" - -using namespace std; -//Should this be AlphaISA? -using namespace TheISA; - -TsunamiCChip::TsunamiCChip(Params *p) - : BasicPioDevice(p), tsunami(p->tsunami) -{ - pioSize = 0xfffffff; - - drir = 0; - ipint = 0; - itint = 0; - - for (int x = 0; x < Tsunami::Max_CPUs; x++) - { - dim[x] = 0; - dir[x] = 0; - } - - //Put back pointer in tsunami - tsunami->cchip = this; -} - -Tick -TsunamiCChip::read(PacketPtr pkt) -{ - DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize()); - - assert(pkt->result == Packet::Unknown); - assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - - Addr regnum = (pkt->getAddr() - pioAddr) >> 6; - Addr daddr = (pkt->getAddr() - pioAddr); - - pkt->allocate(); - switch (pkt->getSize()) { - - case sizeof(uint64_t): - if (daddr & TSDEV_CC_BDIMS) - { - pkt->set(dim[(daddr >> 4) & 0x3F]); - break; - } - - if (daddr & TSDEV_CC_BDIRS) - { - pkt->set(dir[(daddr >> 4) & 0x3F]); - break; - } - - switch(regnum) { - case TSDEV_CC_CSR: - pkt->set(0x0); - break; - case TSDEV_CC_MTR: - panic("TSDEV_CC_MTR not implemeted\n"); - break; - case TSDEV_CC_MISC: - pkt->set((ipint << 8) & 0xF | (itint << 4) & 0xF | - (pkt->req->getCpuNum() & 0x3)); - break; - case TSDEV_CC_AAR0: - case TSDEV_CC_AAR1: - case TSDEV_CC_AAR2: - case TSDEV_CC_AAR3: - pkt->set(0); - break; - case TSDEV_CC_DIM0: - pkt->set(dim[0]); - break; - case TSDEV_CC_DIM1: - pkt->set(dim[1]); - break; - case TSDEV_CC_DIM2: - pkt->set(dim[2]); - break; - case TSDEV_CC_DIM3: - pkt->set(dim[3]); - break; - case TSDEV_CC_DIR0: - pkt->set(dir[0]); - break; - case TSDEV_CC_DIR1: - pkt->set(dir[1]); - break; - case TSDEV_CC_DIR2: - pkt->set(dir[2]); - break; - case TSDEV_CC_DIR3: - pkt->set(dir[3]); - break; - case TSDEV_CC_DRIR: - pkt->set(drir); - break; - case TSDEV_CC_PRBEN: - panic("TSDEV_CC_PRBEN not implemented\n"); - break; - case TSDEV_CC_IIC0: - case TSDEV_CC_IIC1: - case TSDEV_CC_IIC2: - case TSDEV_CC_IIC3: - panic("TSDEV_CC_IICx not implemented\n"); - break; - case TSDEV_CC_MPR0: - case TSDEV_CC_MPR1: - case TSDEV_CC_MPR2: - case TSDEV_CC_MPR3: - panic("TSDEV_CC_MPRx not implemented\n"); - break; - case TSDEV_CC_IPIR: - pkt->set(ipint); - break; - case TSDEV_CC_ITIR: - pkt->set(itint); - break; - default: - panic("default in cchip read reached, accessing 0x%x\n"); - } // uint64_t - - break; - case sizeof(uint32_t): - case sizeof(uint16_t): - case sizeof(uint8_t): - default: - panic("invalid access size(?) for tsunami register!\n"); - } - DPRINTF(Tsunami, "Tsunami CChip: read regnum=%#x size=%d data=%lld\n", - regnum, pkt->getSize(), pkt->get()); - - pkt->result = Packet::Success; - return pioDelay; -} - -Tick -TsunamiCChip::write(PacketPtr pkt) -{ - assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - Addr daddr = pkt->getAddr() - pioAddr; - Addr regnum = (pkt->getAddr() - pioAddr) >> 6 ; - - - assert(pkt->getSize() == sizeof(uint64_t)); - - DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt->getAddr(), pkt->get()); - - bool supportedWrite = false; - - - if (daddr & TSDEV_CC_BDIMS) - { - int number = (daddr >> 4) & 0x3F; - - uint64_t bitvector; - uint64_t olddim; - uint64_t olddir; - - olddim = dim[number]; - olddir = dir[number]; - dim[number] = pkt->get(); - dir[number] = dim[number] & drir; - for(int x = 0; x < Tsunami::Max_CPUs; x++) - { - bitvector = ULL(1) << x; - // Figure out which bits have changed - if ((dim[number] & bitvector) != (olddim & bitvector)) - { - // The bit is now set and it wasn't before (set) - if((dim[number] & bitvector) && (dir[number] & bitvector)) - { - tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "dim write resulting in posting dir" - " interrupt to cpu %d\n", number); - } - else if ((olddir & bitvector) && - !(dir[number] & bitvector)) - { - // The bit was set and now its now clear and - // we were interrupting on that bit before - tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "dim write resulting in clear" - " dir interrupt to cpu %d\n", number); - - } - - - } - } - } else { - switch(regnum) { - case TSDEV_CC_CSR: - panic("TSDEV_CC_CSR write\n"); - case TSDEV_CC_MTR: - panic("TSDEV_CC_MTR write not implemented\n"); - case TSDEV_CC_MISC: - uint64_t ipreq; - ipreq = (pkt->get() >> 12) & 0xF; - //If it is bit 12-15, this is an IPI post - if (ipreq) { - reqIPI(ipreq); - supportedWrite = true; - } - - //If it is bit 8-11, this is an IPI clear - uint64_t ipintr; - ipintr = (pkt->get() >> 8) & 0xF; - if (ipintr) { - clearIPI(ipintr); - supportedWrite = true; - } - - //If it is the 4-7th bit, clear the RTC interrupt - uint64_t itintr; - itintr = (pkt->get() >> 4) & 0xF; - if (itintr) { - clearITI(itintr); - supportedWrite = true; - } - - // ignore NXMs - if (pkt->get() & 0x10000000) - supportedWrite = true; - - if(!supportedWrite) - panic("TSDEV_CC_MISC write not implemented\n"); - - break; - case TSDEV_CC_AAR0: - case TSDEV_CC_AAR1: - case TSDEV_CC_AAR2: - case TSDEV_CC_AAR3: - panic("TSDEV_CC_AARx write not implemeted\n"); - case TSDEV_CC_DIM0: - case TSDEV_CC_DIM1: - case TSDEV_CC_DIM2: - case TSDEV_CC_DIM3: - int number; - if(regnum == TSDEV_CC_DIM0) - number = 0; - else if(regnum == TSDEV_CC_DIM1) - number = 1; - else if(regnum == TSDEV_CC_DIM2) - number = 2; - else - number = 3; - - uint64_t bitvector; - uint64_t olddim; - uint64_t olddir; - - olddim = dim[number]; - olddir = dir[number]; - dim[number] = pkt->get(); - dir[number] = dim[number] & drir; - for(int x = 0; x < 64; x++) - { - bitvector = ULL(1) << x; - // Figure out which bits have changed - if ((dim[number] & bitvector) != (olddim & bitvector)) - { - // The bit is now set and it wasn't before (set) - if((dim[number] & bitvector) && (dir[number] & bitvector)) - { - tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); - } - else if ((olddir & bitvector) && - !(dir[number] & bitvector)) - { - // The bit was set and now its now clear and - // we were interrupting on that bit before - tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "dim write resulting in clear" - " dir interrupt to cpu %d\n", - x); - - } - - - } - } - break; - case TSDEV_CC_DIR0: - case TSDEV_CC_DIR1: - case TSDEV_CC_DIR2: - case TSDEV_CC_DIR3: - panic("TSDEV_CC_DIR write not implemented\n"); - case TSDEV_CC_DRIR: - panic("TSDEV_CC_DRIR write not implemented\n"); - case TSDEV_CC_PRBEN: - panic("TSDEV_CC_PRBEN write not implemented\n"); - case TSDEV_CC_IIC0: - case TSDEV_CC_IIC1: - case TSDEV_CC_IIC2: - case TSDEV_CC_IIC3: - panic("TSDEV_CC_IICx write not implemented\n"); - case TSDEV_CC_MPR0: - case TSDEV_CC_MPR1: - case TSDEV_CC_MPR2: - case TSDEV_CC_MPR3: - panic("TSDEV_CC_MPRx write not implemented\n"); - case TSDEV_CC_IPIR: - clearIPI(pkt->get()); - break; - case TSDEV_CC_ITIR: - clearITI(pkt->get()); - break; - case TSDEV_CC_IPIQ: - reqIPI(pkt->get()); - break; - default: - panic("default in cchip read reached, accessing 0x%x\n"); - } // swtich(regnum) - } // not BIG_TSUNAMI write - pkt->result = Packet::Success; - return pioDelay; -} - -void -TsunamiCChip::clearIPI(uint64_t ipintr) -{ - int numcpus = tsunami->intrctrl->cpu->system->threadContexts.size(); - assert(numcpus <= Tsunami::Max_CPUs); - - if (ipintr) { - for (int cpunum=0; cpunum < numcpus; cpunum++) { - // Check each cpu bit - uint64_t cpumask = ULL(1) << cpunum; - if (ipintr & cpumask) { - // Check if there is a pending ipi - if (ipint & cpumask) { - ipint &= ~cpumask; - tsunami->intrctrl->clear(cpunum, TheISA::INTLEVEL_IRQ3, 0); - DPRINTF(IPI, "clear IPI IPI cpu=%d\n", cpunum); - } - else - warn("clear IPI for CPU=%d, but NO IPI\n", cpunum); - } - } - } - else - panic("Big IPI Clear, but not processors indicated\n"); -} - -void -TsunamiCChip::clearITI(uint64_t itintr) -{ - int numcpus = tsunami->intrctrl->cpu->system->threadContexts.size(); - assert(numcpus <= Tsunami::Max_CPUs); - - if (itintr) { - for (int i=0; i < numcpus; i++) { - uint64_t cpumask = ULL(1) << i; - if (itintr & cpumask & itint) { - tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ2, 0); - itint &= ~cpumask; - DPRINTF(Tsunami, "clearing rtc interrupt to cpu=%d\n", i); - } - } - } - else - panic("Big ITI Clear, but not processors indicated\n"); -} - -void -TsunamiCChip::reqIPI(uint64_t ipreq) -{ - int numcpus = tsunami->intrctrl->cpu->system->threadContexts.size(); - assert(numcpus <= Tsunami::Max_CPUs); - - if (ipreq) { - for (int cpunum=0; cpunum < numcpus; cpunum++) { - // Check each cpu bit - uint64_t cpumask = ULL(1) << cpunum; - if (ipreq & cpumask) { - // Check if there is already an ipi (bits 8:11) - if (!(ipint & cpumask)) { - ipint |= cpumask; - tsunami->intrctrl->post(cpunum, TheISA::INTLEVEL_IRQ3, 0); - DPRINTF(IPI, "send IPI cpu=%d\n", cpunum); - } - else - warn("post IPI for CPU=%d, but IPI already\n", cpunum); - } - } - } - else - panic("Big IPI Request, but not processors indicated\n"); -} - - -void -TsunamiCChip::postRTC() -{ - int size = tsunami->intrctrl->cpu->system->threadContexts.size(); - assert(size <= Tsunami::Max_CPUs); - - for (int i = 0; i < size; i++) { - uint64_t cpumask = ULL(1) << i; - if (!(cpumask & itint)) { - itint |= cpumask; - tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0); - DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i); - } - } - -} - -void -TsunamiCChip::postDRIR(uint32_t interrupt) -{ - uint64_t bitvector = ULL(1) << interrupt; - uint64_t size = tsunami->intrctrl->cpu->system->threadContexts.size(); - assert(size <= Tsunami::Max_CPUs); - drir |= bitvector; - - for(int i=0; i < size; i++) { - dir[i] = dim[i] & drir; - if (dim[i] & bitvector) { - tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt); - DPRINTF(Tsunami, "posting dir interrupt to cpu %d," - "interrupt %d\n",i, interrupt); - } - } -} - -void -TsunamiCChip::clearDRIR(uint32_t interrupt) -{ - uint64_t bitvector = ULL(1) << interrupt; - uint64_t size = tsunami->intrctrl->cpu->system->threadContexts.size(); - assert(size <= Tsunami::Max_CPUs); - - if (drir & bitvector) - { - drir &= ~bitvector; - for(int i=0; i < size; i++) { - if (dir[i] & bitvector) { - tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt); - DPRINTF(Tsunami, "clearing dir interrupt to cpu %d," - "interrupt %d\n",i, interrupt); - - } - dir[i] = dim[i] & drir; - } - } - else - DPRINTF(Tsunami, "Spurrious clear? interrupt %d\n", interrupt); -} - - -void -TsunamiCChip::serialize(std::ostream &os) -{ - SERIALIZE_ARRAY(dim, Tsunami::Max_CPUs); - SERIALIZE_ARRAY(dir, Tsunami::Max_CPUs); - SERIALIZE_SCALAR(ipint); - SERIALIZE_SCALAR(itint); - SERIALIZE_SCALAR(drir); -} - -void -TsunamiCChip::unserialize(Checkpoint *cp, const std::string §ion) -{ - UNSERIALIZE_ARRAY(dim, Tsunami::Max_CPUs); - UNSERIALIZE_ARRAY(dir, Tsunami::Max_CPUs); - UNSERIALIZE_SCALAR(ipint); - UNSERIALIZE_SCALAR(itint); - UNSERIALIZE_SCALAR(drir); -} - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) - - Param pio_addr; - Param pio_latency; - SimObjectParam platform; - SimObjectParam system; - SimObjectParam tsunami; - -END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) - -BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) - - INIT_PARAM(pio_addr, "Device Address"), - INIT_PARAM(pio_latency, "Programmed IO latency"), - INIT_PARAM(platform, "platform"), - INIT_PARAM(system, "system object"), - INIT_PARAM(tsunami, "Tsunami") - -END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) - -CREATE_SIM_OBJECT(TsunamiCChip) -{ - TsunamiCChip::Params *p = new TsunamiCChip::Params; - p->name = getInstanceName(); - p->pio_addr = pio_addr; - p->pio_delay = pio_latency; - p->platform = platform; - p->system = system; - p->tsunami = tsunami; - return new TsunamiCChip(p); -} - -REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip) diff --git a/src/dev/tsunami_cchip.hh b/src/dev/tsunami_cchip.hh deleted file mode 100644 index 297a94129..000000000 --- a/src/dev/tsunami_cchip.hh +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2004-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: Ali Saidi - */ - -/** @file - * Emulation of the Tsunami CChip CSRs - */ - -#ifndef __TSUNAMI_CCHIP_HH__ -#define __TSUNAMI_CCHIP_HH__ - -#include "dev/tsunami.hh" -#include "base/range.hh" -#include "dev/io_device.hh" - - -/** - * Tsunami CChip CSR Emulation. This device includes all the interrupt - * handling code for the chipset. - */ -class TsunamiCChip : public BasicPioDevice -{ - protected: - /** - * pointer to the tsunami object. - * This is our access to all the other tsunami - * devices. - */ - Tsunami *tsunami; - - /** - * The dims are device interrupt mask registers. - * One exists for each CPU, the DRIR X DIM = DIR - */ - uint64_t dim[Tsunami::Max_CPUs]; - - /** - * The dirs are device interrupt registers. - * One exists for each CPU, the DRIR X DIM = DIR - */ - uint64_t dir[Tsunami::Max_CPUs]; - - /** - * This register contains bits for each PCI interrupt - * that can occur. - */ - uint64_t drir; - - /** Indicator of which CPUs have an IPI interrupt */ - uint64_t ipint; - - /** Indicator of which CPUs have an RTC interrupt */ - uint64_t itint; - - public: - struct Params : public BasicPioDevice::Params - { - Tsunami *tsunami; - }; - protected: - const Params *params() const {return (const Params *)_params; } - - public: - /** - * Initialize the Tsunami CChip by setting all of the - * device register to 0. - * @param p params struct - */ - TsunamiCChip(Params *p); - - virtual Tick read(PacketPtr pkt); - - virtual Tick write(PacketPtr pkt); - - /** - * post an RTC interrupt to the CPU - */ - void postRTC(); - - /** - * post an interrupt to the CPU. - * @param interrupt the interrupt number to post (0-64) - */ - void postDRIR(uint32_t interrupt); - - /** - * clear an interrupt previously posted to the CPU. - * @param interrupt the interrupt number to post (0-64) - */ - void clearDRIR(uint32_t interrupt); - - /** - * post an ipi interrupt to the CPU. - * @param ipintr the cpu number to clear(bitvector) - */ - void clearIPI(uint64_t ipintr); - - /** - * clear a timer interrupt previously posted to the CPU. - * @param itintr the cpu number to clear(bitvector) - */ - void clearITI(uint64_t itintr); - - /** - * request an interrupt be posted to the CPU. - * @param ipreq the cpu number to interrupt(bitvector) - */ - void reqIPI(uint64_t ipreq); - - - /** - * Serialize this object to the given output stream. - * @param os The stream to serialize to. - */ - virtual void serialize(std::ostream &os); - - /** - * Reconstruct the state of this object from a checkpoint. - * @param cp The checkpoint use. - * @param section The section name of this object - */ - virtual void unserialize(Checkpoint *cp, const std::string §ion); - -}; - -#endif // __TSUNAMI_CCHIP_HH__ diff --git a/src/dev/tsunami_io.cc b/src/dev/tsunami_io.cc deleted file mode 100644 index 73af6c2ef..000000000 --- a/src/dev/tsunami_io.cc +++ /dev/null @@ -1,688 +0,0 @@ -/* - * Copyright (c) 2004-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: Ali Saidi - * Andrew Schultz - * Miguel Serrano - */ - -/** @file - * Tsunami I/O including PIC, PIT, RTC, DMA - */ - -#include - -#include -#include -#include - -#include "base/trace.hh" -#include "dev/pitreg.h" -#include "dev/rtcreg.h" -#include "dev/tsunami_cchip.hh" -#include "dev/tsunami.hh" -#include "dev/tsunami_io.hh" -#include "dev/tsunamireg.h" -#include "mem/packet.hh" -#include "mem/packet_access.hh" -#include "mem/port.hh" -#include "sim/builder.hh" -#include "sim/system.hh" - -using namespace std; -//Should this be AlphaISA? -using namespace TheISA; - -TsunamiIO::RTC::RTC(const string &name, Tsunami* t, Tick i) - : _name(name), event(t, i), addr(0) -{ - memset(clock_data, 0, sizeof(clock_data)); - stat_regA = RTCA_32768HZ | RTCA_1024HZ; - stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR; -} - -void -TsunamiIO::RTC::set_time(time_t t) -{ - struct tm tm; - gmtime_r(&t, &tm); - - sec = tm.tm_sec; - min = tm.tm_min; - hour = tm.tm_hour; - wday = tm.tm_wday + 1; - mday = tm.tm_mday; - mon = tm.tm_mon + 1; - year = tm.tm_year; - - DPRINTFN("Real-time clock set to %s", asctime(&tm)); -} - -void -TsunamiIO::RTC::writeAddr(const uint8_t data) -{ - if (data <= RTC_STAT_REGD) - addr = data; - else - panic("RTC addresses over 0xD are not implemented.\n"); -} - -void -TsunamiIO::RTC::writeData(const uint8_t data) -{ - if (addr < RTC_STAT_REGA) - clock_data[addr] = data; - else { - switch (addr) { - case RTC_STAT_REGA: - if (data != (RTCA_32768HZ | RTCA_1024HZ)) - panic("Unimplemented RTC register A value write!\n"); - stat_regA = data; - break; - case RTC_STAT_REGB: - if ((data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR)) - panic("Write to RTC reg B bits that are not implemented!\n"); - - if (data & RTCB_PRDC_IE) { - if (!event.scheduled()) - event.scheduleIntr(); - } else { - if (event.scheduled()) - event.deschedule(); - } - stat_regB = data; - break; - case RTC_STAT_REGC: - case RTC_STAT_REGD: - panic("RTC status registers C and D are not implemented.\n"); - break; - } - } -} - -uint8_t -TsunamiIO::RTC::readData() -{ - if (addr < RTC_STAT_REGA) - return clock_data[addr]; - else { - switch (addr) { - case RTC_STAT_REGA: - // toggle UIP bit for linux - stat_regA ^= RTCA_UIP; - return stat_regA; - break; - case RTC_STAT_REGB: - return stat_regB; - break; - case RTC_STAT_REGC: - case RTC_STAT_REGD: - return 0x00; - break; - default: - panic("Shouldn't be here"); - } - } -} - -void -TsunamiIO::RTC::serialize(const string &base, ostream &os) -{ - paramOut(os, base + ".addr", addr); - arrayParamOut(os, base + ".clock_data", clock_data, sizeof(clock_data)); - paramOut(os, base + ".stat_regA", stat_regA); - paramOut(os, base + ".stat_regB", stat_regB); -} - -void -TsunamiIO::RTC::unserialize(const string &base, Checkpoint *cp, - const string §ion) -{ - paramIn(cp, section, base + ".addr", addr); - arrayParamIn(cp, section, base + ".clock_data", clock_data, - sizeof(clock_data)); - paramIn(cp, section, base + ".stat_regA", stat_regA); - paramIn(cp, section, base + ".stat_regB", stat_regB); - - // We're not unserializing the event here, but we need to - // rescehedule the event since curTick was moved forward by the - // checkpoint - event.reschedule(curTick + event.interval); -} - -TsunamiIO::RTC::RTCEvent::RTCEvent(Tsunami*t, Tick i) - : Event(&mainEventQueue), tsunami(t), interval(i) -{ - DPRINTF(MC146818, "RTC Event Initilizing\n"); - schedule(curTick + interval); -} - -void -TsunamiIO::RTC::RTCEvent::scheduleIntr() -{ - schedule(curTick + interval); -} - -void -TsunamiIO::RTC::RTCEvent::process() -{ - DPRINTF(MC146818, "RTC Timer Interrupt\n"); - schedule(curTick + interval); - //Actually interrupt the processor here - tsunami->cchip->postRTC(); -} - -const char * -TsunamiIO::RTC::RTCEvent::description() -{ - return "tsunami RTC interrupt"; -} - -TsunamiIO::PITimer::PITimer(const string &name) - : _name(name), counter0(name + ".counter0"), counter1(name + ".counter1"), - counter2(name + ".counter2") -{ - counter[0] = &counter0; - counter[1] = &counter0; - counter[2] = &counter0; -} - -void -TsunamiIO::PITimer::writeControl(const uint8_t data) -{ - int rw; - int sel; - - sel = GET_CTRL_SEL(data); - - if (sel == PIT_READ_BACK) - panic("PITimer Read-Back Command is not implemented.\n"); - - rw = GET_CTRL_RW(data); - - if (rw == PIT_RW_LATCH_COMMAND) - counter[sel]->latchCount(); - else { - counter[sel]->setRW(rw); - counter[sel]->setMode(GET_CTRL_MODE(data)); - counter[sel]->setBCD(GET_CTRL_BCD(data)); - } -} - -void -TsunamiIO::PITimer::serialize(const string &base, ostream &os) -{ - // serialize the counters - counter0.serialize(base + ".counter0", os); - counter1.serialize(base + ".counter1", os); - counter2.serialize(base + ".counter2", os); -} - -void -TsunamiIO::PITimer::unserialize(const string &base, Checkpoint *cp, - const string §ion) -{ - // unserialze the counters - counter0.unserialize(base + ".counter0", cp, section); - counter1.unserialize(base + ".counter1", cp, section); - counter2.unserialize(base + ".counter2", cp, section); -} - -TsunamiIO::PITimer::Counter::Counter(const string &name) - : _name(name), event(this), count(0), latched_count(0), period(0), - mode(0), output_high(false), latch_on(false), read_byte(LSB), - write_byte(LSB) -{ - -} - -void -TsunamiIO::PITimer::Counter::latchCount() -{ - // behave like a real latch - if(!latch_on) { - latch_on = true; - read_byte = LSB; - latched_count = count; - } -} - -uint8_t -TsunamiIO::PITimer::Counter::read() -{ - if (latch_on) { - switch (read_byte) { - case LSB: - read_byte = MSB; - return (uint8_t)latched_count; - break; - case MSB: - read_byte = LSB; - latch_on = false; - return latched_count >> 8; - break; - default: - panic("Shouldn't be here"); - } - } else { - switch (read_byte) { - case LSB: - read_byte = MSB; - return (uint8_t)count; - break; - case MSB: - read_byte = LSB; - return count >> 8; - break; - default: - panic("Shouldn't be here"); - } - } -} - -void -TsunamiIO::PITimer::Counter::write(const uint8_t data) -{ - switch (write_byte) { - case LSB: - count = (count & 0xFF00) | data; - - if (event.scheduled()) - event.deschedule(); - output_high = false; - write_byte = MSB; - break; - - case MSB: - count = (count & 0x00FF) | (data << 8); - period = count; - - if (period > 0) { - DPRINTF(Tsunami, "Timer set to curTick + %d\n", - count * event.interval); - event.schedule(curTick + count * event.interval); - } - write_byte = LSB; - break; - } -} - -void -TsunamiIO::PITimer::Counter::setRW(int rw_val) -{ - if (rw_val != PIT_RW_16BIT) - panic("Only LSB/MSB read/write is implemented.\n"); -} - -void -TsunamiIO::PITimer::Counter::setMode(int mode_val) -{ - if(mode_val != PIT_MODE_INTTC && mode_val != PIT_MODE_RATEGEN && - mode_val != PIT_MODE_SQWAVE) - panic("PIT mode %#x is not implemented: \n", mode_val); - - mode = mode_val; -} - -void -TsunamiIO::PITimer::Counter::setBCD(int bcd_val) -{ - if (bcd_val != PIT_BCD_FALSE) - panic("PITimer does not implement BCD counts.\n"); -} - -bool -TsunamiIO::PITimer::Counter::outputHigh() -{ - return output_high; -} - -void -TsunamiIO::PITimer::Counter::serialize(const string &base, ostream &os) -{ - paramOut(os, base + ".count", count); - paramOut(os, base + ".latched_count", latched_count); - paramOut(os, base + ".period", period); - paramOut(os, base + ".mode", mode); - paramOut(os, base + ".output_high", output_high); - paramOut(os, base + ".latch_on", latch_on); - paramOut(os, base + ".read_byte", read_byte); - paramOut(os, base + ".write_byte", write_byte); - - Tick event_tick = 0; - if (event.scheduled()) - event_tick = event.when(); - paramOut(os, base + ".event_tick", event_tick); -} - -void -TsunamiIO::PITimer::Counter::unserialize(const string &base, Checkpoint *cp, - const string §ion) -{ - paramIn(cp, section, base + ".count", count); - paramIn(cp, section, base + ".latched_count", latched_count); - paramIn(cp, section, base + ".period", period); - paramIn(cp, section, base + ".mode", mode); - paramIn(cp, section, base + ".output_high", output_high); - paramIn(cp, section, base + ".latch_on", latch_on); - paramIn(cp, section, base + ".read_byte", read_byte); - paramIn(cp, section, base + ".write_byte", write_byte); - - Tick event_tick; - paramIn(cp, section, base + ".event_tick", event_tick); - if (event_tick) - event.schedule(event_tick); -} - -TsunamiIO::PITimer::Counter::CounterEvent::CounterEvent(Counter* c_ptr) - : Event(&mainEventQueue) -{ - interval = (Tick)(Clock::Float::s / 1193180.0); - counter = c_ptr; -} - -void -TsunamiIO::PITimer::Counter::CounterEvent::process() -{ - DPRINTF(Tsunami, "Timer Interrupt\n"); - switch (counter->mode) { - case PIT_MODE_INTTC: - counter->output_high = true; - case PIT_MODE_RATEGEN: - case PIT_MODE_SQWAVE: - break; - default: - panic("Unimplemented PITimer mode.\n"); - } -} - -const char * -TsunamiIO::PITimer::Counter::CounterEvent::description() -{ - return "tsunami 8254 Interval timer"; -} - -TsunamiIO::TsunamiIO(Params *p) - : BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"), - rtc(p->name + ".rtc", p->tsunami, p->frequency) -{ - pioSize = 0xff; - - // set the back pointer from tsunami to myself - tsunami->io = this; - - timerData = 0; - rtc.set_time(p->init_time == 0 ? time(NULL) : p->init_time); - picr = 0; - picInterrupting = false; -} - -Tick -TsunamiIO::frequency() const -{ - return Clock::Frequency / params()->frequency; -} - -Tick -TsunamiIO::read(PacketPtr pkt) -{ - assert(pkt->result == Packet::Unknown); - assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - - Addr daddr = pkt->getAddr() - pioAddr; - - DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt->getAddr(), - pkt->getSize(), daddr); - - pkt->allocate(); - - if (pkt->getSize() == sizeof(uint8_t)) { - switch(daddr) { - // PIC1 mask read - case TSDEV_PIC1_MASK: - pkt->set(~mask1); - break; - case TSDEV_PIC2_MASK: - pkt->set(~mask2); - break; - case TSDEV_PIC1_ISR: - // !!! If this is modified 64bit case needs to be too - // Pal code has to do a 64 bit physical read because there is - // no load physical byte instruction - pkt->set(picr); - break; - case TSDEV_PIC2_ISR: - // PIC2 not implemnted... just return 0 - pkt->set(0x00); - break; - case TSDEV_TMR0_DATA: - pkt->set(pitimer.counter0.read()); - break; - case TSDEV_TMR1_DATA: - pkt->set(pitimer.counter1.read()); - break; - case TSDEV_TMR2_DATA: - pkt->set(pitimer.counter2.read()); - break; - case TSDEV_RTC_DATA: - pkt->set(rtc.readData()); - break; - case TSDEV_CTRL_PORTB: - if (pitimer.counter2.outputHigh()) - pkt->set(PORTB_SPKR_HIGH); - else - pkt->set(0x00); - break; - default: - panic("I/O Read - va%#x size %d\n", pkt->getAddr(), pkt->getSize()); - } - } else if (pkt->getSize() == sizeof(uint64_t)) { - if (daddr == TSDEV_PIC1_ISR) - pkt->set(picr); - else - panic("I/O Read - invalid addr - va %#x size %d\n", - pkt->getAddr(), pkt->getSize()); - } else { - panic("I/O Read - invalid size - va %#x size %d\n", pkt->getAddr(), pkt->getSize()); - } - pkt->result = Packet::Success; - return pioDelay; -} - -Tick -TsunamiIO::write(PacketPtr pkt) -{ - assert(pkt->result == Packet::Unknown); - assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - Addr daddr = pkt->getAddr() - pioAddr; - - DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n", - pkt->getAddr(), pkt->getSize(), pkt->getAddr() & 0xfff, (uint32_t)pkt->get()); - - assert(pkt->getSize() == sizeof(uint8_t)); - - switch(daddr) { - case TSDEV_PIC1_MASK: - mask1 = ~(pkt->get()); - if ((picr & mask1) && !picInterrupting) { - picInterrupting = true; - tsunami->cchip->postDRIR(55); - DPRINTF(Tsunami, "posting pic interrupt to cchip\n"); - } - if ((!(picr & mask1)) && picInterrupting) { - picInterrupting = false; - tsunami->cchip->clearDRIR(55); - DPRINTF(Tsunami, "clearing pic interrupt\n"); - } - break; - case TSDEV_PIC2_MASK: - mask2 = pkt->get(); - //PIC2 Not implemented to interrupt - break; - case TSDEV_PIC1_ACK: - // clear the interrupt on the PIC - picr &= ~(1 << (pkt->get() & 0xF)); - if (!(picr & mask1)) - tsunami->cchip->clearDRIR(55); - break; - case TSDEV_DMA1_MODE: - mode1 = pkt->get(); - break; - case TSDEV_DMA2_MODE: - mode2 = pkt->get(); - break; - case TSDEV_TMR0_DATA: - pitimer.counter0.write(pkt->get()); - break; - case TSDEV_TMR1_DATA: - pitimer.counter1.write(pkt->get()); - break; - case TSDEV_TMR2_DATA: - pitimer.counter2.write(pkt->get()); - break; - case TSDEV_TMR_CTRL: - pitimer.writeControl(pkt->get()); - break; - case TSDEV_RTC_ADDR: - rtc.writeAddr(pkt->get()); - break; - case TSDEV_RTC_DATA: - rtc.writeData(pkt->get()); - break; - case TSDEV_KBD: - case TSDEV_DMA1_CMND: - case TSDEV_DMA2_CMND: - case TSDEV_DMA1_MMASK: - case TSDEV_DMA2_MMASK: - case TSDEV_PIC2_ACK: - case TSDEV_DMA1_RESET: - case TSDEV_DMA2_RESET: - case TSDEV_DMA1_MASK: - case TSDEV_DMA2_MASK: - case TSDEV_CTRL_PORTB: - break; - default: - panic("I/O Write - va%#x size %d data %#x\n", pkt->getAddr(), pkt->getSize(), pkt->get()); - } - - pkt->result = Packet::Success; - return pioDelay; -} - -void -TsunamiIO::postPIC(uint8_t bitvector) -{ - //PIC2 Is not implemented, because nothing of interest there - picr |= bitvector; - if (picr & mask1) { - tsunami->cchip->postDRIR(55); - DPRINTF(Tsunami, "posting pic interrupt to cchip\n"); - } -} - -void -TsunamiIO::clearPIC(uint8_t bitvector) -{ - //PIC2 Is not implemented, because nothing of interest there - picr &= ~bitvector; - if (!(picr & mask1)) { - tsunami->cchip->clearDRIR(55); - DPRINTF(Tsunami, "clearing pic interrupt to cchip\n"); - } -} - -void -TsunamiIO::serialize(ostream &os) -{ - SERIALIZE_SCALAR(timerData); - SERIALIZE_SCALAR(mask1); - SERIALIZE_SCALAR(mask2); - SERIALIZE_SCALAR(mode1); - SERIALIZE_SCALAR(mode2); - SERIALIZE_SCALAR(picr); - SERIALIZE_SCALAR(picInterrupting); - - // Serialize the timers - pitimer.serialize("pitimer", os); - rtc.serialize("rtc", os); -} - -void -TsunamiIO::unserialize(Checkpoint *cp, const string §ion) -{ - UNSERIALIZE_SCALAR(timerData); - UNSERIALIZE_SCALAR(mask1); - UNSERIALIZE_SCALAR(mask2); - UNSERIALIZE_SCALAR(mode1); - UNSERIALIZE_SCALAR(mode2); - UNSERIALIZE_SCALAR(picr); - UNSERIALIZE_SCALAR(picInterrupting); - - // Unserialize the timers - pitimer.unserialize("pitimer", cp, section); - rtc.unserialize("rtc", cp, section); -} - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) - - Param pio_addr; - Param pio_latency; - Param frequency; - SimObjectParam platform; - SimObjectParam system; - Param time; - SimObjectParam tsunami; - -END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) - -BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO) - - INIT_PARAM(pio_addr, "Device Address"), - INIT_PARAM(pio_latency, "Programmed IO latency"), - INIT_PARAM(frequency, "clock interrupt frequency"), - INIT_PARAM(platform, "platform"), - INIT_PARAM(system, "system object"), - INIT_PARAM(time, "System time to use (0 for actual time"), - INIT_PARAM(tsunami, "Tsunami") - -END_INIT_SIM_OBJECT_PARAMS(TsunamiIO) - -CREATE_SIM_OBJECT(TsunamiIO) -{ - TsunamiIO::Params *p = new TsunamiIO::Params; - p->frequency = frequency; - p->name = getInstanceName(); - p->pio_addr = pio_addr; - p->pio_delay = pio_latency; - p->platform = platform; - p->system = system; - p->init_time = time; - p->tsunami = tsunami; - return new TsunamiIO(p); -} - -REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO) diff --git a/src/dev/tsunami_io.hh b/src/dev/tsunami_io.hh deleted file mode 100644 index 5ea3628c1..000000000 --- a/src/dev/tsunami_io.hh +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright (c) 2004-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: Ali Saidi - * Andrew Schultz - * Miguel Serrano - */ - -/** @file - * Tsunami I/O Space mapping including RTC/timer interrupts - */ - -#ifndef __DEV_TSUNAMI_IO_HH__ -#define __DEV_TSUNAMI_IO_HH__ - -#include "dev/io_device.hh" -#include "base/range.hh" -#include "dev/tsunami.hh" -#include "sim/eventq.hh" - -/** - * Tsunami I/O device is a catch all for all the south bridge stuff we care - * to implement. - */ -class TsunamiIO : public BasicPioDevice -{ - private: - struct tm tm; - - protected: - /** Real-Time Clock (MC146818) */ - class RTC - { - private: - /** Event for RTC periodic interrupt */ - struct RTCEvent : public Event - { - /** A pointer back to tsunami to create interrupt the processor. */ - Tsunami* tsunami; - Tick interval; - - RTCEvent(Tsunami* t, Tick i); - - /** Schedule the RTC periodic interrupt */ - void scheduleIntr(); - - /** Event process to occur at interrupt*/ - virtual void process(); - - /** Event description */ - virtual const char *description(); - }; - - private: - std::string _name; - const std::string &name() const { return _name; } - - /** RTC periodic interrupt event */ - RTCEvent event; - - /** Current RTC register address/index */ - int addr; - - /** Data for real-time clock function */ - union { - uint8_t clock_data[10]; - - struct { - uint8_t sec; - uint8_t sec_alrm; - uint8_t min; - uint8_t min_alrm; - uint8_t hour; - uint8_t hour_alrm; - uint8_t wday; - uint8_t mday; - uint8_t mon; - uint8_t year; - }; - }; - - /** RTC status register A */ - uint8_t stat_regA; - - /** RTC status register B */ - uint8_t stat_regB; - - public: - RTC(const std::string &name, Tsunami* t, Tick i); - - /** Set the initial RTC time/date */ - void set_time(time_t t); - - /** RTC address port: write address of RTC RAM data to access */ - void writeAddr(const uint8_t data); - - /** RTC write data */ - void writeData(const uint8_t data); - - /** RTC read data */ - uint8_t readData(); - - /** - * Serialize this object to the given output stream. - * @param base The base name of the counter object. - * @param os The stream to serialize to. - */ - void serialize(const std::string &base, std::ostream &os); - - /** - * Reconstruct the state of this object from a checkpoint. - * @param base The base name of the counter object. - * @param cp The checkpoint use. - * @param section The section name of this object - */ - void unserialize(const std::string &base, Checkpoint *cp, - const std::string §ion); - }; - - /** Programmable Interval Timer (Intel 8254) */ - class PITimer - { - /** Counter element for PIT */ - class Counter - { - /** Event for counter interrupt */ - class CounterEvent : public Event - { - private: - /** Pointer back to Counter */ - Counter* counter; - Tick interval; - - public: - CounterEvent(Counter*); - - /** Event process */ - virtual void process(); - - /** Event description */ - virtual const char *description(); - - friend class Counter; - }; - - private: - std::string _name; - const std::string &name() const { return _name; } - - CounterEvent event; - - /** Current count value */ - uint16_t count; - - /** Latched count */ - uint16_t latched_count; - - /** Interrupt period */ - uint16_t period; - - /** Current mode of operation */ - uint8_t mode; - - /** Output goes high when the counter reaches zero */ - bool output_high; - - /** State of the count latch */ - bool latch_on; - - /** Set of values for read_byte and write_byte */ - enum {LSB, MSB}; - - /** Determine which byte of a 16-bit count value to read/write */ - uint8_t read_byte, write_byte; - - public: - Counter(const std::string &name); - - /** Latch the current count (if one is not already latched) */ - void latchCount(); - - /** Set the read/write mode */ - void setRW(int rw_val); - - /** Set operational mode */ - void setMode(int mode_val); - - /** Set count encoding */ - void setBCD(int bcd_val); - - /** Read a count byte */ - uint8_t read(); - - /** Write a count byte */ - void write(const uint8_t data); - - /** Is the output high? */ - bool outputHigh(); - - /** - * Serialize this object to the given output stream. - * @param base The base name of the counter object. - * @param os The stream to serialize to. - */ - void serialize(const std::string &base, std::ostream &os); - - /** - * Reconstruct the state of this object from a checkpoint. - * @param base The base name of the counter object. - * @param cp The checkpoint use. - * @param section The section name of this object - */ - void unserialize(const std::string &base, Checkpoint *cp, - const std::string §ion); - }; - - private: - std::string _name; - const std::string &name() const { return _name; } - - /** PIT has three seperate counters */ - Counter *counter[3]; - - public: - /** Public way to access individual counters (avoid array accesses) */ - Counter counter0; - Counter counter1; - Counter counter2; - - PITimer(const std::string &name); - - /** Write control word */ - void writeControl(const uint8_t data); - - /** - * Serialize this object to the given output stream. - * @param base The base name of the counter object. - * @param os The stream to serialize to. - */ - void serialize(const std::string &base, std::ostream &os); - - /** - * Reconstruct the state of this object from a checkpoint. - * @param base The base name of the counter object. - * @param cp The checkpoint use. - * @param section The section name of this object - */ - void unserialize(const std::string &base, Checkpoint *cp, - const std::string §ion); - }; - - /** Mask of the PIC1 */ - uint8_t mask1; - - /** Mask of the PIC2 */ - uint8_t mask2; - - /** Mode of PIC1. Not used for anything */ - uint8_t mode1; - - /** Mode of PIC2. Not used for anything */ - uint8_t mode2; - - /** Raw PIC interrupt register before masking */ - uint8_t picr; //Raw PIC interrput register - - /** Is the pic interrupting right now or not. */ - bool picInterrupting; - - /** A pointer to the Tsunami device which be belong to */ - Tsunami *tsunami; - - /** Intel 8253 Periodic Interval Timer */ - PITimer pitimer; - - RTC rtc; - - /** The interval is set via two writes to the PIT. - * This variable contains a flag as to how many writes have happened, and - * the time so far. - */ - uint16_t timerData; - - public: - /** - * Return the freqency of the RTC - * @return interrupt rate of the RTC - */ - Tick frequency() const; - - struct Params : public BasicPioDevice::Params - { - Tick frequency; - Tsunami *tsunami; - time_t init_time; - }; - protected: - const Params *params() const { return (const Params*)_params; } - - public: - /** - * Initialize all the data for devices supported by Tsunami I/O. - * @param p pointer to Params struct - */ - TsunamiIO(Params *p); - - virtual Tick read(PacketPtr pkt); - virtual Tick write(PacketPtr pkt); - - /** - * Post an PIC interrupt to the CPU via the CChip - * @param bitvector interrupt to post. - */ - void postPIC(uint8_t bitvector); - - /** - * Clear a posted interrupt - * @param bitvector interrupt to clear - */ - void clearPIC(uint8_t bitvector); - - /** - * Serialize this object to the given output stream. - * @param os The stream to serialize to. - */ - virtual void serialize(std::ostream &os); - - /** - * Reconstruct the state of this object from a checkpoint. - * @param cp The checkpoint use. - * @param section The section name of this object - */ - virtual void unserialize(Checkpoint *cp, const std::string §ion); - -}; - -#endif // __DEV_TSUNAMI_IO_HH__ diff --git a/src/dev/tsunami_pchip.cc b/src/dev/tsunami_pchip.cc deleted file mode 100644 index 549db1a50..000000000 --- a/src/dev/tsunami_pchip.cc +++ /dev/null @@ -1,369 +0,0 @@ -/* - * Copyright (c) 2004-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: Ali Saidi - * Andrew Schultz - */ - -/** @file - * Tsunami PChip (pci) - */ - -#include -#include -#include - -#include "base/trace.hh" -#include "dev/tsunami_pchip.hh" -#include "dev/tsunamireg.h" -#include "dev/tsunami.hh" -#include "mem/packet.hh" -#include "mem/packet_access.hh" -#include "sim/builder.hh" -#include "sim/system.hh" - -using namespace std; -//Should this be AlphaISA? -using namespace TheISA; - -TsunamiPChip::TsunamiPChip(Params *p) -: BasicPioDevice(p) -{ - pioSize = 0xfff; - - for (int i = 0; i < 4; i++) { - wsba[i] = 0; - wsm[i] = 0; - tba[i] = 0; - } - - // initialize pchip control register - pctl = (ULL(0x1) << 20) | (ULL(0x1) << 32) | (ULL(0x2) << 36); - - //Set back pointer in tsunami - p->tsunami->pchip = this; -} - -Tick -TsunamiPChip::read(PacketPtr pkt) -{ - assert(pkt->result == Packet::Unknown); - assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - - pkt->allocate(); - Addr daddr = (pkt->getAddr() - pioAddr) >> 6;; - assert(pkt->getSize() == sizeof(uint64_t)); - - - DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize()); - - switch(daddr) { - case TSDEV_PC_WSBA0: - pkt->set(wsba[0]); - break; - case TSDEV_PC_WSBA1: - pkt->set(wsba[1]); - break; - case TSDEV_PC_WSBA2: - pkt->set(wsba[2]); - break; - case TSDEV_PC_WSBA3: - pkt->set(wsba[3]); - break; - case TSDEV_PC_WSM0: - pkt->set(wsm[0]); - break; - case TSDEV_PC_WSM1: - pkt->set(wsm[1]); - break; - case TSDEV_PC_WSM2: - pkt->set(wsm[2]); - break; - case TSDEV_PC_WSM3: - pkt->set(wsm[3]); - break; - case TSDEV_PC_TBA0: - pkt->set(tba[0]); - break; - case TSDEV_PC_TBA1: - pkt->set(tba[1]); - break; - case TSDEV_PC_TBA2: - pkt->set(tba[2]); - break; - case TSDEV_PC_TBA3: - pkt->set(tba[3]); - break; - case TSDEV_PC_PCTL: - pkt->set(pctl); - break; - case TSDEV_PC_PLAT: - panic("PC_PLAT not implemented\n"); - case TSDEV_PC_RES: - panic("PC_RES not implemented\n"); - case TSDEV_PC_PERROR: - pkt->set((uint64_t)0x00); - break; - case TSDEV_PC_PERRMASK: - pkt->set((uint64_t)0x00); - break; - case TSDEV_PC_PERRSET: - panic("PC_PERRSET not implemented\n"); - case TSDEV_PC_TLBIV: - panic("PC_TLBIV not implemented\n"); - case TSDEV_PC_TLBIA: - pkt->set((uint64_t)0x00); // shouldn't be readable, but linux - break; - case TSDEV_PC_PMONCTL: - panic("PC_PMONCTL not implemented\n"); - case TSDEV_PC_PMONCNT: - panic("PC_PMONCTN not implemented\n"); - default: - panic("Default in PChip Read reached reading 0x%x\n", daddr); - } - pkt->result = Packet::Success; - return pioDelay; - -} - -Tick -TsunamiPChip::write(PacketPtr pkt) -{ - assert(pkt->result == Packet::Unknown); - assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - Addr daddr = (pkt->getAddr() - pioAddr) >> 6; - - assert(pkt->getSize() == sizeof(uint64_t)); - - DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize()); - - switch(daddr) { - case TSDEV_PC_WSBA0: - wsba[0] = pkt->get(); - break; - case TSDEV_PC_WSBA1: - wsba[1] = pkt->get(); - break; - case TSDEV_PC_WSBA2: - wsba[2] = pkt->get(); - break; - case TSDEV_PC_WSBA3: - wsba[3] = pkt->get(); - break; - case TSDEV_PC_WSM0: - wsm[0] = pkt->get(); - break; - case TSDEV_PC_WSM1: - wsm[1] = pkt->get(); - break; - case TSDEV_PC_WSM2: - wsm[2] = pkt->get(); - break; - case TSDEV_PC_WSM3: - wsm[3] = pkt->get(); - break; - case TSDEV_PC_TBA0: - tba[0] = pkt->get(); - break; - case TSDEV_PC_TBA1: - tba[1] = pkt->get(); - break; - case TSDEV_PC_TBA2: - tba[2] = pkt->get(); - break; - case TSDEV_PC_TBA3: - tba[3] = pkt->get(); - break; - case TSDEV_PC_PCTL: - pctl = pkt->get(); - break; - case TSDEV_PC_PLAT: - panic("PC_PLAT not implemented\n"); - case TSDEV_PC_RES: - panic("PC_RES not implemented\n"); - case TSDEV_PC_PERROR: - break; - case TSDEV_PC_PERRMASK: - panic("PC_PERRMASK not implemented\n"); - case TSDEV_PC_PERRSET: - panic("PC_PERRSET not implemented\n"); - case TSDEV_PC_TLBIV: - panic("PC_TLBIV not implemented\n"); - case TSDEV_PC_TLBIA: - break; // value ignored, supposted to invalidate SG TLB - case TSDEV_PC_PMONCTL: - panic("PC_PMONCTL not implemented\n"); - case TSDEV_PC_PMONCNT: - panic("PC_PMONCTN not implemented\n"); - default: - panic("Default in PChip write reached reading 0x%x\n", daddr); - - } // uint64_t - - pkt->result = Packet::Success; - return pioDelay; -} - -#define DMA_ADDR_MASK ULL(0x3ffffffff) - -Addr -TsunamiPChip::translatePciToDma(Addr busAddr) -{ - // compare the address to the window base registers - uint64_t tbaMask = 0; - uint64_t baMask = 0; - - uint64_t windowMask = 0; - uint64_t windowBase = 0; - - uint64_t pteEntry = 0; - - Addr pteAddr; - Addr dmaAddr; - -#if 0 - DPRINTF(IdeDisk, "Translation for bus address: %#x\n", busAddr); - for (int i = 0; i < 4; i++) { - DPRINTF(IdeDisk, "(%d) base:%#x mask:%#x\n", - i, wsba[i], wsm[i]); - - windowBase = wsba[i]; - windowMask = ~wsm[i] & (ULL(0xfff) << 20); - - if ((busAddr & windowMask) == (windowBase & windowMask)) { - DPRINTF(IdeDisk, "Would have matched %d (wb:%#x wm:%#x --> ba&wm:%#x wb&wm:%#x)\n", - i, windowBase, windowMask, (busAddr & windowMask), - (windowBase & windowMask)); - } - } -#endif - - for (int i = 0; i < 4; i++) { - - windowBase = wsba[i]; - windowMask = ~wsm[i] & (ULL(0xfff) << 20); - - if ((busAddr & windowMask) == (windowBase & windowMask)) { - - if (wsba[i] & 0x1) { // see if enabled - if (wsba[i] & 0x2) { // see if SG bit is set - /** @todo - This currently is faked by just doing a direct - read from memory, however, to be realistic, this - needs to actually do a bus transaction. The process - is explained in the tsunami documentation on page - 10-12 and basically munges the address to look up a - PTE from a table in memory and then uses that mapping - to create an address for the SG page - */ - - tbaMask = ~(((wsm[i] & (ULL(0xfff) << 20)) >> 10) | ULL(0x3ff)); - baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13); - pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10); - - pioPort->readBlob(pteAddr, (uint8_t*)&pteEntry, sizeof(uint64_t)); - - dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff)); - - } else { - baMask = (wsm[i] & (ULL(0xfff) << 20)) | ULL(0xfffff); - tbaMask = ~baMask; - dmaAddr = (tba[i] & tbaMask) | (busAddr & baMask); - } - - return (dmaAddr & DMA_ADDR_MASK); - } - } - } - - // if no match was found, then return the original address - return busAddr; -} -Addr -TsunamiPChip::calcConfigAddr(int bus, int dev, int func) -{ - assert(func < 8); - assert(dev < 32); - assert(bus == 0); - - return TsunamiPciBus0Config | (func << 8) | (dev << 11); -} - - - -void -TsunamiPChip::serialize(std::ostream &os) -{ - SERIALIZE_SCALAR(pctl); - SERIALIZE_ARRAY(wsba, 4); - SERIALIZE_ARRAY(wsm, 4); - SERIALIZE_ARRAY(tba, 4); -} - -void -TsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion) -{ - UNSERIALIZE_SCALAR(pctl); - UNSERIALIZE_ARRAY(wsba, 4); - UNSERIALIZE_ARRAY(wsm, 4); - UNSERIALIZE_ARRAY(tba, 4); -} - - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) - - Param pio_addr; - Param pio_latency; - SimObjectParam platform; - SimObjectParam system; - SimObjectParam tsunami; - -END_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) - -BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) - - INIT_PARAM(pio_addr, "Device Address"), - INIT_PARAM(pio_latency, "Programmed IO latency"), - INIT_PARAM(platform, "platform"), - INIT_PARAM(system, "system object"), - INIT_PARAM(tsunami, "Tsunami") - -END_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) - -CREATE_SIM_OBJECT(TsunamiPChip) -{ - TsunamiPChip::Params *p = new TsunamiPChip::Params; - p->name = getInstanceName(); - p->pio_addr = pio_addr; - p->pio_delay = pio_latency; - p->platform = platform; - p->system = system; - p->tsunami = tsunami; - return new TsunamiPChip(p); -} - -REGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip) diff --git a/src/dev/tsunami_pchip.hh b/src/dev/tsunami_pchip.hh deleted file mode 100644 index d0a9c3157..000000000 --- a/src/dev/tsunami_pchip.hh +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2004-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: Ali Saidi - */ - -/** @file - * Tsunami PCI interface CSRs - */ - -#ifndef __TSUNAMI_PCHIP_HH__ -#define __TSUNAMI_PCHIP_HH__ - -#include "dev/tsunami.hh" -#include "base/range.hh" -#include "dev/io_device.hh" - -/** - * A very simple implementation of the Tsunami PCI interface chips. - */ -class TsunamiPChip : public BasicPioDevice -{ - protected: - - static const Addr TsunamiPciBus0Config = ULL(0x801fe000000); - - /** Pchip control register */ - uint64_t pctl; - - /** Window Base addresses */ - uint64_t wsba[4]; - - /** Window masks */ - uint64_t wsm[4]; - - /** Translated Base Addresses */ - uint64_t tba[4]; - - public: - struct Params : public BasicPioDevice::Params - { - Tsunami *tsunami; - }; - protected: - const Params *params() const { return (const Params*)_params; } - - public: - /** - * Register the PChip with the mmu and init all wsba, wsm, and tba to 0 - * @param p pointer to the parameters struct - */ - TsunamiPChip(Params *p); - - /** - * Translate a PCI bus address to a memory address for DMA. - * @todo Andrew says this needs to be fixed. What's wrong with it? - * @param busAddr PCI address to translate. - * @return memory system address - */ - Addr translatePciToDma(Addr busAddr); - - Addr calcConfigAddr(int bus, int dev, int func); - - virtual Tick read(PacketPtr pkt); - virtual Tick write(PacketPtr pkt); - - /** - * Serialize this object to the given output stream. - * @param os The stream to serialize to. - */ - virtual void serialize(std::ostream &os); - - /** - * Reconstruct the state of this object from a checkpoint. - * @param cp The checkpoint use. - * @param section The section name of this object - */ - virtual void unserialize(Checkpoint *cp, const std::string §ion); -}; - -#endif // __TSUNAMI_PCHIP_HH__ diff --git a/src/dev/tsunamireg.h b/src/dev/tsunamireg.h deleted file mode 100644 index d603972be..000000000 --- a/src/dev/tsunamireg.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2004-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: Ali Saidi - */ - -/** @file - * List of Tsunami CSRs - */ - -#ifndef __TSUNAMIREG_H__ -#define __TSUNAMIREG_H__ - -#define ALPHA_K0SEG_BASE ULL(0xfffffc0000000000) - -// CChip Registers -#define TSDEV_CC_CSR 0x00 -#define TSDEV_CC_MTR 0x01 -#define TSDEV_CC_MISC 0x02 - -#define TSDEV_CC_AAR0 0x04 -#define TSDEV_CC_AAR1 0x05 -#define TSDEV_CC_AAR2 0x06 -#define TSDEV_CC_AAR3 0x07 -#define TSDEV_CC_DIM0 0x08 -#define TSDEV_CC_DIM1 0x09 -#define TSDEV_CC_DIR0 0x0A -#define TSDEV_CC_DIR1 0x0B -#define TSDEV_CC_DRIR 0x0C -#define TSDEV_CC_PRBEN 0x0D -#define TSDEV_CC_IIC0 0x0E -#define TSDEV_CC_IIC1 0x0F -#define TSDEV_CC_MPR0 0x10 -#define TSDEV_CC_MPR1 0x11 -#define TSDEV_CC_MPR2 0x12 -#define TSDEV_CC_MPR3 0x13 - -#define TSDEV_CC_DIM2 0x18 -#define TSDEV_CC_DIM3 0x19 -#define TSDEV_CC_DIR2 0x1A -#define TSDEV_CC_DIR3 0x1B -#define TSDEV_CC_IIC2 0x1C -#define TSDEV_CC_IIC3 0x1D - -// BigTsunami Registers -#define TSDEV_CC_BDIMS 0x1000000 -#define TSDEV_CC_BDIRS 0x2000000 -#define TSDEV_CC_IPIQ 0x20 //0xf01a000800 -#define TSDEV_CC_IPIR 0x21 //0xf01a000840 -#define TSDEV_CC_ITIR 0x22 //0xf01a000880 - - -// PChip Registers -#define TSDEV_PC_WSBA0 0x00 -#define TSDEV_PC_WSBA1 0x01 -#define TSDEV_PC_WSBA2 0x02 -#define TSDEV_PC_WSBA3 0x03 -#define TSDEV_PC_WSM0 0x04 -#define TSDEV_PC_WSM1 0x05 -#define TSDEV_PC_WSM2 0x06 -#define TSDEV_PC_WSM3 0x07 -#define TSDEV_PC_TBA0 0x08 -#define TSDEV_PC_TBA1 0x09 -#define TSDEV_PC_TBA2 0x0A -#define TSDEV_PC_TBA3 0x0B -#define TSDEV_PC_PCTL 0x0C -#define TSDEV_PC_PLAT 0x0D -#define TSDEV_PC_RES 0x0E -#define TSDEV_PC_PERROR 0x0F -#define TSDEV_PC_PERRMASK 0x10 -#define TSDEV_PC_PERRSET 0x11 -#define TSDEV_PC_TLBIV 0x12 -#define TSDEV_PC_TLBIA 0x13 -#define TSDEV_PC_PMONCTL 0x14 -#define TSDEV_PC_PMONCNT 0x15 - -#define TSDEV_PC_SPST 0x20 - - -// DChip Registers -#define TSDEV_DC_DSC 0x20 -#define TSDEV_DC_STR 0x21 -#define TSDEV_DC_DREV 0x22 -#define TSDEV_DC_DSC2 0x23 - -// I/O Ports -#define TSDEV_PIC1_MASK 0x21 -#define TSDEV_PIC2_MASK 0xA1 -#define TSDEV_PIC1_ISR 0x20 -#define TSDEV_PIC2_ISR 0xA0 -#define TSDEV_PIC1_ACK 0x20 -#define TSDEV_PIC2_ACK 0xA0 -#define TSDEV_DMA1_RESET 0x0D -#define TSDEV_DMA2_RESET 0xDA -#define TSDEV_DMA1_MODE 0x0B -#define TSDEV_DMA2_MODE 0xD6 -#define TSDEV_DMA1_MASK 0x0A -#define TSDEV_DMA2_MASK 0xD4 -#define TSDEV_CTRL_PORTB 0x61 -#define TSDEV_TMR0_DATA 0x40 -#define TSDEV_TMR1_DATA 0x41 -#define TSDEV_TMR2_DATA 0x42 -#define TSDEV_TMR_CTRL 0x43 -#define TSDEV_KBD 0x64 -#define TSDEV_DMA1_CMND 0x08 -#define TSDEV_DMA1_STAT TSDEV_DMA1_CMND -#define TSDEV_DMA2_CMND 0xD0 -#define TSDEV_DMA2_STAT TSDEV_DMA2_CMND -#define TSDEV_DMA1_MMASK 0x0F -#define TSDEV_DMA2_MMASK 0xDE - -/* Added for keyboard accesses */ -#define TSDEV_KBD 0x64 - -/* Added for ATA PCI DMA */ -#define ATA_PCI_DMA 0x00 -#define ATA_PCI_DMA2 0x02 -#define ATA_PCI_DMA3 0x16 -#define ATA_PCI_DMA4 0x17 -#define ATA_PCI_DMA5 0x1a -#define ATA_PCI_DMA6 0x11 -#define ATA_PCI_DMA7 0x14 - -#define TSDEV_RTC_ADDR 0x70 -#define TSDEV_RTC_DATA 0x71 - -#define PCHIP_PCI0_MEMORY ULL(0x00000000000) -#define PCHIP_PCI0_IO ULL(0x001FC000000) -#define TSUNAMI_UNCACHABLE_BIT ULL(0x80000000000) -#define TSUNAMI_PCI0_MEMORY TSUNAMI_UNCACHABLE_BIT + PCHIP_PCI0_MEMORY -#define TSUNAMI_PCI0_IO TSUNAMI_UNCACHABLE_BIT + PCHIP_PCI0_IO - - -// UART Defines -#define UART_IER_RDI 0x01 -#define UART_IER_THRI 0x02 -#define UART_IER_RLSI 0x04 - - -#define UART_LSR_TEMT 0x40 -#define UART_LSR_THRE 0x20 -#define UART_LSR_DR 0x01 - -#define UART_MCR_LOOP 0x10 - -// System Control PortB Status Bits -#define PORTB_SPKR_HIGH 0x20 - -#endif // __TSUNAMIREG_H__ diff --git a/src/dev/uart8250.hh b/src/dev/uart8250.hh index 2e768216a..a0620c7e0 100644 --- a/src/dev/uart8250.hh +++ b/src/dev/uart8250.hh @@ -35,7 +35,7 @@ #ifndef __DEV_UART8250_HH__ #define __DEV_UART8250_HH__ -#include "dev/tsunamireg.h" +#include "dev/alpha/tsunamireg.h" #include "base/range.hh" #include "dev/io_device.hh" #include "dev/uart.hh" -- cgit v1.2.3 From 32a927b85fb67d0cf7c77aac0fc6c8e1ef709b54 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 6 Nov 2006 19:55:42 -0500 Subject: Only bother with the device SConscript if you're in FULL_SYSTEM --HG-- extra : convert_revision : ac52f548afb98dd0437e7d7c2600ff9b8ebfd1fa --- src/SConscript | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/SConscript b/src/SConscript index b383f58d6..58081751d 100644 --- a/src/SConscript +++ b/src/SConscript @@ -294,8 +294,9 @@ arch_sources = SConscript(os.path.join('arch', 'SConscript'), exports = 'env') cpu_sources = SConscript(os.path.join('cpu', 'SConscript'), exports = 'env') -dev_sources = SConscript(os.path.join('dev', 'SConscript'), exports = 'env') -full_system_sources += dev_sources +if env['FULL_SYSTEM']: + dev_sources = SConscript(os.path.join('dev', 'SConscript'), exports = 'env') + full_system_sources += dev_sources # This is outside of cpu/SConscript since the source directory isn't # underneath 'cpu'. -- cgit v1.2.3 From b156767f1e9c0211a398f3f40936f431c373ab9e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 6 Nov 2006 19:56:57 -0500 Subject: Get rid of pcifake.cc and tsunami_fake.cc to go with the merged default devices. --HG-- extra : convert_revision : e88aaaa43843c1283f29cef0886e057412705899 --- src/dev/SConscript | 1 - src/dev/alpha/SConscript | 2 -- 2 files changed, 3 deletions(-) (limited to 'src') diff --git a/src/dev/SConscript b/src/dev/SConscript index 75fca324a..951bc29d1 100644 --- a/src/dev/SConscript +++ b/src/dev/SConscript @@ -63,7 +63,6 @@ sources += Split(''' ns_gige.cc pciconfigall.cc pcidev.cc - pcifake.cc pktfifo.cc platform.cc simconsole.cc diff --git a/src/dev/alpha/SConscript b/src/dev/alpha/SConscript index 304cd9ca9..fb0e626d3 100644 --- a/src/dev/alpha/SConscript +++ b/src/dev/alpha/SConscript @@ -39,7 +39,6 @@ sources = Split(''' tsunami.cc tsunami_cchip.cc tsunami_io.cc - tsunami_fake.cc tsunami_pchip.cc ''') # baddev.cc @@ -57,7 +56,6 @@ sources = Split(''' # ns_gige.cc # pciconfigall.cc # pcidev.cc -# pcifake.cc # pktfifo.cc # platform.cc # simconsole.cc -- cgit v1.2.3 From f61cd02e1391996fc247bf624ac66f7c420690c0 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 6 Nov 2006 20:07:44 -0500 Subject: Got rid of the ivlb and ivle kernel stats. --HG-- extra : convert_revision : d85627bb3eafe6411355995a92ba8b151be8320d --- src/kern/kernel_stats.cc | 10 ---------- src/kern/kernel_stats.hh | 4 ---- 2 files changed, 14 deletions(-) (limited to 'src') diff --git a/src/kern/kernel_stats.cc b/src/kern/kernel_stats.cc index f7868b50f..f049ed66c 100644 --- a/src/kern/kernel_stats.cc +++ b/src/kern/kernel_stats.cc @@ -68,16 +68,6 @@ Statistics::regStats(const string &_name) .desc("number of quiesce instructions executed") ; - _ivlb - .name(name() + ".inst.ivlb") - .desc("number of ivlb instructions executed") - ; - - _ivle - .name(name() + ".inst.ivle") - .desc("number of ivle instructions executed") - ; - _hwrei .name(name() + ".inst.hwrei") .desc("number of hwrei instructions executed") diff --git a/src/kern/kernel_stats.hh b/src/kern/kernel_stats.hh index c691ad8cf..bd4850b0a 100644 --- a/src/kern/kernel_stats.hh +++ b/src/kern/kernel_stats.hh @@ -64,8 +64,6 @@ class Statistics : public Serializable private: Stats::Scalar<> _arm; Stats::Scalar<> _quiesce; - Stats::Scalar<> _ivlb; - Stats::Scalar<> _ivle; Stats::Scalar<> _hwrei; Stats::Vector<> _iplCount; @@ -97,8 +95,6 @@ class Statistics : public Serializable public: void arm() { _arm++; } void quiesce() { _quiesce++; } - void ivlb() { _ivlb++; } - void ivle() { _ivle++; } void hwrei() { _hwrei++; } void swpipl(int ipl); void mode(cpu_mode newmode, ThreadContext *tc); -- cgit v1.2.3 From 58f7ed2416fd0bb0823225d5feaff5fc5cf1f9c1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 6 Nov 2006 20:49:48 -0500 Subject: Cleaned up remnants of ivlb and ivle --HG-- extra : convert_revision : 93b37dbcd3d9dd1eced0f829223f52b53fe58643 --- src/sim/pseudo_inst.hh | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/sim/pseudo_inst.hh b/src/sim/pseudo_inst.hh index d211de44e..bc71a7e64 100644 --- a/src/sim/pseudo_inst.hh +++ b/src/sim/pseudo_inst.hh @@ -47,8 +47,6 @@ namespace AlphaPseudo void quiesceNs(ThreadContext *tc, uint64_t ns); void quiesceCycles(ThreadContext *tc, uint64_t cycles); uint64_t quiesceTime(ThreadContext *tc); - void ivlb(ThreadContext *tc); - void ivle(ThreadContext *tc); void m5exit(ThreadContext *tc, Tick delay); void m5exit_old(ThreadContext *tc); void loadsymbol(ThreadContext *xc); -- cgit v1.2.3 From eb4ef3ad763cf95a6437f9a88b1ab38255f5dcc3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:33:21 -0500 Subject: Made kern a switching header file directory. SConstruct: Put the code to make a switching header directory into a function so they are easy to make. src/arch/SConscript: Replace switching header code with the new function call. src/kern/SConscript: Created a new switching header directory in kern, and moved the declaration of some source files here. --HG-- rename : src/kern/kernel_stats.cc => src/kern/base_kernel_stats.cc rename : src/kern/kernel_stats.hh => src/kern/base_kernel_stats.hh extra : convert_revision : 98f5320a5ade567c3e4f67fef123dfb0c5122545 --- src/arch/SConscript | 32 +---- src/kern/SConscript | 69 +++++++++++ src/kern/base_kernel_stats.cc | 280 ++++++++++++++++++++++++++++++++++++++++++ src/kern/base_kernel_stats.hh | 113 +++++++++++++++++ src/kern/kernel_stats.cc | 280 ------------------------------------------ src/kern/kernel_stats.hh | 113 ----------------- 6 files changed, 464 insertions(+), 423 deletions(-) create mode 100644 src/kern/SConscript create mode 100644 src/kern/base_kernel_stats.cc create mode 100644 src/kern/base_kernel_stats.hh delete mode 100644 src/kern/kernel_stats.cc delete mode 100644 src/kern/kernel_stats.hh (limited to 'src') diff --git a/src/arch/SConscript b/src/arch/SConscript index 2ef3d5ee0..82a56d4eb 100644 --- a/src/arch/SConscript +++ b/src/arch/SConscript @@ -63,36 +63,8 @@ isa_switch_hdrs = Split(''' vtophys.hh ''') -# Generate the header. target[0] is the full path of the output -# header to generate. 'source' is a dummy variable, since we get the -# list of ISAs from env['ALL_ISA_LIST']. -def gen_switch_hdr(target, source, env): - fname = str(target[0]) - basename = os.path.basename(fname) - f = open(fname, 'w') - f.write('#include "arch/isa_specific.hh"\n') - cond = '#if' - for isa in env['ALL_ISA_LIST']: - f.write('%s THE_ISA == %s_ISA\n#include "arch/%s/%s"\n' - % (cond, isa.upper(), isa, basename)) - cond = '#elif' - f.write('#else\n#error "THE_ISA not set"\n#endif\n') - f.close() - return 0 - -# String to print when generating header -def gen_switch_hdr_string(target, source, env): - return "Generating ISA switch header " + str(target[0]) - -# Build SCons Action object. 'varlist' specifies env vars that this -# action depends on; when env['ALL_ISA_LIST'] changes these actions -# should get re-executed. -switch_hdr_action = Action(gen_switch_hdr, gen_switch_hdr_string, - varlist=['ALL_ISA_LIST']) - -# Instantiate actions for each header -for hdr in isa_switch_hdrs: - env.Command(hdr, [], switch_hdr_action) +# Set up this directory to support switching headers +env.make_switching_dir('arch', isa_switch_hdrs, env) ################################################################# # diff --git a/src/kern/SConscript b/src/kern/SConscript new file mode 100644 index 000000000..7245e2889 --- /dev/null +++ b/src/kern/SConscript @@ -0,0 +1,69 @@ +# -*- mode:python -*- + +# Copyright (c) 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 + +import os.path, sys + +# Import build environment variable from SConstruct. +Import('env') + +sources = Split(''' + base_kernel_stats.cc + system_events.cc + linux/events.cc + linux/linux_syscalls.cc + linux/printk.cc + ''') + +# Convert file names to SCons File objects. This takes care of the +# path relative to the top of the directory tree. +sources = [File(s) for s in sources] + +################################################################# +# +# ISA "switch header" generation. +# +# Auto-generate arch headers that include the right ISA-specific +# header based on the setting of THE_ISA preprocessor variable. +# +################################################################# + +# List of headers to generate +kern_switch_hdrs = Split(''' + kernel_stats.hh + ''') + +env.make_switching_dir('kern', kern_switch_hdrs, env) + +isa = env['TARGET_ISA'] # someday this may be a list of ISAs + +# Let the target architecture define what additional sources it needs +sources += SConscript(os.path.join(isa, 'SConscript'), exports = 'env') + +Return('sources') diff --git a/src/kern/base_kernel_stats.cc b/src/kern/base_kernel_stats.cc new file mode 100644 index 000000000..f049ed66c --- /dev/null +++ b/src/kern/base_kernel_stats.cc @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2004-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: Lisa Hsu + * Nathan Binkert + */ + +#include +#include +#include + +#include "arch/alpha/osfpal.hh" +#include "base/trace.hh" +#include "cpu/thread_context.hh" +#include "kern/kernel_stats.hh" +#include "kern/tru64/tru64_syscalls.hh" +#include "sim/system.hh" + +using namespace std; +using namespace Stats; + +namespace Kernel { + +const char *modestr[] = { "kernel", "user", "idle" }; + +Statistics::Statistics(System *system) + : idleProcess((Addr)-1), themode(kernel), lastModeTick(0), + iplLast(0), iplLastTick(0) +{ +} + +void +Statistics::regStats(const string &_name) +{ + myname = _name; + + _arm + .name(name() + ".inst.arm") + .desc("number of arm instructions executed") + ; + + _quiesce + .name(name() + ".inst.quiesce") + .desc("number of quiesce instructions executed") + ; + + _hwrei + .name(name() + ".inst.hwrei") + .desc("number of hwrei instructions executed") + ; + + _iplCount + .init(32) + .name(name() + ".ipl_count") + .desc("number of times we switched to this ipl") + .flags(total | pdf | nozero | nonan) + ; + + _iplGood + .init(32) + .name(name() + ".ipl_good") + .desc("number of times we switched to this ipl from a different ipl") + .flags(total | pdf | nozero | nonan) + ; + + _iplTicks + .init(32) + .name(name() + ".ipl_ticks") + .desc("number of cycles we spent at this ipl") + .flags(total | pdf | nozero | nonan) + ; + + _iplUsed + .name(name() + ".ipl_used") + .desc("fraction of swpipl calls that actually changed the ipl") + .flags(total | nozero | nonan) + ; + + _iplUsed = _iplGood / _iplCount; + + _callpal + .init(256) + .name(name() + ".callpal") + .desc("number of callpals executed") + .flags(total | pdf | nozero | nonan) + ; + + for (int i = 0; i < PAL::NumCodes; ++i) { + const char *str = PAL::name(i); + if (str) + _callpal.subname(i, str); + } + + _syscall + .init(SystemCalls::Number) + .name(name() + ".syscall") + .desc("number of syscalls executed") + .flags(total | pdf | nozero | nonan) + ; + + for (int i = 0; i < SystemCalls::Number; ++i) { + const char *str = SystemCalls::name(i); + if (str) { + _syscall.subname(i, str); + } + } + + _mode + .init(cpu_mode_num) + .name(name() + ".mode_switch") + .desc("number of protection mode switches") + ; + + for (int i = 0; i < cpu_mode_num; ++i) + _mode.subname(i, modestr[i]); + + _modeGood + .init(cpu_mode_num) + .name(name() + ".mode_good") + ; + + for (int i = 0; i < cpu_mode_num; ++i) + _modeGood.subname(i, modestr[i]); + + _modeFraction + .name(name() + ".mode_switch_good") + .desc("fraction of useful protection mode switches") + .flags(total) + ; + + for (int i = 0; i < cpu_mode_num; ++i) + _modeFraction.subname(i, modestr[i]); + + _modeFraction = _modeGood / _mode; + + _modeTicks + .init(cpu_mode_num) + .name(name() + ".mode_ticks") + .desc("number of ticks spent at the given mode") + .flags(pdf) + ; + for (int i = 0; i < cpu_mode_num; ++i) + _modeTicks.subname(i, modestr[i]); + + _swap_context + .name(name() + ".swap_context") + .desc("number of times the context was actually changed") + ; +} + +void +Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc) +{ + assert(themode == kernel); + idleProcess = idlepcbb; + themode = idle; + changeMode(themode, tc); +} + +void +Statistics::changeMode(cpu_mode newmode, ThreadContext *tc) +{ + _mode[newmode]++; + + if (newmode == themode) + return; + + DPRINTF(Context, "old mode=%-8s new mode=%-8s\n", + modestr[themode], modestr[newmode]); + + _modeGood[newmode]++; + _modeTicks[themode] += curTick - lastModeTick; + + lastModeTick = curTick; + themode = newmode; +} + +void +Statistics::swpipl(int ipl) +{ + assert(ipl >= 0 && ipl <= 0x1f && "invalid IPL\n"); + + _iplCount[ipl]++; + + if (ipl == iplLast) + return; + + _iplGood[ipl]++; + _iplTicks[iplLast] += curTick - iplLastTick; + iplLastTick = curTick; + iplLast = ipl; +} + +void +Statistics::mode(cpu_mode newmode, ThreadContext *tc) +{ + Addr pcbb = tc->readMiscReg(AlphaISA::IPR_PALtemp23); + + if (newmode == kernel && pcbb == idleProcess) + newmode = idle; + + changeMode(newmode, tc); +} + +void +Statistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc) +{ + assert(themode != user); + + _swap_context++; + changeMode(newpcbb == idleProcess ? idle : kernel, tc); +} + +void +Statistics::callpal(int code, ThreadContext *tc) +{ + if (!PAL::name(code)) + return; + + _callpal[code]++; + + switch (code) { + case PAL::callsys: { + int number = tc->readIntReg(0); + if (SystemCalls::validSyscallNumber(number)) { + int cvtnum = SystemCalls::convert(number); + _syscall[cvtnum]++; + } + } break; + } +} + +void +Statistics::serialize(ostream &os) +{ + int exemode = themode; + SERIALIZE_SCALAR(exemode); + SERIALIZE_SCALAR(idleProcess); + SERIALIZE_SCALAR(iplLast); + SERIALIZE_SCALAR(iplLastTick); + SERIALIZE_SCALAR(lastModeTick); +} + +void +Statistics::unserialize(Checkpoint *cp, const string §ion) +{ + int exemode; + UNSERIALIZE_SCALAR(exemode); + UNSERIALIZE_SCALAR(idleProcess); + UNSERIALIZE_SCALAR(iplLast); + UNSERIALIZE_SCALAR(iplLastTick); + UNSERIALIZE_SCALAR(lastModeTick); + themode = (cpu_mode)exemode; +} + +/* end namespace Kernel */ } diff --git a/src/kern/base_kernel_stats.hh b/src/kern/base_kernel_stats.hh new file mode 100644 index 000000000..bd4850b0a --- /dev/null +++ b/src/kern/base_kernel_stats.hh @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2004-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: Lisa Hsu + * Nathan Binkert + */ + +#ifndef __KERNEL_STATS_HH__ +#define __KERNEL_STATS_HH__ + +#include +#include +#include +#include + +#include "cpu/static_inst.hh" + +class BaseCPU; +class ThreadContext; +class FnEvent; +// What does kernel stats expect is included? +class System; + +namespace Kernel { + +enum cpu_mode { kernel, user, idle, cpu_mode_num }; +extern const char *modestr[]; + +class Statistics : public Serializable +{ + private: + std::string myname; + + Addr idleProcess; + cpu_mode themode; + Tick lastModeTick; + + void changeMode(cpu_mode newmode, ThreadContext *tc); + + private: + Stats::Scalar<> _arm; + Stats::Scalar<> _quiesce; + Stats::Scalar<> _hwrei; + + Stats::Vector<> _iplCount; + Stats::Vector<> _iplGood; + Stats::Vector<> _iplTicks; + Stats::Formula _iplUsed; + + Stats::Vector<> _callpal; + Stats::Vector<> _syscall; +// Stats::Vector<> _faults; + + Stats::Vector<> _mode; + Stats::Vector<> _modeGood; + Stats::Formula _modeFraction; + Stats::Vector<> _modeTicks; + + Stats::Scalar<> _swap_context; + + private: + int iplLast; + Tick iplLastTick; + + public: + Statistics(System *system); + + const std::string name() const { return myname; } + void regStats(const std::string &name); + + public: + void arm() { _arm++; } + void quiesce() { _quiesce++; } + void hwrei() { _hwrei++; } + void swpipl(int ipl); + void mode(cpu_mode newmode, ThreadContext *tc); + void context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc); + void callpal(int code, ThreadContext *tc); + + void setIdleProcess(Addr idle, ThreadContext *tc); + + public: + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +/* end namespace Kernel */ } + +#endif // __KERNEL_STATS_HH__ diff --git a/src/kern/kernel_stats.cc b/src/kern/kernel_stats.cc deleted file mode 100644 index f049ed66c..000000000 --- a/src/kern/kernel_stats.cc +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (c) 2004-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: Lisa Hsu - * Nathan Binkert - */ - -#include -#include -#include - -#include "arch/alpha/osfpal.hh" -#include "base/trace.hh" -#include "cpu/thread_context.hh" -#include "kern/kernel_stats.hh" -#include "kern/tru64/tru64_syscalls.hh" -#include "sim/system.hh" - -using namespace std; -using namespace Stats; - -namespace Kernel { - -const char *modestr[] = { "kernel", "user", "idle" }; - -Statistics::Statistics(System *system) - : idleProcess((Addr)-1), themode(kernel), lastModeTick(0), - iplLast(0), iplLastTick(0) -{ -} - -void -Statistics::regStats(const string &_name) -{ - myname = _name; - - _arm - .name(name() + ".inst.arm") - .desc("number of arm instructions executed") - ; - - _quiesce - .name(name() + ".inst.quiesce") - .desc("number of quiesce instructions executed") - ; - - _hwrei - .name(name() + ".inst.hwrei") - .desc("number of hwrei instructions executed") - ; - - _iplCount - .init(32) - .name(name() + ".ipl_count") - .desc("number of times we switched to this ipl") - .flags(total | pdf | nozero | nonan) - ; - - _iplGood - .init(32) - .name(name() + ".ipl_good") - .desc("number of times we switched to this ipl from a different ipl") - .flags(total | pdf | nozero | nonan) - ; - - _iplTicks - .init(32) - .name(name() + ".ipl_ticks") - .desc("number of cycles we spent at this ipl") - .flags(total | pdf | nozero | nonan) - ; - - _iplUsed - .name(name() + ".ipl_used") - .desc("fraction of swpipl calls that actually changed the ipl") - .flags(total | nozero | nonan) - ; - - _iplUsed = _iplGood / _iplCount; - - _callpal - .init(256) - .name(name() + ".callpal") - .desc("number of callpals executed") - .flags(total | pdf | nozero | nonan) - ; - - for (int i = 0; i < PAL::NumCodes; ++i) { - const char *str = PAL::name(i); - if (str) - _callpal.subname(i, str); - } - - _syscall - .init(SystemCalls::Number) - .name(name() + ".syscall") - .desc("number of syscalls executed") - .flags(total | pdf | nozero | nonan) - ; - - for (int i = 0; i < SystemCalls::Number; ++i) { - const char *str = SystemCalls::name(i); - if (str) { - _syscall.subname(i, str); - } - } - - _mode - .init(cpu_mode_num) - .name(name() + ".mode_switch") - .desc("number of protection mode switches") - ; - - for (int i = 0; i < cpu_mode_num; ++i) - _mode.subname(i, modestr[i]); - - _modeGood - .init(cpu_mode_num) - .name(name() + ".mode_good") - ; - - for (int i = 0; i < cpu_mode_num; ++i) - _modeGood.subname(i, modestr[i]); - - _modeFraction - .name(name() + ".mode_switch_good") - .desc("fraction of useful protection mode switches") - .flags(total) - ; - - for (int i = 0; i < cpu_mode_num; ++i) - _modeFraction.subname(i, modestr[i]); - - _modeFraction = _modeGood / _mode; - - _modeTicks - .init(cpu_mode_num) - .name(name() + ".mode_ticks") - .desc("number of ticks spent at the given mode") - .flags(pdf) - ; - for (int i = 0; i < cpu_mode_num; ++i) - _modeTicks.subname(i, modestr[i]); - - _swap_context - .name(name() + ".swap_context") - .desc("number of times the context was actually changed") - ; -} - -void -Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc) -{ - assert(themode == kernel); - idleProcess = idlepcbb; - themode = idle; - changeMode(themode, tc); -} - -void -Statistics::changeMode(cpu_mode newmode, ThreadContext *tc) -{ - _mode[newmode]++; - - if (newmode == themode) - return; - - DPRINTF(Context, "old mode=%-8s new mode=%-8s\n", - modestr[themode], modestr[newmode]); - - _modeGood[newmode]++; - _modeTicks[themode] += curTick - lastModeTick; - - lastModeTick = curTick; - themode = newmode; -} - -void -Statistics::swpipl(int ipl) -{ - assert(ipl >= 0 && ipl <= 0x1f && "invalid IPL\n"); - - _iplCount[ipl]++; - - if (ipl == iplLast) - return; - - _iplGood[ipl]++; - _iplTicks[iplLast] += curTick - iplLastTick; - iplLastTick = curTick; - iplLast = ipl; -} - -void -Statistics::mode(cpu_mode newmode, ThreadContext *tc) -{ - Addr pcbb = tc->readMiscReg(AlphaISA::IPR_PALtemp23); - - if (newmode == kernel && pcbb == idleProcess) - newmode = idle; - - changeMode(newmode, tc); -} - -void -Statistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc) -{ - assert(themode != user); - - _swap_context++; - changeMode(newpcbb == idleProcess ? idle : kernel, tc); -} - -void -Statistics::callpal(int code, ThreadContext *tc) -{ - if (!PAL::name(code)) - return; - - _callpal[code]++; - - switch (code) { - case PAL::callsys: { - int number = tc->readIntReg(0); - if (SystemCalls::validSyscallNumber(number)) { - int cvtnum = SystemCalls::convert(number); - _syscall[cvtnum]++; - } - } break; - } -} - -void -Statistics::serialize(ostream &os) -{ - int exemode = themode; - SERIALIZE_SCALAR(exemode); - SERIALIZE_SCALAR(idleProcess); - SERIALIZE_SCALAR(iplLast); - SERIALIZE_SCALAR(iplLastTick); - SERIALIZE_SCALAR(lastModeTick); -} - -void -Statistics::unserialize(Checkpoint *cp, const string §ion) -{ - int exemode; - UNSERIALIZE_SCALAR(exemode); - UNSERIALIZE_SCALAR(idleProcess); - UNSERIALIZE_SCALAR(iplLast); - UNSERIALIZE_SCALAR(iplLastTick); - UNSERIALIZE_SCALAR(lastModeTick); - themode = (cpu_mode)exemode; -} - -/* end namespace Kernel */ } diff --git a/src/kern/kernel_stats.hh b/src/kern/kernel_stats.hh deleted file mode 100644 index bd4850b0a..000000000 --- a/src/kern/kernel_stats.hh +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2004-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: Lisa Hsu - * Nathan Binkert - */ - -#ifndef __KERNEL_STATS_HH__ -#define __KERNEL_STATS_HH__ - -#include -#include -#include -#include - -#include "cpu/static_inst.hh" - -class BaseCPU; -class ThreadContext; -class FnEvent; -// What does kernel stats expect is included? -class System; - -namespace Kernel { - -enum cpu_mode { kernel, user, idle, cpu_mode_num }; -extern const char *modestr[]; - -class Statistics : public Serializable -{ - private: - std::string myname; - - Addr idleProcess; - cpu_mode themode; - Tick lastModeTick; - - void changeMode(cpu_mode newmode, ThreadContext *tc); - - private: - Stats::Scalar<> _arm; - Stats::Scalar<> _quiesce; - Stats::Scalar<> _hwrei; - - Stats::Vector<> _iplCount; - Stats::Vector<> _iplGood; - Stats::Vector<> _iplTicks; - Stats::Formula _iplUsed; - - Stats::Vector<> _callpal; - Stats::Vector<> _syscall; -// Stats::Vector<> _faults; - - Stats::Vector<> _mode; - Stats::Vector<> _modeGood; - Stats::Formula _modeFraction; - Stats::Vector<> _modeTicks; - - Stats::Scalar<> _swap_context; - - private: - int iplLast; - Tick iplLastTick; - - public: - Statistics(System *system); - - const std::string name() const { return myname; } - void regStats(const std::string &name); - - public: - void arm() { _arm++; } - void quiesce() { _quiesce++; } - void hwrei() { _hwrei++; } - void swpipl(int ipl); - void mode(cpu_mode newmode, ThreadContext *tc); - void context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc); - void callpal(int code, ThreadContext *tc); - - void setIdleProcess(Addr idle, ThreadContext *tc); - - public: - virtual void serialize(std::ostream &os); - virtual void unserialize(Checkpoint *cp, const std::string §ion); -}; - -/* end namespace Kernel */ } - -#endif // __KERNEL_STATS_HH__ -- cgit v1.2.3 From 54241565167bcab9fd3ae47010e46e7e8ad04826 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:34:14 -0500 Subject: Missed this file in my last changeset. --HG-- extra : convert_revision : 94affbcfb5e5fd948010b10d481627a4dd500267 --- src/SConscript | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/SConscript b/src/SConscript index 58081751d..7907dbb5d 100644 --- a/src/SConscript +++ b/src/SConscript @@ -214,12 +214,6 @@ full_system_sources = Split(''' dev/uart.cc dev/uart8250.cc - kern/kernel_stats.cc - kern/system_events.cc - kern/linux/events.cc - kern/linux/linux_syscalls.cc - kern/linux/printk.cc - mem/vport.cc sim/pseudo_inst.cc @@ -298,6 +292,9 @@ if env['FULL_SYSTEM']: dev_sources = SConscript(os.path.join('dev', 'SConscript'), exports = 'env') full_system_sources += dev_sources + kern_sources = SConscript(os.path.join('kern', 'SConscript'), exports = 'env') + full_system_sources += kern_sources + # This is outside of cpu/SConscript since the source directory isn't # underneath 'cpu'. if 'FullCPU' in env['CPU_MODELS']: -- cgit v1.2.3 From 4bfb8547bbdee3bd0ec23ae067ff04fd5e07f4be Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:36:54 -0500 Subject: Moved the switched version of kernel_stats.hh back to kern, and moved the base kernel_stats to base_kernel_stats --HG-- extra : convert_revision : 2a010d2eb7ea2586ff063b99b8bcde6eb1e8e017 --- src/arch/alpha/ev5.cc | 6 +- src/cpu/checker/thread_context.hh | 9 ++- src/cpu/o3/thread_context.hh | 2 +- src/cpu/o3/thread_context_impl.hh | 2 +- src/cpu/ozone/cpu.hh | 8 ++- src/cpu/ozone/cpu_impl.hh | 2 +- src/cpu/simple_thread.cc | 6 +- src/cpu/simple_thread.hh | 6 +- src/cpu/thread_context.hh | 11 +-- src/cpu/thread_state.hh | 10 +-- src/kern/base_kernel_stats.cc | 147 +------------------------------------- src/kern/base_kernel_stats.hh | 32 ++------- 12 files changed, 44 insertions(+), 197 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 6f8f255b4..76574e2df 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -40,7 +40,7 @@ #include "cpu/base.hh" #include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" -#include "kern/kernel_stats.hh" +#include "kern/alpha/kernel_stats.hh" #include "sim/debug.hh" #include "sim/sim_exit.hh" @@ -379,10 +379,10 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) case AlphaISA::IPR_DTB_CM: if (val & 0x18) { if (tc->getKernelStats()) - tc->getKernelStats()->mode(Kernel::user, tc); + tc->getKernelStats()->mode(TheISA::Kernel::user, tc); } else { if (tc->getKernelStats()) - tc->getKernelStats()->mode(Kernel::kernel, tc); + tc->getKernelStats()->mode(TheISA::Kernel::kernel, tc); } case AlphaISA::IPR_ICM: diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh index b46031167..cf36d8392 100644 --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@ -37,8 +37,10 @@ #include "cpu/thread_context.hh" class EndQuiesceEvent; -namespace Kernel { - class Statistics; +namespace TheISA { + namespace Kernel { + class Statistics; + }; }; /** @@ -91,7 +93,8 @@ class CheckerThreadContext : public ThreadContext TheISA::DTB *getDTBPtr() { return actualTC->getDTBPtr(); } - Kernel::Statistics *getKernelStats() { return actualTC->getKernelStats(); } + TheISA::Kernel::Statistics *getKernelStats() + { return actualTC->getKernelStats(); } FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); } diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index 4556c5e22..daee2fc7d 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -83,7 +83,7 @@ class O3ThreadContext : public ThreadContext virtual PhysicalMemory *getPhysMemPtr() { return cpu->physmem; } /** Returns a pointer to this thread's kernel statistics. */ - virtual Kernel::Statistics *getKernelStats() + virtual TheISA::Kernel::Statistics *getKernelStats() { return thread->kernelStats; } virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); } diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index 81750ada7..8d623f5b8 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -194,7 +194,7 @@ void O3ThreadContext::regStats(const std::string &name) { #if FULL_SYSTEM - thread->kernelStats = new Kernel::Statistics(cpu->system); + thread->kernelStats = new TheISA::Kernel::Statistics(cpu->system); thread->kernelStats->regStats(name + ".kern"); #endif } diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh index b3d3531e9..2b2ed7b3e 100644 --- a/src/cpu/ozone/cpu.hh +++ b/src/cpu/ozone/cpu.hh @@ -62,8 +62,10 @@ class MemoryController; class RemoteGDB; class GDBListener; -namespace Kernel { - class Statistics; +namespace TheISA { + namespace Kernel { + class Statistics; + }; }; #else @@ -127,7 +129,7 @@ class OzoneCPU : public BaseCPU TheISA::DTB * getDTBPtr() { return cpu->dtb; } - Kernel::Statistics *getKernelStats() + TheISA::Kernel::Statistics *getKernelStats() { return thread->getKernelStats(); } FunctionalPort *getPhysPort() { return thread->getPhysPort(); } diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh index 6f5dede3e..b83cf4e9e 100644 --- a/src/cpu/ozone/cpu_impl.hh +++ b/src/cpu/ozone/cpu_impl.hh @@ -891,7 +891,7 @@ void OzoneCPU::OzoneTC::regStats(const std::string &name) { #if FULL_SYSTEM - thread->kernelStats = new Kernel::Statistics(cpu->system); + thread->kernelStats = new TheISA::Kernel::Statistics(cpu->system); thread->kernelStats->regStats(name + ".kern"); #endif } diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 8bb4ec46b..5ae1e1d3c 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -87,7 +87,7 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, profilePC = 3; if (use_kernel_stats) { - kernelStats = new Kernel::Statistics(system); + kernelStats = new TheISA::Kernel::Statistics(system); } else { kernelStats = NULL; } @@ -158,7 +158,7 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext) quiesceEvent->tc = tc; } - Kernel::Statistics *stats = oldContext->getKernelStats(); + TheISA::Kernel::Statistics *stats = oldContext->getKernelStats(); if (stats) { kernelStats = stats; } @@ -179,7 +179,7 @@ SimpleThread::copyTC(ThreadContext *context) if (quiesce) { quiesceEvent = quiesce; } - Kernel::Statistics *stats = context->getKernelStats(); + TheISA::Kernel::Statistics *stats = context->getKernelStats(); if (stats) { kernelStats = stats; } diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 600588295..e8757c8c2 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -55,8 +55,10 @@ class ProfileNode; class FunctionalPort; class PhysicalPort; -namespace Kernel { - class Statistics; +namespace TheISA { + namespace Kernel { + class Statistics; + }; }; #else // !FULL_SYSTEM diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index 82d75b161..1e6a907f8 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -56,8 +56,10 @@ class FunctionalPort; class VirtualPort; class Process; class System; -namespace Kernel { - class Statistics; +namespace TheISA { + namespace Kernel { + class Statistics; + }; }; /** @@ -124,7 +126,7 @@ class ThreadContext virtual TheISA::DTB *getDTBPtr() = 0; - virtual Kernel::Statistics *getKernelStats() = 0; + virtual TheISA::Kernel::Statistics *getKernelStats() = 0; virtual FunctionalPort *getPhysPort() = 0; @@ -295,7 +297,8 @@ class ProxyThreadContext : public ThreadContext TheISA::DTB *getDTBPtr() { return actualTC->getDTBPtr(); } - Kernel::Statistics *getKernelStats() { return actualTC->getKernelStats(); } + TheISA::Kernel::Statistics *getKernelStats() + { return actualTC->getKernelStats(); } FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); } diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh index 862d671f2..0a0af8b71 100644 --- a/src/cpu/thread_state.hh +++ b/src/cpu/thread_state.hh @@ -44,8 +44,10 @@ class EndQuiesceEvent; class FunctionProfile; class ProfileNode; -namespace Kernel { - class Statistics; +namespace TheISA { + namespace Kernel { + class Statistics; + }; }; #endif @@ -97,7 +99,7 @@ struct ThreadState { void profileSample(); - Kernel::Statistics *getKernelStats() { return kernelStats; } + TheISA::Kernel::Statistics *getKernelStats() { return kernelStats; } FunctionalPort *getPhysPort() { return physPort; } @@ -187,7 +189,7 @@ struct ThreadState { Addr profilePC; EndQuiesceEvent *quiesceEvent; - Kernel::Statistics *kernelStats; + TheISA::Kernel::Statistics *kernelStats; protected: /** A functional port outgoing only for functional accesses to physical * addresses.*/ diff --git a/src/kern/base_kernel_stats.cc b/src/kern/base_kernel_stats.cc index f049ed66c..84a38aca5 100644 --- a/src/kern/base_kernel_stats.cc +++ b/src/kern/base_kernel_stats.cc @@ -29,14 +29,11 @@ * Nathan Binkert */ -#include -#include #include -#include "arch/alpha/osfpal.hh" #include "base/trace.hh" #include "cpu/thread_context.hh" -#include "kern/kernel_stats.hh" +#include "kern/base_kernel_stats.hh" #include "kern/tru64/tru64_syscalls.hh" #include "sim/system.hh" @@ -45,11 +42,8 @@ using namespace Stats; namespace Kernel { -const char *modestr[] = { "kernel", "user", "idle" }; - Statistics::Statistics(System *system) - : idleProcess((Addr)-1), themode(kernel), lastModeTick(0), - iplLast(0), iplLastTick(0) + : iplLast(0), iplLastTick(0) { } @@ -68,11 +62,6 @@ Statistics::regStats(const string &_name) .desc("number of quiesce instructions executed") ; - _hwrei - .name(name() + ".inst.hwrei") - .desc("number of hwrei instructions executed") - ; - _iplCount .init(32) .name(name() + ".ipl_count") @@ -102,19 +91,6 @@ Statistics::regStats(const string &_name) _iplUsed = _iplGood / _iplCount; - _callpal - .init(256) - .name(name() + ".callpal") - .desc("number of callpals executed") - .flags(total | pdf | nozero | nonan) - ; - - for (int i = 0; i < PAL::NumCodes; ++i) { - const char *str = PAL::name(i); - if (str) - _callpal.subname(i, str); - } - _syscall .init(SystemCalls::Number) .name(name() + ".syscall") @@ -123,80 +99,11 @@ Statistics::regStats(const string &_name) ; for (int i = 0; i < SystemCalls::Number; ++i) { - const char *str = SystemCalls::name(i); + const char *str = "Please fix me";//SystemCalls::name(i); if (str) { _syscall.subname(i, str); } } - - _mode - .init(cpu_mode_num) - .name(name() + ".mode_switch") - .desc("number of protection mode switches") - ; - - for (int i = 0; i < cpu_mode_num; ++i) - _mode.subname(i, modestr[i]); - - _modeGood - .init(cpu_mode_num) - .name(name() + ".mode_good") - ; - - for (int i = 0; i < cpu_mode_num; ++i) - _modeGood.subname(i, modestr[i]); - - _modeFraction - .name(name() + ".mode_switch_good") - .desc("fraction of useful protection mode switches") - .flags(total) - ; - - for (int i = 0; i < cpu_mode_num; ++i) - _modeFraction.subname(i, modestr[i]); - - _modeFraction = _modeGood / _mode; - - _modeTicks - .init(cpu_mode_num) - .name(name() + ".mode_ticks") - .desc("number of ticks spent at the given mode") - .flags(pdf) - ; - for (int i = 0; i < cpu_mode_num; ++i) - _modeTicks.subname(i, modestr[i]); - - _swap_context - .name(name() + ".swap_context") - .desc("number of times the context was actually changed") - ; -} - -void -Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc) -{ - assert(themode == kernel); - idleProcess = idlepcbb; - themode = idle; - changeMode(themode, tc); -} - -void -Statistics::changeMode(cpu_mode newmode, ThreadContext *tc) -{ - _mode[newmode]++; - - if (newmode == themode) - return; - - DPRINTF(Context, "old mode=%-8s new mode=%-8s\n", - modestr[themode], modestr[newmode]); - - _modeGood[newmode]++; - _modeTicks[themode] += curTick - lastModeTick; - - lastModeTick = curTick; - themode = newmode; } void @@ -215,66 +122,18 @@ Statistics::swpipl(int ipl) iplLast = ipl; } -void -Statistics::mode(cpu_mode newmode, ThreadContext *tc) -{ - Addr pcbb = tc->readMiscReg(AlphaISA::IPR_PALtemp23); - - if (newmode == kernel && pcbb == idleProcess) - newmode = idle; - - changeMode(newmode, tc); -} - -void -Statistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc) -{ - assert(themode != user); - - _swap_context++; - changeMode(newpcbb == idleProcess ? idle : kernel, tc); -} - -void -Statistics::callpal(int code, ThreadContext *tc) -{ - if (!PAL::name(code)) - return; - - _callpal[code]++; - - switch (code) { - case PAL::callsys: { - int number = tc->readIntReg(0); - if (SystemCalls::validSyscallNumber(number)) { - int cvtnum = SystemCalls::convert(number); - _syscall[cvtnum]++; - } - } break; - } -} - void Statistics::serialize(ostream &os) { - int exemode = themode; - SERIALIZE_SCALAR(exemode); - SERIALIZE_SCALAR(idleProcess); SERIALIZE_SCALAR(iplLast); SERIALIZE_SCALAR(iplLastTick); - SERIALIZE_SCALAR(lastModeTick); } void Statistics::unserialize(Checkpoint *cp, const string §ion) { - int exemode; - UNSERIALIZE_SCALAR(exemode); - UNSERIALIZE_SCALAR(idleProcess); UNSERIALIZE_SCALAR(iplLast); UNSERIALIZE_SCALAR(iplLastTick); - UNSERIALIZE_SCALAR(lastModeTick); - themode = (cpu_mode)exemode; } /* end namespace Kernel */ } diff --git a/src/kern/base_kernel_stats.hh b/src/kern/base_kernel_stats.hh index bd4850b0a..66248c9c8 100644 --- a/src/kern/base_kernel_stats.hh +++ b/src/kern/base_kernel_stats.hh @@ -32,12 +32,10 @@ #ifndef __KERNEL_STATS_HH__ #define __KERNEL_STATS_HH__ -#include -#include #include -#include #include "cpu/static_inst.hh" +#include "sim/serialize.hh" class BaseCPU; class ThreadContext; @@ -47,21 +45,12 @@ class System; namespace Kernel { -enum cpu_mode { kernel, user, idle, cpu_mode_num }; -extern const char *modestr[]; - class Statistics : public Serializable { - private: + protected: std::string myname; - Addr idleProcess; - cpu_mode themode; - Tick lastModeTick; - - void changeMode(cpu_mode newmode, ThreadContext *tc); - - private: + protected: Stats::Scalar<> _arm; Stats::Scalar<> _quiesce; Stats::Scalar<> _hwrei; @@ -71,23 +60,16 @@ class Statistics : public Serializable Stats::Vector<> _iplTicks; Stats::Formula _iplUsed; - Stats::Vector<> _callpal; Stats::Vector<> _syscall; // Stats::Vector<> _faults; - Stats::Vector<> _mode; - Stats::Vector<> _modeGood; - Stats::Formula _modeFraction; - Stats::Vector<> _modeTicks; - - Stats::Scalar<> _swap_context; - private: int iplLast; Tick iplLastTick; public: Statistics(System *system); + virtual ~Statistics() {} const std::string name() const { return myname; } void regStats(const std::string &name); @@ -95,13 +77,7 @@ class Statistics : public Serializable public: void arm() { _arm++; } void quiesce() { _quiesce++; } - void hwrei() { _hwrei++; } void swpipl(int ipl); - void mode(cpu_mode newmode, ThreadContext *tc); - void context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc); - void callpal(int code, ThreadContext *tc); - - void setIdleProcess(Addr idle, ThreadContext *tc); public: virtual void serialize(std::ostream &os); -- cgit v1.2.3 From da24915181516740e94efc7de4d9e9263c663e0d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:38:33 -0500 Subject: Moved the idle event out of system_events.hh. The skipFuncEvent can be made ISA independent by making it use the #define for branch delay slots (and NNPC) --HG-- extra : convert_revision : b2631b1163397ecc99f2f315e2b88537e2002731 --- src/arch/alpha/linux/system.cc | 1 + src/arch/alpha/linux/system.hh | 1 + src/kern/alpha/idle_event.cc | 45 ++++++++++++++++++++++++++++++++++++++++ src/kern/alpha/idle_event.hh | 47 ++++++++++++++++++++++++++++++++++++++++++ src/kern/system_events.cc | 19 +---------------- src/kern/system_events.hh | 11 ---------- 6 files changed, 95 insertions(+), 29 deletions(-) create mode 100644 src/kern/alpha/idle_event.cc create mode 100644 src/kern/alpha/idle_event.hh (limited to 'src') diff --git a/src/arch/alpha/linux/system.cc b/src/arch/alpha/linux/system.cc index 7cf234eeb..00684edbb 100644 --- a/src/arch/alpha/linux/system.cc +++ b/src/arch/alpha/linux/system.cc @@ -49,6 +49,7 @@ #include "cpu/thread_context.hh" #include "cpu/base.hh" #include "dev/platform.hh" +#include "kern/alpha/idle_event.hh" #include "kern/linux/printk.hh" #include "kern/linux/events.hh" #include "mem/physical.hh" diff --git a/src/arch/alpha/linux/system.hh b/src/arch/alpha/linux/system.hh index 6921ba820..d4c92ac01 100644 --- a/src/arch/alpha/linux/system.hh +++ b/src/arch/alpha/linux/system.hh @@ -39,6 +39,7 @@ class BreakPCEvent; class IdleStartEvent; #include "arch/alpha/system.hh" +#include "kern/alpha/idle_event.hh" #include "kern/linux/events.hh" using namespace AlphaISA; diff --git a/src/kern/alpha/idle_event.cc b/src/kern/alpha/idle_event.cc new file mode 100644 index 000000000..3f07b6c16 --- /dev/null +++ b/src/kern/alpha/idle_event.cc @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2004-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: Lisa Hsu + * Nathan Binkert + */ + +#include "cpu/thread_context.hh" +#include "kern/alpha/idle_event.hh" +#include "kern/kernel_stats.hh" + +using namespace TheISA; + +void +IdleStartEvent::process(ThreadContext *tc) +{ + if (tc->getKernelStats()) + tc->getKernelStats()->setIdleProcess( + tc->readMiscReg(AlphaISA::IPR_PALtemp23), tc); + remove(); +} diff --git a/src/kern/alpha/idle_event.hh b/src/kern/alpha/idle_event.hh new file mode 100644 index 000000000..97d5bdd6e --- /dev/null +++ b/src/kern/alpha/idle_event.hh @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2004-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: Nathan Binkert + * Lisa Hsu + * Ali Saidi + */ + +#ifndef __KERN_ALPHA_IDLE_EVENT_HH__ +#define __KERN_ALPHA_IDLE_EVENT_HH__ + +#include "cpu/pc_event.hh" + +class IdleStartEvent : public PCEvent +{ + public: + IdleStartEvent(PCEventQueue *q, const std::string &desc, Addr addr) + : PCEvent(q, desc, addr) + {} + virtual void process(ThreadContext *tc); +}; + +#endif // __KERN_ALPHA_IDLE_EVENT_HH__ diff --git a/src/kern/system_events.cc b/src/kern/system_events.cc index 177ce96d1..a6337a2fd 100644 --- a/src/kern/system_events.cc +++ b/src/kern/system_events.cc @@ -29,11 +29,9 @@ * Nathan Binkert */ -#include "cpu/base.hh" +#include "base/trace.hh" #include "cpu/thread_context.hh" -#include "kern/kernel_stats.hh" #include "kern/system_events.hh" -#include "sim/system.hh" using namespace TheISA; @@ -47,19 +45,4 @@ SkipFuncEvent::process(ThreadContext *tc) tc->setPC(newpc); tc->setNextPC(tc->readPC() + sizeof(TheISA::MachInst)); -/* - BranchPred *bp = tc->getCpuPtr()->getBranchPred(); - if (bp != NULL) { - bp->popRAS(tc->getThreadNum()); - } -*/ -} - -void -IdleStartEvent::process(ThreadContext *tc) -{ - if (tc->getKernelStats()) - tc->getKernelStats()->setIdleProcess( - tc->readMiscReg(AlphaISA::IPR_PALtemp23), tc); - remove(); } diff --git a/src/kern/system_events.hh b/src/kern/system_events.hh index 93b5eb528..58cbc4808 100644 --- a/src/kern/system_events.hh +++ b/src/kern/system_events.hh @@ -35,8 +35,6 @@ #include "cpu/pc_event.hh" -class System; - class SkipFuncEvent : public PCEvent { public: @@ -46,13 +44,4 @@ class SkipFuncEvent : public PCEvent virtual void process(ThreadContext *tc); }; -class IdleStartEvent : public PCEvent -{ - public: - IdleStartEvent(PCEventQueue *q, const std::string &desc, Addr addr) - : PCEvent(q, desc, addr) - {} - virtual void process(ThreadContext *tc); -}; - #endif // __SYSTEM_EVENTS_HH__ -- cgit v1.2.3 From 54e22bfe9591ef6e83613757dd43c4cce2255cef Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:39:40 -0500 Subject: Broke remote_gdb into a base class and architecture specific derived classes. --HG-- extra : convert_revision : 8c528fab56a95b8245ad0f2572d62bb556ce0dde --- src/arch/alpha/remote_gdb.cc | 137 +++----------------------- src/arch/alpha/remote_gdb.hh | 60 +----------- src/arch/sparc/remote_gdb.cc | 222 +++++-------------------------------------- src/arch/sparc/remote_gdb.hh | 80 ++++------------ src/base/remote_gdb.cc | 15 +++ src/base/remote_gdb.hh | 4 + 6 files changed, 73 insertions(+), 445 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc index 96c7ea6e2..829e41ca8 100644 --- a/src/arch/alpha/remote_gdb.cc +++ b/src/arch/alpha/remote_gdb.cc @@ -121,8 +121,9 @@ #include #include -#include "arch/vtophys.hh" +#include "arch/alpha/kgdb.h" #include "arch/alpha/remote_gdb.hh" +#include "arch/vtophys.hh" #include "base/intmath.hh" #include "base/remote_gdb.hh" #include "base/socket.hh" @@ -135,30 +136,12 @@ #include "sim/system.hh" using namespace std; -using namespace AlphaISA; - -RemoteGDB::Event::Event(RemoteGDB *g, int fd, int e) - : PollEvent(fd, e), gdb(g) -{} - -void -RemoteGDB::Event::process(int revent) -{ - if (revent & POLLIN) - gdb->trap(ALPHA_KENTRY_IF); - else if (revent & POLLNVAL) - gdb->detach(); -} +using namespace TheISA; RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) - : BaseRemoteGDB(_system, c, KGDB_NUMREGS), - event(NULL) -{} - -RemoteGDB::~RemoteGDB() + : BaseRemoteGDB(_system, c, KGDB_NUMREGS) { - if (event) - delete event; + memset(gdbregs.regs, 0, gdbregs.size); } /////////////////////////////////////////////////////////// @@ -268,36 +251,16 @@ RemoteGDB::setregs() context->setPC(gdbregs.regs[KGDB_REG_PC]); } -void -RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr) -{ - DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", addr); - - bkpt.address = addr; - insertHardBreak(addr, 4); -} - -void -RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt) -{ - DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", - bkpt.address); - - - removeHardBreak(bkpt.address, 4); - bkpt.address = 0; -} - void RemoteGDB::clearSingleStep() { DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n", - takenBkpt.address, notTakenBkpt.address); + takenBkpt, notTakenBkpt); - if (takenBkpt.address != 0) + if (takenBkpt != 0) clearTempBreakpoint(takenBkpt); - if (notTakenBkpt.address != 0) + if (notTakenBkpt != 0) clearTempBreakpoint(notTakenBkpt); } @@ -322,12 +285,12 @@ RemoteGDB::setSingleStep() } DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n", - takenBkpt.address, notTakenBkpt.address); + takenBkpt, notTakenBkpt); - setTempBreakpoint(notTakenBkpt, npc); + setTempBreakpoint(notTakenBkpt = npc); if (set_bt) - setTempBreakpoint(takenBkpt, bpc); + setTempBreakpoint(takenBkpt = bpc); } // Write bytes to kernel address space for debugger. @@ -344,81 +307,3 @@ RemoteGDB::write(Addr vaddr, size_t size, const char *data) } } - -PCEventQueue *RemoteGDB::getPcEventQueue() -{ - return &system->pcEventQueue; -} - - -RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc) - : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc), - gdb(_gdb), refcount(0) -{ - DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc); -} - -void -RemoteGDB::HardBreakpoint::process(ThreadContext *tc) -{ - DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc()); - - if (tc == gdb->context) - gdb->trap(ALPHA_KENTRY_INT); -} - -bool -RemoteGDB::insertSoftBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - return insertHardBreak(addr, len); -} - -bool -RemoteGDB::removeSoftBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - return removeHardBreak(addr, len); -} - -bool -RemoteGDB::insertHardBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - DPRINTF(GDBMisc, "inserting hardware breakpoint at %#x\n", addr); - - HardBreakpoint *&bkpt = hardBreakMap[addr]; - if (bkpt == 0) - bkpt = new HardBreakpoint(this, addr); - - bkpt->refcount++; - - return true; -} - -bool -RemoteGDB::removeHardBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - DPRINTF(GDBMisc, "removing hardware breakpoint at %#x\n", addr); - - break_iter_t i = hardBreakMap.find(addr); - if (i == hardBreakMap.end()) - return false; - - HardBreakpoint *hbp = (*i).second; - if (--hbp->refcount == 0) { - delete hbp; - hardBreakMap.erase(i); - } - - return true; -} diff --git a/src/arch/alpha/remote_gdb.hh b/src/arch/alpha/remote_gdb.hh index 1dd4ada38..7bef183c3 100644 --- a/src/arch/alpha/remote_gdb.hh +++ b/src/arch/alpha/remote_gdb.hh @@ -48,31 +48,12 @@ namespace AlphaISA { class RemoteGDB : public BaseRemoteGDB { - private: - friend void debugger(); - friend class GDBListener; - - protected: - class Event : public PollEvent - { - protected: - RemoteGDB *gdb; - - public: - Event(RemoteGDB *g, int fd, int e); - void process(int revent); - }; - - friend class Event; - Event *event; - protected: // Machine memory bool write(Addr addr, size_t size, const char *data); public: RemoteGDB(System *system, ThreadContext *context); - ~RemoteGDB(); bool acc(Addr addr, size_t len); @@ -83,47 +64,10 @@ namespace AlphaISA void clearSingleStep(); void setSingleStep(); - PCEventQueue *getPcEventQueue(); - - protected: - class HardBreakpoint : public PCEvent - { - private: - RemoteGDB *gdb; - - public: - int refcount; - - public: - HardBreakpoint(RemoteGDB *_gdb, Addr addr); - std::string name() { return gdb->name() + ".hwbkpt"; } - - virtual void process(ThreadContext *tc); - }; - friend class HardBreakpoint; - - typedef std::map break_map_t; - typedef break_map_t::iterator break_iter_t; - break_map_t hardBreakMap; - - bool insertSoftBreak(Addr addr, size_t len); - bool removeSoftBreak(Addr addr, size_t len); - bool insertHardBreak(Addr addr, size_t len); - bool removeHardBreak(Addr addr, size_t len); - protected: - struct TempBreakpoint { - Addr address; // set here - MachInst bkpt_inst; // saved instruction at bkpt - int init_count; // number of times to skip bkpt - int count; // current count - }; - - TempBreakpoint notTakenBkpt; - TempBreakpoint takenBkpt; - void clearTempBreakpoint(TempBreakpoint &bkpt); - void setTempBreakpoint(TempBreakpoint &bkpt, Addr addr); + Addr notTakenBkpt; + Addr takenBkpt; }; } diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc index 2e662af7f..5f9c532b8 100644 --- a/src/arch/sparc/remote_gdb.cc +++ b/src/arch/sparc/remote_gdb.cc @@ -124,7 +124,6 @@ #include "arch/vtophys.hh" #include "arch/sparc/remote_gdb.hh" #include "base/intmath.hh" -#include "base/kgdb.h" #include "base/remote_gdb.hh" #include "base/socket.hh" #include "base/trace.hh" @@ -138,30 +137,10 @@ using namespace std; using namespace TheISA; -RemoteGDB::Event::Event(RemoteGDB *g, int fd, int e) - : PollEvent(fd, e), gdb(g) -{} - -void -RemoteGDB::Event::process(int revent) -{ - if (revent & POLLIN) - gdb->trap(ALPHA_KENTRY_IF); - else if (revent & POLLNVAL) - gdb->detach(); -} - RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) - : BaseRemoteGDB(_system, c, KGDB_NUMREGS), - event(NULL) + : BaseRemoteGDB(_system, c, NumGDBRegs) {} -RemoteGDB::~RemoteGDB() -{ - if (event) - delete event; -} - /////////////////////////////////////////////////////////// // RemoteGDB::acc // @@ -170,6 +149,7 @@ RemoteGDB::~RemoteGDB() bool RemoteGDB::acc(Addr va, size_t len) { +#if 0 Addr last_va; va = TheISA::TruncPage(va); @@ -208,40 +188,10 @@ RemoteGDB::acc(Addr va, size_t len) } while (va < last_va); DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va); +#endif return true; } -/////////////////////////////////////////////////////////// -// RemoteGDB::signal -// -// Translate a trap number into a Unix-compatible signal number. -// (GDB only understands Unix signal numbers.) -// -int -RemoteGDB::signal(int type) -{ - switch (type) { - case ALPHA_KENTRY_INT: - return (SIGTRAP); - - case ALPHA_KENTRY_UNA: - return (SIGBUS); - - case ALPHA_KENTRY_ARITH: - return (SIGFPE); - - case ALPHA_KENTRY_IF: - return (SIGILL); - - case ALPHA_KENTRY_MM: - return (SIGSEGV); - - default: - panic("unknown signal type"); - return 0; - } -} - /////////////////////////////////////////////////////////// // RemoteGDB::getregs // @@ -252,24 +202,14 @@ RemoteGDB::getregs() { memset(gdbregs.regs, 0, gdbregs.size); - gdbregs.regs[KGDB_REG_PC] = context->readPC(); - - // @todo: Currently this is very Alpha specific. - if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { - gdbregs.regs[i] = context->readIntReg(AlphaISA::reg_redir[i]); - } - } else { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { - gdbregs.regs[i] = context->readIntReg(i); - } - } - -#ifdef KGDB_FP_REGS - for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { - gdbregs.regs[i + KGDB_REG_F0] = context->readFloatRegBits(i); - } -#endif + gdbregs.regs[RegPc] = context->readPC(); + gdbregs.regs[RegNpc] = context->readNextPC(); + for(int x = RegG0; x <= RegI7; x++) + gdbregs.regs[x] = context->readIntReg(x - RegG0); + for(int x = RegF0; x <= RegF31; x++) + gdbregs.regs[x] = context->readFloatRegBits(x - RegF0); + gdbregs.regs[RegY] = context->readMiscReg(MISCREG_Y); + //XXX need to also load up Psr, Wim, Tbr, Fpsr, and Cpsr } /////////////////////////////////////////////////////////// @@ -281,48 +221,20 @@ RemoteGDB::getregs() void RemoteGDB::setregs() { - // @todo: Currently this is very Alpha specific. - if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { - context->setIntReg(AlphaISA::reg_redir[i], gdbregs.regs[i]); - } - } else { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { - context->setIntReg(i, gdbregs.regs[i]); - } - } - -#ifdef KGDB_FP_REGS - for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { - context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]); - } -#endif - context->setPC(gdbregs.regs[KGDB_REG_PC]); -} - -void -RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr) -{ - DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", addr); - - bkpt.address = addr; - insertHardBreak(addr, 4); -} - -void -RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt) -{ - DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", - bkpt.address); - - - removeHardBreak(bkpt.address, 4); - bkpt.address = 0; + context->setPC(gdbregs.regs[RegPc]); + context->setNextPC(gdbregs.regs[RegNpc]); + for(int x = RegG0; x <= RegI7; x++) + context->setIntReg(x - RegG0, gdbregs.regs[x]); + for(int x = RegF0; x <= RegF31; x++) + context->setFloatRegBits(x - RegF0, gdbregs.regs[x]); + context->setMiscRegWithEffect(MISCREG_Y, gdbregs.regs[RegY]); + //XXX need to also set Psr, Wim, Tbr, Fpsr, and Cpsr } void RemoteGDB::clearSingleStep() { +#if 0 DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n", takenBkpt.address, notTakenBkpt.address); @@ -331,11 +243,13 @@ RemoteGDB::clearSingleStep() if (notTakenBkpt.address != 0) clearTempBreakpoint(notTakenBkpt); +#endif } void RemoteGDB::setSingleStep() { +#if 0 Addr pc = context->readPC(); Addr npc, bpc; bool set_bt = false; @@ -360,97 +274,5 @@ RemoteGDB::setSingleStep() if (set_bt) setTempBreakpoint(takenBkpt, bpc); -} - -// Write bytes to kernel address space for debugger. -bool -RemoteGDB::write(Addr vaddr, size_t size, const char *data) -{ - if (BaseRemoteGDB::write(vaddr, size, data)) { -#ifdef IMB - alpha_pal_imb(); #endif - return true; - } else { - return false; - } -} - - -PCEventQueue *RemoteGDB::getPcEventQueue() -{ - return &system->pcEventQueue; -} - - -RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc) - : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc), - gdb(_gdb), refcount(0) -{ - DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc); -} - -void -RemoteGDB::HardBreakpoint::process(ThreadContext *tc) -{ - DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc()); - - if (tc == gdb->context) - gdb->trap(ALPHA_KENTRY_INT); -} - -bool -RemoteGDB::insertSoftBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - return insertHardBreak(addr, len); -} - -bool -RemoteGDB::removeSoftBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - return removeHardBreak(addr, len); -} - -bool -RemoteGDB::insertHardBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - DPRINTF(GDBMisc, "inserting hardware breakpoint at %#x\n", addr); - - HardBreakpoint *&bkpt = hardBreakMap[addr]; - if (bkpt == 0) - bkpt = new HardBreakpoint(this, addr); - - bkpt->refcount++; - - return true; -} - -bool -RemoteGDB::removeHardBreak(Addr addr, size_t len) -{ - if (len != sizeof(MachInst)) - panic("invalid length\n"); - - DPRINTF(GDBMisc, "removing hardware breakpoint at %#x\n", addr); - - break_iter_t i = hardBreakMap.find(addr); - if (i == hardBreakMap.end()) - return false; - - HardBreakpoint *hbp = (*i).second; - if (--hbp->refcount == 0) { - delete hbp; - hardBreakMap.erase(i); - } - - return true; } diff --git a/src/arch/sparc/remote_gdb.hh b/src/arch/sparc/remote_gdb.hh index 6ac4f296f..3ded1e218 100644 --- a/src/arch/sparc/remote_gdb.hh +++ b/src/arch/sparc/remote_gdb.hh @@ -46,34 +46,32 @@ namespace SparcISA { class RemoteGDB : public BaseRemoteGDB { - private: - friend void debugger(); - friend class GDBListener; - protected: - class Event : public PollEvent + enum RegisterConstants { - protected: - RemoteGDB *gdb; - - public: - Event(RemoteGDB *g, int fd, int e); - void process(int revent); + RegG0, RegG1, RegG2, RegG3, RegG4, RegG5, RegG6, RegG7, + RegO0, RegO1, RegO2, RegO3, RegO4, RegO5, RegO6, RegO7, + RegL0, RegL1, RegL2, RegL3, RegL4, RegL5, RegL6, RegL7, + RegI0, RegI1, RegI2, RegI3, RegI4, RegI5, RegI6, RegI7, + RegF0, RegF1, RegF2, RegF3, RegF4, RegF5, RegF6, RegF7, + RegF8, RegF9, RegF10, RegF11, RegF12, RegF13, RegF14, RegF15, + RegF16, RegF17, RegF18, RegF19, RegF20, RegF21, RegF22, RegF23, + RegF24, RegF25, RegF26, RegF27, RegF28, RegF29, RegF30, RegF31, + RegY, + RegPsr, + RegWim, + RegTbr, + RegPc, + RegNpc, + RegFpsr, + RegCpsr, + NumGDBRegs }; - friend class Event; - Event *event; - - protected: - // Machine memory - bool write(Addr addr, size_t size, const char *data); - public: RemoteGDB(System *system, ThreadContext *context); - ~RemoteGDB(); bool acc(Addr addr, size_t len); - int signal(int type); protected: void getregs(); @@ -82,47 +80,7 @@ namespace SparcISA void clearSingleStep(); void setSingleStep(); - PCEventQueue *getPcEventQueue(); - - protected: - class HardBreakpoint : public PCEvent - { - private: - RemoteGDB *gdb; - - public: - int refcount; - - public: - HardBreakpoint(RemoteGDB *_gdb, Addr addr); - std::string name() { return gdb->name() + ".hwbkpt"; } - - virtual void process(ThreadContext *tc); - }; - friend class HardBreakpoint; - - typedef std::map break_map_t; - typedef break_map_t::iterator break_iter_t; - break_map_t hardBreakMap; - - bool insertSoftBreak(Addr addr, size_t len); - bool removeSoftBreak(Addr addr, size_t len); - bool insertHardBreak(Addr addr, size_t len); - bool removeHardBreak(Addr addr, size_t len); - - protected: - struct TempBreakpoint { - Addr address; // set here - MachInst bkpt_inst; // saved instruction at bkpt - int init_count; // number of times to skip bkpt - int count; // current count - }; - - TempBreakpoint notTakenBkpt; - TempBreakpoint takenBkpt; - - void clearTempBreakpoint(TempBreakpoint &bkpt); - void setTempBreakpoint(TempBreakpoint &bkpt, Addr addr); + Addr singleStepBreaks[2]; }; } diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index 01166d46f..fae814904 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -571,6 +571,21 @@ BaseRemoteGDB::removeHardBreak(Addr addr, size_t len) return true; } +void +BaseRemoteGDB::setTempBreakpoint(Addr bkpt) +{ + DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt); + insertHardBreak(bkpt, sizeof(TheISA::MachInst)); +} + +void +BaseRemoteGDB::clearTempBreakpoint(Addr &bkpt) +{ + DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", bkpt); + removeHardBreak(bkpt, sizeof(TheISA::MachInst)); + bkpt = 0; +} + const char * BaseRemoteGDB::break_type(char c) { diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh index 65e4313eb..4a1754afd 100644 --- a/src/base/remote_gdb.hh +++ b/src/base/remote_gdb.hh @@ -212,6 +212,10 @@ class BaseRemoteGDB bool insertHardBreak(Addr addr, size_t len); bool removeHardBreak(Addr addr, size_t len); + protected: + void clearTempBreakpoint(Addr &bkpt); + void setTempBreakpoint(Addr bkpt); + public: std::string name(); }; -- cgit v1.2.3 From bcd5099aace33750d38d4270ceb93c000ac2288e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:40:06 -0500 Subject: Added in alot of missing source files. --HG-- extra : convert_revision : 335b458d195a00dac3d04e92fe9df915e660538f --- src/arch/sparc/SConscript | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript index 5843058a4..281c166c0 100644 --- a/src/arch/sparc/SConscript +++ b/src/arch/sparc/SConscript @@ -54,8 +54,12 @@ base_sources = Split(''' # Full-system sources full_system_sources = Split(''' - vtophys.cc + arguments.cc + remote_gdb.cc + stacktrace.cc system.cc + tlb.cc + vtophys.cc ''') # Syscall emulation (non-full-system) sources -- cgit v1.2.3 From 0c9bcf209a2d169dbd37f576c2f3c6f74deda192 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:40:48 -0500 Subject: The normal spill and fill faults only need to behave specially in SE. --HG-- extra : convert_revision : 4d4b866699e3450b88418822fc198411ee3d831a --- src/arch/sparc/faults.hh | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index 0c7106707..b25b7706e 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -548,7 +548,10 @@ class SpillNNormal : public EnumeratedFault FaultName name() {return _name;} FaultPriority priority() {return _priority;} FaultStat & countStat() {return _count;} + //These need to be handled specially to enable spill traps in SE +#if !FULL_SYSTEM void invoke(ThreadContext * tc); +#endif }; class SpillNOther : public EnumeratedFault @@ -579,7 +582,10 @@ class FillNNormal : public EnumeratedFault FaultName name() {return _name;} FaultPriority priority() {return _priority;} FaultStat & countStat() {return _count;} + //These need to be handled specially to enable fill traps in SE +#if !FULL_SYSTEM void invoke(ThreadContext * tc); +#endif }; class FillNOther : public EnumeratedFault -- cgit v1.2.3 From 74112dec522ace81203966b40d1e4b34773b01db Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:41:23 -0500 Subject: Added a stub implementation of fixFuncEventAddr to get past linker errors. --HG-- extra : convert_revision : 24ab1789496c5fae6c0992db2d521ea02354ee90 --- src/arch/sparc/system.hh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/system.hh b/src/arch/sparc/system.hh index 3c8c6327e..0b79eda38 100644 --- a/src/arch/sparc/system.hh +++ b/src/arch/sparc/system.hh @@ -111,8 +111,11 @@ class SparcSystem : public System return addFuncEvent(openbootSymtab, lbl); } - virtual Addr fixFuncEventAddr(Addr addr); - + virtual Addr fixFuncEventAddr(Addr addr) + { + //XXX This may eventually have to do something useful. + return addr; + } }; #endif -- cgit v1.2.3 From 3826b6927c5c8863b344f1a36f2f145861c450bd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:41:51 -0500 Subject: Got rid of a stray blank line. --HG-- extra : convert_revision : 7b58f75e5efc3c9ead2434f87605cbabcb23d90a --- src/cpu/o3/regfile.hh | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh index 29ee19e49..772cd76f0 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -40,7 +40,6 @@ #if FULL_SYSTEM #include "kern/kernel_stats.hh" - #endif #include -- cgit v1.2.3 From 2f4c66ad2d1ddf7c3295cd176ce39aa4d3fcb816 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:42:15 -0500 Subject: Added sim/host.hh for the Addr type. --HG-- extra : convert_revision : cd07a920417b7fb34e5ca3bf70d707327eb59eb3 --- src/cpu/pc_event.hh | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/cpu/pc_event.hh b/src/cpu/pc_event.hh index 6b048b2c2..3709dcd59 100644 --- a/src/cpu/pc_event.hh +++ b/src/cpu/pc_event.hh @@ -35,6 +35,7 @@ #include #include "base/misc.hh" +#include "sim/host.hh" class ThreadContext; class PCEventQueue; -- cgit v1.2.3 From 5411fbe6e8b96cc0f793465ba07442eb1038bac1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:42:52 -0500 Subject: Removed unnecessary arch/alpha/ev5.hh include --HG-- extra : convert_revision : e8277cc279be839c1754b5da96f9153da06d3ec1 --- src/dev/ns_gige.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc index 19c553d87..74f9d88d1 100644 --- a/src/dev/ns_gige.cc +++ b/src/dev/ns_gige.cc @@ -36,7 +36,6 @@ #include #include -#include "arch/alpha/ev5.hh" #include "base/inet.hh" #include "cpu/thread_context.hh" #include "dev/etherlink.hh" -- cgit v1.2.3 From 7e422980e9f37603a4453567a319865b93be4527 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:43:33 -0500 Subject: Arguments class for SPARC. This is basically just a copy of Alpha's --HG-- extra : convert_revision : 9df68973c63d5ff256d6de485e8d918c454c8ff1 --- src/arch/sparc/arguments.cc | 71 +++++++++++++++++++++ src/arch/sparc/arguments.hh | 149 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 220 insertions(+) create mode 100644 src/arch/sparc/arguments.cc create mode 100644 src/arch/sparc/arguments.hh (limited to 'src') diff --git a/src/arch/sparc/arguments.cc b/src/arch/sparc/arguments.cc new file mode 100644 index 000000000..a0a31567e --- /dev/null +++ b/src/arch/sparc/arguments.cc @@ -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: Nathan Binkert + */ + +#include "arch/sparc/arguments.hh" +#include "arch/sparc/vtophys.hh" +#include "cpu/thread_context.hh" +#include "mem/vport.hh" + +using namespace SparcISA; + +Arguments::Data::~Data() +{ + while (!data.empty()) { + delete [] data.front(); + data.pop_front(); + } +} + +char * +Arguments::Data::alloc(size_t size) +{ + char *buf = new char[size]; + data.push_back(buf); + return buf; +} + +uint64_t +Arguments::getArg(bool fp) +{ + //XXX This needs to be replaced with the sparc version + if (number < 6) { + if (fp) + return tc->readFloatRegBits(16 + number); + else + return tc->readIntReg(16 + number); + } else { + Addr sp = tc->readIntReg(30); + VirtualPort *vp = tc->getVirtPort(tc); + uint64_t arg = vp->read(sp + (number-6) * sizeof(uint64_t)); + tc->delVirtPort(vp); + return arg; + } +} + diff --git a/src/arch/sparc/arguments.hh b/src/arch/sparc/arguments.hh new file mode 100644 index 000000000..0d059a564 --- /dev/null +++ b/src/arch/sparc/arguments.hh @@ -0,0 +1,149 @@ +/* + * 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: Nathan Binkert + */ + +#ifndef __ARCH_SPARC_ARGUMENTS_HH__ +#define __ARCH_SPARC_ARGUMENTS_HH__ + +#include + +#include "arch/sparc/vtophys.hh" +#include "base/refcnt.hh" +#include "sim/host.hh" + +class ThreadContext; + +namespace SparcISA { + +class Arguments +{ + protected: + ThreadContext *tc; + int number; + uint64_t getArg(bool fp = false); + + protected: + class Data : public RefCounted + { + public: + Data(){} + ~Data(); + + private: + std::list data; + + public: + char *alloc(size_t size); + }; + + RefCountingPtr data; + + public: + Arguments(ThreadContext *ctx, int n = 0) + : tc(ctx), number(n), data(NULL) + { assert(number >= 0); data = new Data;} + Arguments(const Arguments &args) + : tc(args.tc), number(args.number), data(args.data) {} + ~Arguments() {} + + ThreadContext *getThreadContext() const { return tc; } + + const Arguments &operator=(const Arguments &args) { + tc = args.tc; + number = args.number; + data = args.data; + return *this; + } + + Arguments &operator++() { + ++number; + assert(number >= 0); + return *this; + } + + Arguments operator++(int) { + Arguments args = *this; + ++number; + assert(number >= 0); + return args; + } + + Arguments &operator--() { + --number; + assert(number >= 0); + return *this; + } + + Arguments operator--(int) { + Arguments args = *this; + --number; + assert(number >= 0); + return args; + } + + const Arguments &operator+=(int index) { + number += index; + assert(number >= 0); + return *this; + } + + const Arguments &operator-=(int index) { + number -= index; + assert(number >= 0); + return *this; + } + + Arguments operator[](int index) { + return Arguments(tc, index); + } + + template + operator T() { + assert(sizeof(T) <= sizeof(uint64_t)); + T data = static_cast(getArg()); + return data; + } + + template + operator T *() { + T *buf = (T *)data->alloc(sizeof(T)); + CopyData(tc, buf, getArg(), sizeof(T)); + return buf; + } + + operator char *() { + char *buf = data->alloc(2048); + CopyStringOut(tc, buf, getArg(), 2048); + return buf; + } +}; + +}; // namespace AlphaISA + +#endif // __ARCH_ALPHA_ARGUMENTS_HH__ -- cgit v1.2.3 From 48415ad2985d5b9fcd671a009c0f00afbe3c0abf Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:44:22 -0500 Subject: A dummy implementation of stacktrace.cc to clear up linker errors. --HG-- extra : convert_revision : ea1e54a529ad7ae4a6564dd6fb47c31fb0573adf --- src/arch/sparc/stacktrace.cc | 371 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100644 src/arch/sparc/stacktrace.cc (limited to 'src') diff --git a/src/arch/sparc/stacktrace.cc b/src/arch/sparc/stacktrace.cc new file mode 100644 index 000000000..0985eb149 --- /dev/null +++ b/src/arch/sparc/stacktrace.cc @@ -0,0 +1,371 @@ +/* + * Copyright (c) 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: Nathan Binkert + */ + +#include + +#include "arch/sparc/isa_traits.hh" +#include "arch/sparc/stacktrace.hh" +#include "arch/sparc/vtophys.hh" +#include "base/bitfield.hh" +#include "base/trace.hh" +#include "cpu/base.hh" +#include "cpu/thread_context.hh" +#include "sim/system.hh" + +using namespace std; +using namespace SparcISA; + +ProcessInfo::ProcessInfo(ThreadContext *_tc) + : tc(_tc) +{ + Addr addr = 0; + + VirtualPort *vp; + + vp = tc->getVirtPort(); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) + panic("thread info not compiled into kernel\n"); + thread_info_size = vp->readGtoH(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) + panic("thread info not compiled into kernel\n"); + task_struct_size = vp->readGtoH(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) + panic("thread info not compiled into kernel\n"); + task_off = vp->readGtoH(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) + panic("thread info not compiled into kernel\n"); + pid_off = vp->readGtoH(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) + panic("thread info not compiled into kernel\n"); + name_off = vp->readGtoH(addr); + + tc->delVirtPort(vp); +} + +Addr +ProcessInfo::task(Addr ksp) const +{ + Addr base = ksp & ~0x3fff; + if (base == ULL(0xfffffc0000000000)) + return 0; + + Addr tsk; + + VirtualPort *vp; + + vp = tc->getVirtPort(); + tsk = vp->readGtoH(base + task_off); + tc->delVirtPort(vp); + + return tsk; +} + +int +ProcessInfo::pid(Addr ksp) const +{ + Addr task = this->task(ksp); + if (!task) + return -1; + + uint16_t pd; + + VirtualPort *vp; + + vp = tc->getVirtPort(); + pd = vp->readGtoH(task + pid_off); + tc->delVirtPort(vp); + + return pd; +} + +string +ProcessInfo::name(Addr ksp) const +{ + Addr task = this->task(ksp); + if (!task) + return "console"; + + char comm[256]; + CopyStringOut(tc, comm, task + name_off, sizeof(comm)); + if (!comm[0]) + return "startup"; + + return comm; +} + +StackTrace::StackTrace() + : tc(0), stack(64) +{ +} + +StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) + : tc(0), stack(64) +{ + trace(_tc, inst); +} + +StackTrace::~StackTrace() +{ +} + +void +StackTrace::trace(ThreadContext *_tc, bool is_call) +{ +#if 0 + tc = _tc; + + bool usermode = (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; + + Addr pc = tc->readNextPC(); + bool kernel = tc->getSystemPtr()->kernelStart <= pc && + pc <= tc->getSystemPtr()->kernelEnd; + + if (usermode) { + stack.push_back(user); + return; + } + + if (!kernel) { + stack.push_back(console); + return; + } + + SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; + Addr ksp = tc->readIntReg(TheISA::StackPointerReg); + Addr bottom = ksp & ~0x3fff; + Addr addr; + + if (is_call) { + if (!symtab->findNearestAddr(pc, addr)) + panic("could not find address %#x", pc); + + stack.push_back(addr); + pc = tc->readPC(); + } + + Addr ra; + int size; + + while (ksp > bottom) { + if (!symtab->findNearestAddr(pc, addr)) + panic("could not find symbol for pc=%#x", pc); + assert(pc >= addr && "symbol botch: callpc < func"); + + stack.push_back(addr); + + if (isEntry(addr)) + return; + + if (decodePrologue(ksp, pc, addr, size, ra)) { + if (!ra) + return; + + if (size <= 0) { + stack.push_back(unknown); + return; + } + + pc = ra; + ksp += size; + } else { + stack.push_back(unknown); + return; + } + + bool kernel = tc->getSystemPtr()->kernelStart <= pc && + pc <= tc->getSystemPtr()->kernelEnd; + if (!kernel) + return; + + if (stack.size() >= 1000) + panic("unwinding too far"); + } + + panic("unwinding too far"); +#endif +} + +bool +StackTrace::isEntry(Addr addr) +{ +#if 0 + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp12)) + return true; + + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp7)) + return true; + + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp11)) + return true; + + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp21)) + return true; + + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp9)) + return true; + + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp2)) + return true; +#endif + return false; +} + +bool +StackTrace::decodeStack(MachInst inst, int &disp) +{ + // lda $sp, -disp($sp) + // + // Opcode<31:26> == 0x08 + // RA<25:21> == 30 + // RB<20:16> == 30 + // Disp<15:0> + const MachInst mem_mask = 0xffff0000; + const MachInst lda_pattern = 0x23de0000; + const MachInst lda_disp_mask = 0x0000ffff; + + // subq $sp, disp, $sp + // addq $sp, disp, $sp + // + // Opcode<31:26> == 0x10 + // RA<25:21> == 30 + // Lit<20:13> + // One<12> = 1 + // Func<11:5> == 0x20 (addq) + // Func<11:5> == 0x29 (subq) + // RC<4:0> == 30 + const MachInst intop_mask = 0xffe01fff; + const MachInst addq_pattern = 0x43c0141e; + const MachInst subq_pattern = 0x43c0153e; + const MachInst intop_disp_mask = 0x001fe000; + const int intop_disp_shift = 13; + + if ((inst & mem_mask) == lda_pattern) + disp = -sext<16>(inst & lda_disp_mask); + else if ((inst & intop_mask) == addq_pattern) + disp = -int((inst & intop_disp_mask) >> intop_disp_shift); + else if ((inst & intop_mask) == subq_pattern) + disp = int((inst & intop_disp_mask) >> intop_disp_shift); + else + return false; + + return true; +} + +bool +StackTrace::decodeSave(MachInst inst, int ®, int &disp) +{ + // lda $stq, disp($sp) + // + // Opcode<31:26> == 0x08 + // RA<25:21> == ? + // RB<20:16> == 30 + // Disp<15:0> + const MachInst stq_mask = 0xfc1f0000; + const MachInst stq_pattern = 0xb41e0000; + const MachInst stq_disp_mask = 0x0000ffff; + const MachInst reg_mask = 0x03e00000; + const int reg_shift = 21; + + if ((inst & stq_mask) == stq_pattern) { + reg = (inst & reg_mask) >> reg_shift; + disp = sext<16>(inst & stq_disp_mask); + } else { + return false; + } + + return true; +} + +/* + * Decode the function prologue for the function we're in, and note + * which registers are stored where, and how large the stack frame is. + */ +bool +StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, + int &size, Addr &ra) +{ + size = 0; + ra = 0; + + for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { + MachInst inst; + CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst)); + + int reg, disp; + if (decodeStack(inst, disp)) { + if (size) { + // panic("decoding frame size again"); + return true; + } + size += disp; + } else if (decodeSave(inst, reg, disp)) { + if (!ra && reg == ReturnAddressReg) { + CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr)); + if (!ra) { + // panic("no return address value pc=%#x\n", pc); + return false; + } + } + } + } + + return true; +} + +#if TRACING_ON +void +StackTrace::dump() +{ + StringWrap name(tc->getCpuPtr()->name()); + SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; + + DPRINTFN("------ Stack ------\n"); + + string symbol; + for (int i = 0, size = stack.size(); i < size; ++i) { + Addr addr = stack[size - i - 1]; + if (addr == user) + symbol = "user"; + else if (addr == console) + symbol = "console"; + else if (addr == unknown) + symbol = "unknown"; + else + symtab->findSymbol(addr, symbol); + + DPRINTFN("%#x: %s\n", addr, symbol); + } +} +#endif -- cgit v1.2.3 From 95d611f7bb664bd4352a6856c5e12d4ebf014f28 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:46:15 -0500 Subject: Alpha derived classes for kernel_stats. --HG-- extra : convert_revision : 93b2c6f6687b21c84b97a7665cd9fc04c59ba9d6 --- src/kern/alpha/kernel_stats.cc | 211 +++++++++++++++++++++++++++++++++++++++++ src/kern/alpha/kernel_stats.hh | 96 +++++++++++++++++++ 2 files changed, 307 insertions(+) create mode 100644 src/kern/alpha/kernel_stats.cc create mode 100644 src/kern/alpha/kernel_stats.hh (limited to 'src') diff --git a/src/kern/alpha/kernel_stats.cc b/src/kern/alpha/kernel_stats.cc new file mode 100644 index 000000000..7b74295e4 --- /dev/null +++ b/src/kern/alpha/kernel_stats.cc @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2004-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: Lisa Hsu + * Nathan Binkert + */ + +#include +#include +#include + +#include "kern/alpha/kernel_stats.hh" +#include "arch/alpha/osfpal.hh" +#include "base/trace.hh" +#include "cpu/thread_context.hh" +#include "kern/tru64/tru64_syscalls.hh" +#include "sim/system.hh" + +using namespace std; +using namespace Stats; + +namespace AlphaISA { +namespace Kernel { + +const char *modestr[] = { "kernel", "user", "idle" }; + +Statistics::Statistics(System *system) + : ::Kernel::Statistics(system), + idleProcess((Addr)-1), themode(kernel), lastModeTick(0) +{ +} + +void +Statistics::regStats(const string &_name) +{ + ::Kernel::Statistics::regStats(_name); + + _callpal + .init(256) + .name(name() + ".callpal") + .desc("number of callpals executed") + .flags(total | pdf | nozero | nonan) + ; + + for (int i = 0; i < PAL::NumCodes; ++i) { + const char *str = PAL::name(i); + if (str) + _callpal.subname(i, str); + } + + _hwrei + .name(name() + ".inst.hwrei") + .desc("number of hwrei instructions executed") + ; + + _mode + .init(cpu_mode_num) + .name(name() + ".mode_switch") + .desc("number of protection mode switches") + ; + + for (int i = 0; i < cpu_mode_num; ++i) + _mode.subname(i, modestr[i]); + + _modeGood + .init(cpu_mode_num) + .name(name() + ".mode_good") + ; + + for (int i = 0; i < cpu_mode_num; ++i) + _modeGood.subname(i, modestr[i]); + + _modeFraction + .name(name() + ".mode_switch_good") + .desc("fraction of useful protection mode switches") + .flags(total) + ; + + for (int i = 0; i < cpu_mode_num; ++i) + _modeFraction.subname(i, modestr[i]); + + _modeFraction = _modeGood / _mode; + + _modeTicks + .init(cpu_mode_num) + .name(name() + ".mode_ticks") + .desc("number of ticks spent at the given mode") + .flags(pdf) + ; + for (int i = 0; i < cpu_mode_num; ++i) + _modeTicks.subname(i, modestr[i]); + + _swap_context + .name(name() + ".swap_context") + .desc("number of times the context was actually changed") + ; +} + +void +Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc) +{ + assert(themode == kernel); + idleProcess = idlepcbb; + themode = idle; + changeMode(themode, tc); +} + +void +Statistics::changeMode(cpu_mode newmode, ThreadContext *tc) +{ + _mode[newmode]++; + + if (newmode == themode) + return; + + DPRINTF(Context, "old mode=%-8s new mode=%-8s\n", + modestr[themode], modestr[newmode]); + + _modeGood[newmode]++; + _modeTicks[themode] += curTick - lastModeTick; + + lastModeTick = curTick; + themode = newmode; +} + +void +Statistics::mode(cpu_mode newmode, ThreadContext *tc) +{ + Addr pcbb = tc->readMiscReg(AlphaISA::IPR_PALtemp23); + + if (newmode == kernel && pcbb == idleProcess) + newmode = idle; + + changeMode(newmode, tc); +} + +void +Statistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc) +{ + assert(themode != user); + + _swap_context++; + changeMode(newpcbb == idleProcess ? idle : kernel, tc); +} + +void +Statistics::callpal(int code, ThreadContext *tc) +{ + if (!PAL::name(code)) + return; + + _callpal[code]++; + + switch (code) { + case PAL::callsys: { + int number = tc->readIntReg(0); + if (SystemCalls::validSyscallNumber(number)) { + int cvtnum = SystemCalls::convert(number); + _syscall[cvtnum]++; + } + } break; + } +} + +void +Statistics::serialize(ostream &os) +{ + ::Kernel::Statistics::serialize(os); + int exemode = themode; + SERIALIZE_SCALAR(exemode); + SERIALIZE_SCALAR(idleProcess); + SERIALIZE_SCALAR(lastModeTick); +} + +void +Statistics::unserialize(Checkpoint *cp, const string §ion) +{ + ::Kernel::Statistics::unserialize(cp, section); + int exemode; + UNSERIALIZE_SCALAR(exemode); + UNSERIALIZE_SCALAR(idleProcess); + UNSERIALIZE_SCALAR(lastModeTick); + themode = (cpu_mode)exemode; +} + +} /* end namespace AlphaISA::Kernel */ +} /* end namespace AlphaISA */ diff --git a/src/kern/alpha/kernel_stats.hh b/src/kern/alpha/kernel_stats.hh new file mode 100644 index 000000000..90058e507 --- /dev/null +++ b/src/kern/alpha/kernel_stats.hh @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2004-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: Lisa Hsu + * Nathan Binkert + */ + +#ifndef __ARCH_ALPHA_KERNEL_STATS_HH__ +#define __ARCH_ALPHA_KERNEL_STATS_HH__ + +#include +#include +#include +#include + +#include "cpu/static_inst.hh" +#include "kern/base_kernel_stats.hh" + +class BaseCPU; +class ThreadContext; +class FnEvent; +// What does kernel stats expect is included? +class System; + +namespace AlphaISA { +namespace Kernel { + +enum cpu_mode { kernel, user, idle, cpu_mode_num }; +extern const char *modestr[]; + +class Statistics : public ::Kernel::Statistics +{ + protected: + Addr idleProcess; + cpu_mode themode; + Tick lastModeTick; + + void changeMode(cpu_mode newmode, ThreadContext *tc); + + private: + Stats::Vector<> _callpal; +// Stats::Vector<> _faults; + + Stats::Vector<> _mode; + Stats::Vector<> _modeGood; + Stats::Formula _modeFraction; + Stats::Vector<> _modeTicks; + + Stats::Scalar<> _swap_context; + + public: + Statistics(System *system); + + void regStats(const std::string &name); + + public: + void mode(cpu_mode newmode, ThreadContext *tc); + void context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc); + void callpal(int code, ThreadContext *tc); + void hwrei() { _hwrei++; } + + void setIdleProcess(Addr idle, ThreadContext *tc); + + public: + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); +}; + +} /* end namespace AlphaISA::Kernel */ +} /* end namespace AlphaISA */ + +#endif // __ARCH_ALPHA_KERNEL_STATS_HH__ -- cgit v1.2.3 From 56230ffb3ae216c0d30f65bbf8818e57a36407b5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 05:47:10 -0500 Subject: Definition of stub kernel_stats object. This just uses the base object. --HG-- extra : convert_revision : 349b6743b82eef4fe46b04f10b5adfa8adfb6a0e --- src/kern/sparc/kernel_stats.hh | 57 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/kern/sparc/kernel_stats.hh (limited to 'src') diff --git a/src/kern/sparc/kernel_stats.hh b/src/kern/sparc/kernel_stats.hh new file mode 100644 index 000000000..72bffd2b2 --- /dev/null +++ b/src/kern/sparc/kernel_stats.hh @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2004-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: Gabe Black + */ + +#ifndef __ARCH_SPARC_KERNEL_STATS_HH__ +#define __ARCH_SPARC_KERNEL_STATS_HH__ + +#include +#include +#include +#include + +#include "kern/base_kernel_stats.hh" + +namespace SparcISA { +namespace Kernel { + +enum cpu_mode { hypervisor, kernel, user, idle, cpu_mode_num }; +extern const char *modestr[]; + +class Statistics : public ::Kernel::Statistics +{ + public: + Statistics(System *system) : ::Kernel::Statistics(system) + {} +}; + +} /* end namespace AlphaISA::Kernel */ +} /* end namespace AlphaISA */ + +#endif // __ARCH_SPARC_KERNEL_STATS_HH__ -- cgit v1.2.3 From d9f159a3b996b25683f33bcc8ae5142311639722 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 7 Nov 2006 13:53:06 -0500 Subject: Initialize mem dep unit properly. src/cpu/o3/mem_dep_unit_impl.hh: Initialize mem dep unit properly, add debug output. --HG-- extra : convert_revision : 3c56dedfa57de1edc4b1c8f8d9bc94e18002eff2 --- src/cpu/o3/mem_dep_unit.hh | 2 +- src/cpu/o3/mem_dep_unit_impl.hh | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cpu/o3/mem_dep_unit.hh b/src/cpu/o3/mem_dep_unit.hh index e399f0133..a12a3001b 100644 --- a/src/cpu/o3/mem_dep_unit.hh +++ b/src/cpu/o3/mem_dep_unit.hh @@ -69,7 +69,7 @@ class MemDepUnit { typedef typename Impl::DynInstPtr DynInstPtr; /** Empty constructor. Must call init() prior to using in this case. */ - MemDepUnit() {} + MemDepUnit(); /** Constructs a MemDepUnit with given parameters. */ MemDepUnit(Params *params); diff --git a/src/cpu/o3/mem_dep_unit_impl.hh b/src/cpu/o3/mem_dep_unit_impl.hh index c649ca385..f19980fd5 100644 --- a/src/cpu/o3/mem_dep_unit_impl.hh +++ b/src/cpu/o3/mem_dep_unit_impl.hh @@ -33,6 +33,13 @@ #include "cpu/o3/inst_queue.hh" #include "cpu/o3/mem_dep_unit.hh" +template +MemDepUnit::MemDepUnit() + : loadBarrier(false), loadBarrierSN(0), storeBarrier(false), + storeBarrierSN(0), iqPtr(NULL) +{ +} + template MemDepUnit::MemDepUnit(Params *params) : depPred(params->SSITSize, params->LFSTSize), loadBarrier(false), @@ -160,8 +167,12 @@ MemDepUnit::insert(DynInstPtr &inst) // producing memrefs/stores. InstSeqNum producing_store; if (inst->isLoad() && loadBarrier) { + DPRINTF(MemDepUnit, "Load barrier [sn:%lli] in flight\n", + loadBarrierSN); producing_store = loadBarrierSN; } else if (inst->isStore() && storeBarrier) { + DPRINTF(MemDepUnit, "Store barrier [sn:%lli] in flight\n", + storeBarrierSN); producing_store = storeBarrierSN; } else { producing_store = depPred.checkInst(inst->readPC()); @@ -171,10 +182,12 @@ MemDepUnit::insert(DynInstPtr &inst) // If there is a producing store, try to find the entry. if (producing_store != 0) { + DPRINTF(MemDepUnit, "Searching for producer\n"); MemDepHashIt hash_it = memDepHash.find(producing_store); if (hash_it != memDepHash.end()) { store_entry = (*hash_it).second; + DPRINTF(MemDepUnit, "Proucer found\n"); } } -- cgit v1.2.3 From 4589ec55aed596a4b0b7d81779f2b4665643d223 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 7 Nov 2006 13:53:49 -0500 Subject: Fix compile error. --HG-- extra : convert_revision : a4c4195bc07383149a56907f26d327a4bfa77c26 --- src/cpu/ozone/cpu.hh | 4 ++-- src/cpu/ozone/thread_state.hh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh index 828c2b4ca..ccb467394 100644 --- a/src/cpu/ozone/cpu.hh +++ b/src/cpu/ozone/cpu.hh @@ -363,8 +363,8 @@ class OzoneCPU : public BaseCPU bool interval_stats; - AlphaITB *itb; - AlphaDTB *dtb; + TheISA::ITB *itb; + TheISA::DTB *dtb; System *system; PhysicalMemory *physmem; #endif diff --git a/src/cpu/ozone/thread_state.hh b/src/cpu/ozone/thread_state.hh index c4d16b3af..a71795851 100644 --- a/src/cpu/ozone/thread_state.hh +++ b/src/cpu/ozone/thread_state.hh @@ -122,7 +122,7 @@ struct OzoneThreadState : public ThreadState { MiscReg readMiscRegWithEffect(int misc_reg) { - return miscRegFile.readRegWithEffect(misc_reg, fault, tc); + return miscRegFile.readRegWithEffect(misc_reg, tc); } void setMiscReg(int misc_reg, const MiscReg &val) -- cgit v1.2.3 From 244e0c884c60c141ea1bc63bb93e0aee25d6a854 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 7 Nov 2006 14:24:31 -0500 Subject: Remove hack by setting configuration better. src/dev/isa_fake.cc: src/dev/isa_fake.hh: No need for specialized init() function any more. src/python/m5/objects/Tsunami.py: Override responder when set by user. This avoids having bus.responder floating around and not doing anything when the user has specified their own default responder. --HG-- extra : convert_revision : c547daf15b23a889c98e62bfd53c293c85d7a041 --- src/dev/isa_fake.cc | 9 --------- src/dev/isa_fake.hh | 2 -- src/python/m5/objects/Tsunami.py | 1 + 3 files changed, 1 insertion(+), 11 deletions(-) (limited to 'src') diff --git a/src/dev/isa_fake.cc b/src/dev/isa_fake.cc index 103fdd8ce..40909c6a1 100644 --- a/src/dev/isa_fake.cc +++ b/src/dev/isa_fake.cc @@ -50,15 +50,6 @@ IsaFake::IsaFake(Params *p) memset(&retData, p->retData, sizeof(retData)); } -void -IsaFake::init() -{ - // Only init this device if it's connected to anything. - if (pioPort) - PioDevice::init(); -} - - Tick IsaFake::read(PacketPtr pkt) { diff --git a/src/dev/isa_fake.hh b/src/dev/isa_fake.hh index c4072e42c..e35b9c58f 100644 --- a/src/dev/isa_fake.hh +++ b/src/dev/isa_fake.hh @@ -80,8 +80,6 @@ class IsaFake : public BasicPioDevice * @param data the data to not write. */ virtual Tick write(PacketPtr pkt); - - void init(); }; #endif // __ISA_FAKE_HH__ diff --git a/src/python/m5/objects/Tsunami.py b/src/python/m5/objects/Tsunami.py index 78ab65b31..ffe93727b 100644 --- a/src/python/m5/objects/Tsunami.py +++ b/src/python/m5/objects/Tsunami.py @@ -76,6 +76,7 @@ class Tsunami(Platform): self.pchip.pio = bus.port self.pciconfig.pio = bus.default bus.responder_set = True + bus.responder = self.pciconfig self.fake_sm_chip.pio = bus.port self.fake_uart1.pio = bus.port self.fake_uart2.pio = bus.port -- cgit v1.2.3 From 8ba73da056ae8b34713dc5b927d4ceb238db969a Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 7 Nov 2006 14:25:54 -0500 Subject: Fix up bus draining and add draining to the caches. src/mem/bus.cc: Fix up draining to work properly. src/mem/bus.hh: Initialize drainEvent to NULL. src/mem/cache/base_cache.cc: src/mem/cache/base_cache.hh: Add draining to the caches. --HG-- extra : convert_revision : 3082220a75d50876f10909f9f99bec535889f818 --- src/mem/bus.cc | 10 +++++----- src/mem/bus.hh | 4 ++-- src/mem/cache/base_cache.cc | 22 ++++++++++++++++++++++ src/mem/cache/base_cache.hh | 33 ++++++++++++++++++++++++++++++++- 4 files changed, 61 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/mem/bus.cc b/src/mem/bus.cc index 28ee3476b..7b65d252b 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -240,10 +240,10 @@ Bus::recvRetry(int id) busIdle.reschedule(tickNextIdle); } } - //If we weren't able to drain before, we might be able to now. - if (drainEvent && retryList.size() == 0 && curTick >= tickNextIdle) - drainEvent->process(); } + //If we weren't able to drain before, we might be able to now. + if (drainEvent && retryList.size() == 0 && curTick >= tickNextIdle) + drainEvent->process(); } Port * @@ -521,10 +521,10 @@ Bus::drain(Event * de) //waiting. We might be idle but have someone waiting if the device we //contacted for a retry didn't actually retry. if (curTick >= tickNextIdle && retryList.size() == 0) { + return 0; + } else { drainEvent = de; return 1; - } else { - return 0; } } diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 1d1cfde89..ff1d2545d 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -257,8 +257,8 @@ class Bus : public MemObject Bus(const std::string &n, int bus_id, int _clock, int _width, bool responder_set) : MemObject(n), busId(bus_id), clock(_clock), width(_width), - tickNextIdle(0), busIdle(this), inRetry(false), defaultPort(NULL), - responderSet(responder_set) + tickNextIdle(0), drainEvent(NULL), busIdle(this), inRetry(false), + defaultPort(NULL), responderSet(responder_set) { //Both the width and clock period must be positive if (width <= 0) diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 1c519fb86..c26d7782b 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -140,6 +140,9 @@ BaseCache::CachePort::recvRetry() } waitingOnRetry = false; } + // Check if we're done draining once this list is empty + if (drainList.empty()) + cache->checkDrain(); } else if (!isCpuSide) { @@ -338,6 +341,10 @@ BaseCache::CacheEvent::process() cachePort->drainList.push_back(pkt); cachePort->waitingOnRetry = true; } + + // Check if we're done draining once this list is empty + if (cachePort->drainList.empty()) + cachePort->cache->checkDrain(); } const char * @@ -599,3 +606,18 @@ BaseCache::regStats() ; } + +unsigned int +BaseCache::drain(Event *de) +{ + // Set status + if (!canDrain()) { + drainEvent = de; + + changeState(SimObject::Draining); + return 1; + } + + changeState(SimObject::Drained); + return 0; +} diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh index 565280aef..ea7544fbb 100644 --- a/src/mem/cache/base_cache.hh +++ b/src/mem/cache/base_cache.hh @@ -105,6 +105,8 @@ class BaseCache : public MemObject void clearBlocked(); + bool canDrain() { return drainList.empty(); } + bool blocked; bool mustSendRetry; @@ -227,6 +229,9 @@ class BaseCache : public MemObject /** The number of misses to trigger an exit event. */ Counter missCount; + /** The drain event. */ + Event *drainEvent; + public: // Statistics /** @@ -340,7 +345,7 @@ class BaseCache : public MemObject BaseCache(const std::string &name, Params ¶ms) : MemObject(name), blocked(0), blockedSnoop(0), masterRequests(0), slaveRequests(0), blkSize(params.blkSize), - missCount(params.maxMisses) + missCount(params.maxMisses), drainEvent(NULL) { //Start ports at null if more than one is created we should panic cpuSidePort = NULL; @@ -477,6 +482,7 @@ class BaseCache : public MemObject { uint8_t flag = 1<process(); + changeState(SimObject::Drained); + // Clear the drain event + drainEvent = NULL; + } + } + + bool canDrain() + { + if (doMasterRequest() || doSlaveRequest()) { + return false; + } else if (memSidePort && !memSidePort->canDrain()) { + return false; + } else if (cpuSidePort && !cpuSidePort->canDrain()) { + return false; + } + return true; + } }; #endif //__BASE_CACHE_HH__ -- cgit v1.2.3 From ea5df468820c1c152ecd6932ac6a2a67b3f1725d Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 7 Nov 2006 15:45:03 -0500 Subject: Fix error message. --HG-- extra : convert_revision : 7ac0f40595c89b0d9352e82e447d25380b038408 --- src/python/m5/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py index d41fd5a61..42abfe2cc 100644 --- a/src/python/m5/__init__.py +++ b/src/python/m5/__init__.py @@ -171,10 +171,10 @@ def switchCpus(cpuList): for cpu in old_cpus: if not isinstance(cpu, objects.BaseCPU): - raise TypeError, "%s is not of type BaseCPU", cpu + raise TypeError, "%s is not of type BaseCPU" % cpu for cpu in new_cpus: if not isinstance(cpu, objects.BaseCPU): - raise TypeError, "%s is not of type BaseCPU", cpu + raise TypeError, "%s is not of type BaseCPU" % cpu # Drain all of the individual CPUs drain_event = cc_main.createCountedDrain() -- cgit v1.2.3 From f7a35c33d70d99c1276a70c2ed1a86719e64973b Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 7 Nov 2006 15:51:37 -0500 Subject: add code to operate in lockstep with legion src/python/m5/main.py: add option to operate in lockstep with legion --HG-- extra : convert_revision : 2cc90ec0cf7e8d028ee813c2034a77415671a628 --- src/cpu/exetrace.cc | 92 ++++++++++++++++++++++++++++++++++++++++++++ src/cpu/exetrace.hh | 1 + src/cpu/m5legion_interface.h | 50 ++++++++++++++++++++++++ src/python/m5/main.py | 3 ++ 4 files changed, 146 insertions(+) create mode 100644 src/cpu/m5legion_interface.h (limited to 'src') diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 9d85311bb..80b144e85 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -33,6 +33,8 @@ #include #include +#include +#include #include "arch/regfile.hh" #include "base/loader/symtab.hh" @@ -44,10 +46,15 @@ //XXX This is temporary #include "arch/isa_specific.hh" +#include "cpu/m5legion_interface.h" using namespace std; using namespace TheISA; +namespace Trace { +SharedData *shared_data = NULL; +} + //////////////////////////////////////////////////////////////////////// // // Methods for the InstRecord object @@ -60,6 +67,7 @@ Trace::InstRecord::dump(ostream &outs) if (flags[PRINT_REG_DELTA]) { #if THE_ISA == SPARC_ISA +#if 0 //Don't print what happens for each micro-op, just print out //once at the last op, and for regular instructions. if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) @@ -120,6 +128,7 @@ Trace::InstRecord::dump(ostream &outs) } outs << endl; } +#endif #endif } else if (flags[INTEL_FORMAT]) { @@ -222,6 +231,65 @@ Trace::InstRecord::dump(ostream &outs) // outs << endl; } + // Compare + if (flags[LEGION_LOCKSTEP]) + { + bool compared = false; + bool diffPC = false; + bool diffInst = false; + bool diffRegs = false; + + while (!compared) { + if (shared_data->flags == OWN_M5) { + if (shared_data->pc != PC) + diffPC = true; + if (shared_data->instruction != staticInst->machInst) + diffInst = true; + for (int i = 0; i < TheISA::NumIntRegs; i++) { + if (thread->readIntReg(i) != shared_data->intregs[i]) + diffRegs = true; + } + + if (diffPC || diffInst || diffRegs ) { + outs << "Differences found between M5 and Legion:"; + if (diffPC) + outs << " PC"; + if (diffInst) + outs << " Instruction"; + if (diffRegs) + outs << " IntRegs"; + outs << endl; + + outs << "M5 PC: " << setw(20) << "0x" << hex << PC; + outs << "Legion PC: " << setw(20) << "0x" << hex << + shared_data->pc << endl; + + + + outs << "M5 Instruction: " << staticInst->machInst << "(" + << staticInst->disassemble(PC, debugSymbolTable) + << ")" << "Legion Instruction: " << + shared_data->instruction << "(" + /*<< legionInst->disassemble(shared_data->pc, + debugSymbolTable)*/ + << ")" << endl; + + for (int i = 0; i < TheISA::NumIntRegs; i++) { + outs << setw(16) << "0x" << hex << thread->readIntReg(i) + << setw(16) << "0x" << hex << shared_data->intregs[i]; + + if (thread->readIntReg(i) != shared_data->intregs[i]) + outs << "<--- Different"; + outs << endl; + } + } + + compared = true; + shared_data->flags = OWN_LEGION; + } + } + + } } @@ -271,6 +339,9 @@ Param exe_trace_pc_symbol(&exeTraceParams, "pc_symbol", "Use symbols for the PC if available", true); Param exe_trace_intel_format(&exeTraceParams, "intel_format", "print trace in intel compatible format", false); +Param exe_trace_legion_lockstep(&exeTraceParams, "legion_lockstep", + "Compare sim state to legion state every cycle", + false); Param exe_trace_system(&exeTraceParams, "trace_system", "print trace of which system (client or server)", "client"); @@ -296,7 +367,28 @@ Trace::InstRecord::setParams() flags[PRINT_REG_DELTA] = exe_trace_print_reg_delta; flags[PC_SYMBOL] = exe_trace_pc_symbol; flags[INTEL_FORMAT] = exe_trace_intel_format; + flags[LEGION_LOCKSTEP] = exe_trace_legion_lockstep; trace_system = exe_trace_system; + + // If were going to be in lockstep with Legion + // Setup shared memory, and get otherwise ready + if (flags[LEGION_LOCKSTEP]) { + int shmfd = shmget(getuid(), sizeof(SharedData), 0777); + if (shmfd < 0) + fatal("Couldn't get shared memory fd. Is Legion running?"); + + shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND); + if (shared_data == (SharedData*)-1) + fatal("Couldn't allocate shared memory"); + + if (shared_data->flags != OWN_M5) + fatal("Shared memory has invalid owner"); + + if (shared_data->version != VERSION) + fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION, + shared_data->version); + + } } void diff --git a/src/cpu/exetrace.hh b/src/cpu/exetrace.hh index 02ea162f0..6562e5265 100644 --- a/src/cpu/exetrace.hh +++ b/src/cpu/exetrace.hh @@ -150,6 +150,7 @@ class InstRecord : public Record PRINT_REG_DELTA, PC_SYMBOL, INTEL_FORMAT, + LEGION_LOCKSTEP, NUM_BITS }; diff --git a/src/cpu/m5legion_interface.h b/src/cpu/m5legion_interface.h new file mode 100644 index 000000000..0fa0e7279 --- /dev/null +++ b/src/cpu/m5legion_interface.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 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: Ali Saidi + */ + +#include + +#define VERSION 0xA1000001 +#define OWN_M5 0x000000AA +#define OWN_LEGION 0x00000055 + +/** !!! VVV Increment VERSION on change VVV !!! **/ + +typedef struct { + uint32_t flags; + uint32_t version; + + uint64_t pc; + uint64_t instruction; + uint64_t intregs[32]; + +} SharedData; + +/** !!! ^^^ Increment VERSION on change ^^^ !!! **/ + diff --git a/src/python/m5/main.py b/src/python/m5/main.py index ccd6c5807..ef37f62ac 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -181,6 +181,8 @@ bool_option("print-cpseq", default=False, help="Print correct path sequence numbers in trace output") #bool_option("print-reg-delta", default=False, # help="Print which registers changed to what in trace output") +bool_option("legion-lock", default=False, + help="Compare simulator state with Legion simulator every cycle") options = attrdict() arguments = [] @@ -296,6 +298,7 @@ def main(): objects.ExecutionTrace.print_fetchseq = options.print_fetch_seq objects.ExecutionTrace.print_cpseq = options.print_cpseq #objects.ExecutionTrace.print_reg_delta = options.print_reg_delta + objects.ExecutionTrace.legion_lockstep = options.legion_lock sys.argv = arguments sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path -- cgit v1.2.3 From a05b16b1ab56d55bb7400f0cb1eaa466905f43d5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 20:26:45 -0500 Subject: Only include kern/kernel_stats.hh if in full system. This was breaking MIPS_SE --HG-- extra : convert_revision : b3f956af92cb98b4945aebc8aece1dffcabdf15c --- src/cpu/simple/base.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index e91569db2..b7df39218 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -46,7 +46,6 @@ #include "cpu/smt.hh" #include "cpu/static_inst.hh" #include "cpu/thread_context.hh" -#include "kern/kernel_stats.hh" #include "mem/packet.hh" #include "sim/builder.hh" #include "sim/byteswap.hh" @@ -58,10 +57,11 @@ #include "sim/system.hh" #if FULL_SYSTEM -#include "base/remote_gdb.hh" #include "arch/tlb.hh" #include "arch/stacktrace.hh" #include "arch/vtophys.hh" +#include "base/remote_gdb.hh" +#include "kern/kernel_stats.hh" #else // !FULL_SYSTEM #include "mem/mem_object.hh" #endif // FULL_SYSTEM -- cgit v1.2.3 From eb7c923e10cfb60f216d7452d94b0fd0b237c38f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 20:35:42 -0500 Subject: A cleaner hack. --HG-- extra : convert_revision : 8992af33f2779a8d9dc357e648ba39005d0c971a --- src/kern/base_kernel_stats.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/kern/base_kernel_stats.cc b/src/kern/base_kernel_stats.cc index 84a38aca5..d29672753 100644 --- a/src/kern/base_kernel_stats.cc +++ b/src/kern/base_kernel_stats.cc @@ -98,12 +98,15 @@ Statistics::regStats(const string &_name) .flags(total | pdf | nozero | nonan) ; + //@todo This needs to get the names of syscalls from an appropriate place. +#if 0 for (int i = 0; i < SystemCalls::Number; ++i) { - const char *str = "Please fix me";//SystemCalls::name(i); + const char *str = SystemCalls::name(i); if (str) { _syscall.subname(i, str); } } +#endif } void -- cgit v1.2.3 From c693c6ba9f9d641344db8a2a505484f5f8aa2645 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 22:34:34 -0500 Subject: Put kernel_stats back into arch. --HG-- rename : src/kern/alpha/idle_event.cc => src/arch/alpha/idle_event.cc rename : src/kern/alpha/idle_event.hh => src/arch/alpha/idle_event.hh rename : src/kern/alpha/kernel_stats.cc => src/arch/alpha/kernel_stats.cc rename : src/kern/alpha/kernel_stats.hh => src/arch/alpha/kernel_stats.hh rename : src/kern/sparc/kernel_stats.hh => src/arch/sparc/kernel_stats.hh rename : src/kern/base_kernel_stats.cc => src/kern/kernel_stats.cc rename : src/kern/base_kernel_stats.hh => src/kern/kernel_stats.hh extra : convert_revision : 42bd3e36b407edbd19b912c9218f4e5923a15966 --- src/arch/SConscript | 1 + src/arch/alpha/SConscript | 2 + src/arch/alpha/ev5.cc | 2 +- src/arch/alpha/idle_event.cc | 45 +++++++++ src/arch/alpha/idle_event.hh | 47 +++++++++ src/arch/alpha/kernel_stats.cc | 211 +++++++++++++++++++++++++++++++++++++++++ src/arch/alpha/kernel_stats.hh | 96 +++++++++++++++++++ src/arch/alpha/linux/system.cc | 2 +- src/arch/alpha/linux/system.hh | 2 +- src/arch/sparc/kernel_stats.hh | 57 +++++++++++ src/cpu/checker/cpu.cc | 2 +- src/cpu/o3/alpha/cpu_impl.hh | 2 +- src/cpu/o3/regfile.hh | 2 +- src/cpu/ozone/cpu_impl.hh | 6 +- src/cpu/ozone/dyn_inst_impl.hh | 3 + src/cpu/simple/base.cc | 4 +- src/cpu/simple_thread.cc | 2 +- src/cpu/thread_state.cc | 2 +- src/kern/SConscript | 23 +---- src/kern/alpha/idle_event.cc | 45 --------- src/kern/alpha/idle_event.hh | 47 --------- src/kern/alpha/kernel_stats.cc | 211 ----------------------------------------- src/kern/alpha/kernel_stats.hh | 96 ------------------- src/kern/base_kernel_stats.cc | 142 --------------------------- src/kern/base_kernel_stats.hh | 89 ----------------- src/kern/kernel_stats.cc | 142 +++++++++++++++++++++++++++ src/kern/kernel_stats.hh | 89 +++++++++++++++++ src/kern/sparc/kernel_stats.hh | 57 ----------- src/sim/pseudo_inst.cc | 4 +- 29 files changed, 709 insertions(+), 724 deletions(-) create mode 100644 src/arch/alpha/idle_event.cc create mode 100644 src/arch/alpha/idle_event.hh create mode 100644 src/arch/alpha/kernel_stats.cc create mode 100644 src/arch/alpha/kernel_stats.hh create mode 100644 src/arch/sparc/kernel_stats.hh delete mode 100644 src/kern/alpha/idle_event.cc delete mode 100644 src/kern/alpha/idle_event.hh delete mode 100644 src/kern/alpha/kernel_stats.cc delete mode 100644 src/kern/alpha/kernel_stats.hh delete mode 100644 src/kern/base_kernel_stats.cc delete mode 100644 src/kern/base_kernel_stats.hh create mode 100644 src/kern/kernel_stats.cc create mode 100644 src/kern/kernel_stats.hh delete mode 100644 src/kern/sparc/kernel_stats.hh (limited to 'src') diff --git a/src/arch/SConscript b/src/arch/SConscript index 82a56d4eb..bbe3c4e3a 100644 --- a/src/arch/SConscript +++ b/src/arch/SConscript @@ -51,6 +51,7 @@ isa_switch_hdrs = Split(''' faults.hh interrupts.hh isa_traits.hh + kernel_stats.hh locked_mem.hh process.hh regfile.hh diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript index 2d733d73b..3947ec23a 100644 --- a/src/arch/alpha/SConscript +++ b/src/arch/alpha/SConscript @@ -56,7 +56,9 @@ full_system_sources = Split(''' tlb.cc arguments.cc ev5.cc + idle_event.cc ipr.cc + kernel_stats.cc osfpal.cc stacktrace.cc vtophys.cc diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 76574e2df..59f9d2fb5 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -31,6 +31,7 @@ #include "arch/alpha/faults.hh" #include "arch/alpha/isa_traits.hh" +#include "arch/alpha/kernel_stats.hh" #include "arch/alpha/osfpal.hh" #include "arch/alpha/tlb.hh" #include "arch/alpha/kgdb.h" @@ -40,7 +41,6 @@ #include "cpu/base.hh" #include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" -#include "kern/alpha/kernel_stats.hh" #include "sim/debug.hh" #include "sim/sim_exit.hh" diff --git a/src/arch/alpha/idle_event.cc b/src/arch/alpha/idle_event.cc new file mode 100644 index 000000000..0f6806319 --- /dev/null +++ b/src/arch/alpha/idle_event.cc @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2004-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: Lisa Hsu + * Nathan Binkert + */ + +#include "arch/alpha/idle_event.hh" +#include "arch/alpha/kernel_stats.hh" +#include "cpu/thread_context.hh" + +using namespace TheISA; + +void +IdleStartEvent::process(ThreadContext *tc) +{ + if (tc->getKernelStats()) + tc->getKernelStats()->setIdleProcess( + tc->readMiscReg(AlphaISA::IPR_PALtemp23), tc); + remove(); +} diff --git a/src/arch/alpha/idle_event.hh b/src/arch/alpha/idle_event.hh new file mode 100644 index 000000000..97d5bdd6e --- /dev/null +++ b/src/arch/alpha/idle_event.hh @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2004-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: Nathan Binkert + * Lisa Hsu + * Ali Saidi + */ + +#ifndef __KERN_ALPHA_IDLE_EVENT_HH__ +#define __KERN_ALPHA_IDLE_EVENT_HH__ + +#include "cpu/pc_event.hh" + +class IdleStartEvent : public PCEvent +{ + public: + IdleStartEvent(PCEventQueue *q, const std::string &desc, Addr addr) + : PCEvent(q, desc, addr) + {} + virtual void process(ThreadContext *tc); +}; + +#endif // __KERN_ALPHA_IDLE_EVENT_HH__ diff --git a/src/arch/alpha/kernel_stats.cc b/src/arch/alpha/kernel_stats.cc new file mode 100644 index 000000000..6fc3cb72f --- /dev/null +++ b/src/arch/alpha/kernel_stats.cc @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2004-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: Lisa Hsu + * Nathan Binkert + */ + +#include +#include +#include + +#include "arch/alpha/kernel_stats.hh" +#include "arch/alpha/osfpal.hh" +#include "base/trace.hh" +#include "cpu/thread_context.hh" +#include "kern/tru64/tru64_syscalls.hh" +#include "sim/system.hh" + +using namespace std; +using namespace Stats; + +namespace AlphaISA { +namespace Kernel { + +const char *modestr[] = { "kernel", "user", "idle" }; + +Statistics::Statistics(System *system) + : ::Kernel::Statistics(system), + idleProcess((Addr)-1), themode(kernel), lastModeTick(0) +{ +} + +void +Statistics::regStats(const string &_name) +{ + ::Kernel::Statistics::regStats(_name); + + _callpal + .init(256) + .name(name() + ".callpal") + .desc("number of callpals executed") + .flags(total | pdf | nozero | nonan) + ; + + for (int i = 0; i < PAL::NumCodes; ++i) { + const char *str = PAL::name(i); + if (str) + _callpal.subname(i, str); + } + + _hwrei + .name(name() + ".inst.hwrei") + .desc("number of hwrei instructions executed") + ; + + _mode + .init(cpu_mode_num) + .name(name() + ".mode_switch") + .desc("number of protection mode switches") + ; + + for (int i = 0; i < cpu_mode_num; ++i) + _mode.subname(i, modestr[i]); + + _modeGood + .init(cpu_mode_num) + .name(name() + ".mode_good") + ; + + for (int i = 0; i < cpu_mode_num; ++i) + _modeGood.subname(i, modestr[i]); + + _modeFraction + .name(name() + ".mode_switch_good") + .desc("fraction of useful protection mode switches") + .flags(total) + ; + + for (int i = 0; i < cpu_mode_num; ++i) + _modeFraction.subname(i, modestr[i]); + + _modeFraction = _modeGood / _mode; + + _modeTicks + .init(cpu_mode_num) + .name(name() + ".mode_ticks") + .desc("number of ticks spent at the given mode") + .flags(pdf) + ; + for (int i = 0; i < cpu_mode_num; ++i) + _modeTicks.subname(i, modestr[i]); + + _swap_context + .name(name() + ".swap_context") + .desc("number of times the context was actually changed") + ; +} + +void +Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc) +{ + assert(themode == kernel); + idleProcess = idlepcbb; + themode = idle; + changeMode(themode, tc); +} + +void +Statistics::changeMode(cpu_mode newmode, ThreadContext *tc) +{ + _mode[newmode]++; + + if (newmode == themode) + return; + + DPRINTF(Context, "old mode=%-8s new mode=%-8s\n", + modestr[themode], modestr[newmode]); + + _modeGood[newmode]++; + _modeTicks[themode] += curTick - lastModeTick; + + lastModeTick = curTick; + themode = newmode; +} + +void +Statistics::mode(cpu_mode newmode, ThreadContext *tc) +{ + Addr pcbb = tc->readMiscReg(AlphaISA::IPR_PALtemp23); + + if (newmode == kernel && pcbb == idleProcess) + newmode = idle; + + changeMode(newmode, tc); +} + +void +Statistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc) +{ + assert(themode != user); + + _swap_context++; + changeMode(newpcbb == idleProcess ? idle : kernel, tc); +} + +void +Statistics::callpal(int code, ThreadContext *tc) +{ + if (!PAL::name(code)) + return; + + _callpal[code]++; + + switch (code) { + case PAL::callsys: { + int number = tc->readIntReg(0); + if (SystemCalls::validSyscallNumber(number)) { + int cvtnum = SystemCalls::convert(number); + _syscall[cvtnum]++; + } + } break; + } +} + +void +Statistics::serialize(ostream &os) +{ + ::Kernel::Statistics::serialize(os); + int exemode = themode; + SERIALIZE_SCALAR(exemode); + SERIALIZE_SCALAR(idleProcess); + SERIALIZE_SCALAR(lastModeTick); +} + +void +Statistics::unserialize(Checkpoint *cp, const string §ion) +{ + ::Kernel::Statistics::unserialize(cp, section); + int exemode; + UNSERIALIZE_SCALAR(exemode); + UNSERIALIZE_SCALAR(idleProcess); + UNSERIALIZE_SCALAR(lastModeTick); + themode = (cpu_mode)exemode; +} + +} /* end namespace AlphaISA::Kernel */ +} /* end namespace AlphaISA */ diff --git a/src/arch/alpha/kernel_stats.hh b/src/arch/alpha/kernel_stats.hh new file mode 100644 index 000000000..7b8640ad7 --- /dev/null +++ b/src/arch/alpha/kernel_stats.hh @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2004-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: Lisa Hsu + * Nathan Binkert + */ + +#ifndef __ARCH_ALPHA_KERNEL_STATS_HH__ +#define __ARCH_ALPHA_KERNEL_STATS_HH__ + +#include +#include +#include +#include + +#include "cpu/static_inst.hh" +#include "kern/kernel_stats.hh" + +class BaseCPU; +class ThreadContext; +class FnEvent; +// What does kernel stats expect is included? +class System; + +namespace AlphaISA { +namespace Kernel { + +enum cpu_mode { kernel, user, idle, cpu_mode_num }; +extern const char *modestr[]; + +class Statistics : public ::Kernel::Statistics +{ + protected: + Addr idleProcess; + cpu_mode themode; + Tick lastModeTick; + + void changeMode(cpu_mode newmode, ThreadContext *tc); + + private: + Stats::Vector<> _callpal; +// Stats::Vector<> _faults; + + Stats::Vector<> _mode; + Stats::Vector<> _modeGood; + Stats::Formula _modeFraction; + Stats::Vector<> _modeTicks; + + Stats::Scalar<> _swap_context; + + public: + Statistics(System *system); + + void regStats(const std::string &name); + + public: + void mode(cpu_mode newmode, ThreadContext *tc); + void context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc); + void callpal(int code, ThreadContext *tc); + void hwrei() { _hwrei++; } + + void setIdleProcess(Addr idle, ThreadContext *tc); + + public: + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); +}; + +} /* end namespace AlphaISA::Kernel */ +} /* end namespace AlphaISA */ + +#endif // __ARCH_ALPHA_KERNEL_STATS_HH__ diff --git a/src/arch/alpha/linux/system.cc b/src/arch/alpha/linux/system.cc index 00684edbb..9a452e10f 100644 --- a/src/arch/alpha/linux/system.cc +++ b/src/arch/alpha/linux/system.cc @@ -42,6 +42,7 @@ #include "arch/arguments.hh" #include "arch/vtophys.hh" +#include "arch/alpha/idle_event.hh" #include "arch/alpha/linux/system.hh" #include "arch/alpha/linux/threadinfo.hh" #include "arch/alpha/system.hh" @@ -49,7 +50,6 @@ #include "cpu/thread_context.hh" #include "cpu/base.hh" #include "dev/platform.hh" -#include "kern/alpha/idle_event.hh" #include "kern/linux/printk.hh" #include "kern/linux/events.hh" #include "mem/physical.hh" diff --git a/src/arch/alpha/linux/system.hh b/src/arch/alpha/linux/system.hh index d4c92ac01..14396f8ab 100644 --- a/src/arch/alpha/linux/system.hh +++ b/src/arch/alpha/linux/system.hh @@ -38,8 +38,8 @@ class ThreadContext; class BreakPCEvent; class IdleStartEvent; +#include "arch/alpha/idle_event.hh" #include "arch/alpha/system.hh" -#include "kern/alpha/idle_event.hh" #include "kern/linux/events.hh" using namespace AlphaISA; diff --git a/src/arch/sparc/kernel_stats.hh b/src/arch/sparc/kernel_stats.hh new file mode 100644 index 000000000..c007c54c2 --- /dev/null +++ b/src/arch/sparc/kernel_stats.hh @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2004-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: Gabe Black + */ + +#ifndef __ARCH_SPARC_KERNEL_STATS_HH__ +#define __ARCH_SPARC_KERNEL_STATS_HH__ + +#include +#include +#include +#include + +#include "kern/kernel_stats.hh" + +namespace SparcISA { +namespace Kernel { + +enum cpu_mode { hypervisor, kernel, user, idle, cpu_mode_num }; +extern const char *modestr[]; + +class Statistics : public ::Kernel::Statistics +{ + public: + Statistics(System *system) : ::Kernel::Statistics(system) + {} +}; + +} /* end namespace AlphaISA::Kernel */ +} /* end namespace AlphaISA */ + +#endif // __ARCH_SPARC_KERNEL_STATS_HH__ diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc index 2e81b7b31..d6cd9409b 100644 --- a/src/cpu/checker/cpu.cc +++ b/src/cpu/checker/cpu.cc @@ -38,8 +38,8 @@ #include "cpu/thread_context.hh" #if FULL_SYSTEM +#include "arch/kernel_stats.hh" #include "arch/vtophys.hh" -#include "kern/kernel_stats.hh" #endif // FULL_SYSTEM using namespace std; diff --git a/src/cpu/o3/alpha/cpu_impl.hh b/src/cpu/o3/alpha/cpu_impl.hh index 750ccc912..04eadfa5a 100644 --- a/src/cpu/o3/alpha/cpu_impl.hh +++ b/src/cpu/o3/alpha/cpu_impl.hh @@ -48,8 +48,8 @@ #if FULL_SYSTEM #include "arch/alpha/osfpal.hh" #include "arch/isa_traits.hh" +#include "arch/kernel_stats.hh" #include "cpu/quiesce_event.hh" -#include "kern/kernel_stats.hh" #include "sim/sim_exit.hh" #include "sim/system.hh" #endif diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh index 772cd76f0..598af123e 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -39,7 +39,7 @@ #include "cpu/o3/comm.hh" #if FULL_SYSTEM -#include "kern/kernel_stats.hh" +#include "arch/kernel_stats.hh" #endif #include diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh index b83cf4e9e..86c973a0f 100644 --- a/src/cpu/ozone/cpu_impl.hh +++ b/src/cpu/ozone/cpu_impl.hh @@ -47,12 +47,12 @@ #if FULL_SYSTEM #include "arch/faults.hh" #include "arch/alpha/osfpal.hh" -#include "arch/alpha/tlb.hh" -#include "arch/alpha/types.hh" +#include "arch/tlb.hh" +#include "arch/types.hh" +#include "arch/kernel_stats.hh" #include "arch/vtophys.hh" #include "base/callback.hh" #include "cpu/profile.hh" -#include "kern/kernel_stats.hh" #include "mem/physical.hh" #include "sim/faults.hh" #include "sim/sim_events.hh" diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh index 426841536..05a66d77a 100644 --- a/src/cpu/ozone/dyn_inst_impl.hh +++ b/src/cpu/ozone/dyn_inst_impl.hh @@ -31,7 +31,10 @@ #include "sim/faults.hh" #include "config/full_system.hh" #include "cpu/ozone/dyn_inst.hh" + +#if FULL_SYSTEM #include "kern/kernel_stats.hh" +#endif template OzoneDynInst::OzoneDynInst(OzoneCPU *cpu) diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index b7df39218..00fa4d247 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -57,11 +57,11 @@ #include "sim/system.hh" #if FULL_SYSTEM -#include "arch/tlb.hh" +#include "arch/kernel_stats.hh" #include "arch/stacktrace.hh" +#include "arch/tlb.hh" #include "arch/vtophys.hh" #include "base/remote_gdb.hh" -#include "kern/kernel_stats.hh" #else // !FULL_SYSTEM #include "mem/mem_object.hh" #endif // FULL_SYSTEM diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 5ae1e1d3c..1edcbf352 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -39,13 +39,13 @@ #include "cpu/thread_context.hh" #if FULL_SYSTEM +#include "arch/kernel_stats.hh" #include "base/callback.hh" #include "base/cprintf.hh" #include "base/output.hh" #include "base/trace.hh" #include "cpu/profile.hh" #include "cpu/quiesce_event.hh" -#include "kern/kernel_stats.hh" #include "sim/serialize.hh" #include "sim/sim_exit.hh" #include "arch/stacktrace.hh" diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc index a6fff5fc3..8602f8a50 100644 --- a/src/cpu/thread_state.cc +++ b/src/cpu/thread_state.cc @@ -37,8 +37,8 @@ #include "sim/serialize.hh" #if FULL_SYSTEM +#include "arch/kernel_stats.hh" #include "cpu/quiesce_event.hh" -#include "kern/kernel_stats.hh" #endif #if FULL_SYSTEM diff --git a/src/kern/SConscript b/src/kern/SConscript index 7245e2889..12df28836 100644 --- a/src/kern/SConscript +++ b/src/kern/SConscript @@ -34,7 +34,7 @@ import os.path, sys Import('env') sources = Split(''' - base_kernel_stats.cc + kernel_stats.cc system_events.cc linux/events.cc linux/linux_syscalls.cc @@ -45,25 +45,4 @@ sources = Split(''' # path relative to the top of the directory tree. sources = [File(s) for s in sources] -################################################################# -# -# ISA "switch header" generation. -# -# Auto-generate arch headers that include the right ISA-specific -# header based on the setting of THE_ISA preprocessor variable. -# -################################################################# - -# List of headers to generate -kern_switch_hdrs = Split(''' - kernel_stats.hh - ''') - -env.make_switching_dir('kern', kern_switch_hdrs, env) - -isa = env['TARGET_ISA'] # someday this may be a list of ISAs - -# Let the target architecture define what additional sources it needs -sources += SConscript(os.path.join(isa, 'SConscript'), exports = 'env') - Return('sources') diff --git a/src/kern/alpha/idle_event.cc b/src/kern/alpha/idle_event.cc deleted file mode 100644 index 3f07b6c16..000000000 --- a/src/kern/alpha/idle_event.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2004-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: Lisa Hsu - * Nathan Binkert - */ - -#include "cpu/thread_context.hh" -#include "kern/alpha/idle_event.hh" -#include "kern/kernel_stats.hh" - -using namespace TheISA; - -void -IdleStartEvent::process(ThreadContext *tc) -{ - if (tc->getKernelStats()) - tc->getKernelStats()->setIdleProcess( - tc->readMiscReg(AlphaISA::IPR_PALtemp23), tc); - remove(); -} diff --git a/src/kern/alpha/idle_event.hh b/src/kern/alpha/idle_event.hh deleted file mode 100644 index 97d5bdd6e..000000000 --- a/src/kern/alpha/idle_event.hh +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2004-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: Nathan Binkert - * Lisa Hsu - * Ali Saidi - */ - -#ifndef __KERN_ALPHA_IDLE_EVENT_HH__ -#define __KERN_ALPHA_IDLE_EVENT_HH__ - -#include "cpu/pc_event.hh" - -class IdleStartEvent : public PCEvent -{ - public: - IdleStartEvent(PCEventQueue *q, const std::string &desc, Addr addr) - : PCEvent(q, desc, addr) - {} - virtual void process(ThreadContext *tc); -}; - -#endif // __KERN_ALPHA_IDLE_EVENT_HH__ diff --git a/src/kern/alpha/kernel_stats.cc b/src/kern/alpha/kernel_stats.cc deleted file mode 100644 index 7b74295e4..000000000 --- a/src/kern/alpha/kernel_stats.cc +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2004-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: Lisa Hsu - * Nathan Binkert - */ - -#include -#include -#include - -#include "kern/alpha/kernel_stats.hh" -#include "arch/alpha/osfpal.hh" -#include "base/trace.hh" -#include "cpu/thread_context.hh" -#include "kern/tru64/tru64_syscalls.hh" -#include "sim/system.hh" - -using namespace std; -using namespace Stats; - -namespace AlphaISA { -namespace Kernel { - -const char *modestr[] = { "kernel", "user", "idle" }; - -Statistics::Statistics(System *system) - : ::Kernel::Statistics(system), - idleProcess((Addr)-1), themode(kernel), lastModeTick(0) -{ -} - -void -Statistics::regStats(const string &_name) -{ - ::Kernel::Statistics::regStats(_name); - - _callpal - .init(256) - .name(name() + ".callpal") - .desc("number of callpals executed") - .flags(total | pdf | nozero | nonan) - ; - - for (int i = 0; i < PAL::NumCodes; ++i) { - const char *str = PAL::name(i); - if (str) - _callpal.subname(i, str); - } - - _hwrei - .name(name() + ".inst.hwrei") - .desc("number of hwrei instructions executed") - ; - - _mode - .init(cpu_mode_num) - .name(name() + ".mode_switch") - .desc("number of protection mode switches") - ; - - for (int i = 0; i < cpu_mode_num; ++i) - _mode.subname(i, modestr[i]); - - _modeGood - .init(cpu_mode_num) - .name(name() + ".mode_good") - ; - - for (int i = 0; i < cpu_mode_num; ++i) - _modeGood.subname(i, modestr[i]); - - _modeFraction - .name(name() + ".mode_switch_good") - .desc("fraction of useful protection mode switches") - .flags(total) - ; - - for (int i = 0; i < cpu_mode_num; ++i) - _modeFraction.subname(i, modestr[i]); - - _modeFraction = _modeGood / _mode; - - _modeTicks - .init(cpu_mode_num) - .name(name() + ".mode_ticks") - .desc("number of ticks spent at the given mode") - .flags(pdf) - ; - for (int i = 0; i < cpu_mode_num; ++i) - _modeTicks.subname(i, modestr[i]); - - _swap_context - .name(name() + ".swap_context") - .desc("number of times the context was actually changed") - ; -} - -void -Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc) -{ - assert(themode == kernel); - idleProcess = idlepcbb; - themode = idle; - changeMode(themode, tc); -} - -void -Statistics::changeMode(cpu_mode newmode, ThreadContext *tc) -{ - _mode[newmode]++; - - if (newmode == themode) - return; - - DPRINTF(Context, "old mode=%-8s new mode=%-8s\n", - modestr[themode], modestr[newmode]); - - _modeGood[newmode]++; - _modeTicks[themode] += curTick - lastModeTick; - - lastModeTick = curTick; - themode = newmode; -} - -void -Statistics::mode(cpu_mode newmode, ThreadContext *tc) -{ - Addr pcbb = tc->readMiscReg(AlphaISA::IPR_PALtemp23); - - if (newmode == kernel && pcbb == idleProcess) - newmode = idle; - - changeMode(newmode, tc); -} - -void -Statistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc) -{ - assert(themode != user); - - _swap_context++; - changeMode(newpcbb == idleProcess ? idle : kernel, tc); -} - -void -Statistics::callpal(int code, ThreadContext *tc) -{ - if (!PAL::name(code)) - return; - - _callpal[code]++; - - switch (code) { - case PAL::callsys: { - int number = tc->readIntReg(0); - if (SystemCalls::validSyscallNumber(number)) { - int cvtnum = SystemCalls::convert(number); - _syscall[cvtnum]++; - } - } break; - } -} - -void -Statistics::serialize(ostream &os) -{ - ::Kernel::Statistics::serialize(os); - int exemode = themode; - SERIALIZE_SCALAR(exemode); - SERIALIZE_SCALAR(idleProcess); - SERIALIZE_SCALAR(lastModeTick); -} - -void -Statistics::unserialize(Checkpoint *cp, const string §ion) -{ - ::Kernel::Statistics::unserialize(cp, section); - int exemode; - UNSERIALIZE_SCALAR(exemode); - UNSERIALIZE_SCALAR(idleProcess); - UNSERIALIZE_SCALAR(lastModeTick); - themode = (cpu_mode)exemode; -} - -} /* end namespace AlphaISA::Kernel */ -} /* end namespace AlphaISA */ diff --git a/src/kern/alpha/kernel_stats.hh b/src/kern/alpha/kernel_stats.hh deleted file mode 100644 index 90058e507..000000000 --- a/src/kern/alpha/kernel_stats.hh +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2004-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: Lisa Hsu - * Nathan Binkert - */ - -#ifndef __ARCH_ALPHA_KERNEL_STATS_HH__ -#define __ARCH_ALPHA_KERNEL_STATS_HH__ - -#include -#include -#include -#include - -#include "cpu/static_inst.hh" -#include "kern/base_kernel_stats.hh" - -class BaseCPU; -class ThreadContext; -class FnEvent; -// What does kernel stats expect is included? -class System; - -namespace AlphaISA { -namespace Kernel { - -enum cpu_mode { kernel, user, idle, cpu_mode_num }; -extern const char *modestr[]; - -class Statistics : public ::Kernel::Statistics -{ - protected: - Addr idleProcess; - cpu_mode themode; - Tick lastModeTick; - - void changeMode(cpu_mode newmode, ThreadContext *tc); - - private: - Stats::Vector<> _callpal; -// Stats::Vector<> _faults; - - Stats::Vector<> _mode; - Stats::Vector<> _modeGood; - Stats::Formula _modeFraction; - Stats::Vector<> _modeTicks; - - Stats::Scalar<> _swap_context; - - public: - Statistics(System *system); - - void regStats(const std::string &name); - - public: - void mode(cpu_mode newmode, ThreadContext *tc); - void context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc); - void callpal(int code, ThreadContext *tc); - void hwrei() { _hwrei++; } - - void setIdleProcess(Addr idle, ThreadContext *tc); - - public: - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); -}; - -} /* end namespace AlphaISA::Kernel */ -} /* end namespace AlphaISA */ - -#endif // __ARCH_ALPHA_KERNEL_STATS_HH__ diff --git a/src/kern/base_kernel_stats.cc b/src/kern/base_kernel_stats.cc deleted file mode 100644 index d29672753..000000000 --- a/src/kern/base_kernel_stats.cc +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2004-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: Lisa Hsu - * Nathan Binkert - */ - -#include - -#include "base/trace.hh" -#include "cpu/thread_context.hh" -#include "kern/base_kernel_stats.hh" -#include "kern/tru64/tru64_syscalls.hh" -#include "sim/system.hh" - -using namespace std; -using namespace Stats; - -namespace Kernel { - -Statistics::Statistics(System *system) - : iplLast(0), iplLastTick(0) -{ -} - -void -Statistics::regStats(const string &_name) -{ - myname = _name; - - _arm - .name(name() + ".inst.arm") - .desc("number of arm instructions executed") - ; - - _quiesce - .name(name() + ".inst.quiesce") - .desc("number of quiesce instructions executed") - ; - - _iplCount - .init(32) - .name(name() + ".ipl_count") - .desc("number of times we switched to this ipl") - .flags(total | pdf | nozero | nonan) - ; - - _iplGood - .init(32) - .name(name() + ".ipl_good") - .desc("number of times we switched to this ipl from a different ipl") - .flags(total | pdf | nozero | nonan) - ; - - _iplTicks - .init(32) - .name(name() + ".ipl_ticks") - .desc("number of cycles we spent at this ipl") - .flags(total | pdf | nozero | nonan) - ; - - _iplUsed - .name(name() + ".ipl_used") - .desc("fraction of swpipl calls that actually changed the ipl") - .flags(total | nozero | nonan) - ; - - _iplUsed = _iplGood / _iplCount; - - _syscall - .init(SystemCalls::Number) - .name(name() + ".syscall") - .desc("number of syscalls executed") - .flags(total | pdf | nozero | nonan) - ; - - //@todo This needs to get the names of syscalls from an appropriate place. -#if 0 - for (int i = 0; i < SystemCalls::Number; ++i) { - const char *str = SystemCalls::name(i); - if (str) { - _syscall.subname(i, str); - } - } -#endif -} - -void -Statistics::swpipl(int ipl) -{ - assert(ipl >= 0 && ipl <= 0x1f && "invalid IPL\n"); - - _iplCount[ipl]++; - - if (ipl == iplLast) - return; - - _iplGood[ipl]++; - _iplTicks[iplLast] += curTick - iplLastTick; - iplLastTick = curTick; - iplLast = ipl; -} - -void -Statistics::serialize(ostream &os) -{ - SERIALIZE_SCALAR(iplLast); - SERIALIZE_SCALAR(iplLastTick); -} - -void -Statistics::unserialize(Checkpoint *cp, const string §ion) -{ - UNSERIALIZE_SCALAR(iplLast); - UNSERIALIZE_SCALAR(iplLastTick); -} - -/* end namespace Kernel */ } diff --git a/src/kern/base_kernel_stats.hh b/src/kern/base_kernel_stats.hh deleted file mode 100644 index 66248c9c8..000000000 --- a/src/kern/base_kernel_stats.hh +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2004-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: Lisa Hsu - * Nathan Binkert - */ - -#ifndef __KERNEL_STATS_HH__ -#define __KERNEL_STATS_HH__ - -#include - -#include "cpu/static_inst.hh" -#include "sim/serialize.hh" - -class BaseCPU; -class ThreadContext; -class FnEvent; -// What does kernel stats expect is included? -class System; - -namespace Kernel { - -class Statistics : public Serializable -{ - protected: - std::string myname; - - protected: - Stats::Scalar<> _arm; - Stats::Scalar<> _quiesce; - Stats::Scalar<> _hwrei; - - Stats::Vector<> _iplCount; - Stats::Vector<> _iplGood; - Stats::Vector<> _iplTicks; - Stats::Formula _iplUsed; - - Stats::Vector<> _syscall; -// Stats::Vector<> _faults; - - private: - int iplLast; - Tick iplLastTick; - - public: - Statistics(System *system); - virtual ~Statistics() {} - - const std::string name() const { return myname; } - void regStats(const std::string &name); - - public: - void arm() { _arm++; } - void quiesce() { _quiesce++; } - void swpipl(int ipl); - - public: - virtual void serialize(std::ostream &os); - virtual void unserialize(Checkpoint *cp, const std::string §ion); -}; - -/* end namespace Kernel */ } - -#endif // __KERNEL_STATS_HH__ diff --git a/src/kern/kernel_stats.cc b/src/kern/kernel_stats.cc new file mode 100644 index 000000000..29c77b3d9 --- /dev/null +++ b/src/kern/kernel_stats.cc @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2004-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: Lisa Hsu + * Nathan Binkert + */ + +#include + +#include "base/trace.hh" +#include "cpu/thread_context.hh" +#include "kern/kernel_stats.hh" +#include "kern/tru64/tru64_syscalls.hh" +#include "sim/system.hh" + +using namespace std; +using namespace Stats; + +namespace Kernel { + +Statistics::Statistics(System *system) + : iplLast(0), iplLastTick(0) +{ +} + +void +Statistics::regStats(const string &_name) +{ + myname = _name; + + _arm + .name(name() + ".inst.arm") + .desc("number of arm instructions executed") + ; + + _quiesce + .name(name() + ".inst.quiesce") + .desc("number of quiesce instructions executed") + ; + + _iplCount + .init(32) + .name(name() + ".ipl_count") + .desc("number of times we switched to this ipl") + .flags(total | pdf | nozero | nonan) + ; + + _iplGood + .init(32) + .name(name() + ".ipl_good") + .desc("number of times we switched to this ipl from a different ipl") + .flags(total | pdf | nozero | nonan) + ; + + _iplTicks + .init(32) + .name(name() + ".ipl_ticks") + .desc("number of cycles we spent at this ipl") + .flags(total | pdf | nozero | nonan) + ; + + _iplUsed + .name(name() + ".ipl_used") + .desc("fraction of swpipl calls that actually changed the ipl") + .flags(total | nozero | nonan) + ; + + _iplUsed = _iplGood / _iplCount; + + _syscall + .init(SystemCalls::Number) + .name(name() + ".syscall") + .desc("number of syscalls executed") + .flags(total | pdf | nozero | nonan) + ; + + //@todo This needs to get the names of syscalls from an appropriate place. +#if 0 + for (int i = 0; i < SystemCalls::Number; ++i) { + const char *str = SystemCalls::name(i); + if (str) { + _syscall.subname(i, str); + } + } +#endif +} + +void +Statistics::swpipl(int ipl) +{ + assert(ipl >= 0 && ipl <= 0x1f && "invalid IPL\n"); + + _iplCount[ipl]++; + + if (ipl == iplLast) + return; + + _iplGood[ipl]++; + _iplTicks[iplLast] += curTick - iplLastTick; + iplLastTick = curTick; + iplLast = ipl; +} + +void +Statistics::serialize(ostream &os) +{ + SERIALIZE_SCALAR(iplLast); + SERIALIZE_SCALAR(iplLastTick); +} + +void +Statistics::unserialize(Checkpoint *cp, const string §ion) +{ + UNSERIALIZE_SCALAR(iplLast); + UNSERIALIZE_SCALAR(iplLastTick); +} + +/* end namespace Kernel */ } diff --git a/src/kern/kernel_stats.hh b/src/kern/kernel_stats.hh new file mode 100644 index 000000000..66248c9c8 --- /dev/null +++ b/src/kern/kernel_stats.hh @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2004-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: Lisa Hsu + * Nathan Binkert + */ + +#ifndef __KERNEL_STATS_HH__ +#define __KERNEL_STATS_HH__ + +#include + +#include "cpu/static_inst.hh" +#include "sim/serialize.hh" + +class BaseCPU; +class ThreadContext; +class FnEvent; +// What does kernel stats expect is included? +class System; + +namespace Kernel { + +class Statistics : public Serializable +{ + protected: + std::string myname; + + protected: + Stats::Scalar<> _arm; + Stats::Scalar<> _quiesce; + Stats::Scalar<> _hwrei; + + Stats::Vector<> _iplCount; + Stats::Vector<> _iplGood; + Stats::Vector<> _iplTicks; + Stats::Formula _iplUsed; + + Stats::Vector<> _syscall; +// Stats::Vector<> _faults; + + private: + int iplLast; + Tick iplLastTick; + + public: + Statistics(System *system); + virtual ~Statistics() {} + + const std::string name() const { return myname; } + void regStats(const std::string &name); + + public: + void arm() { _arm++; } + void quiesce() { _quiesce++; } + void swpipl(int ipl); + + public: + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +/* end namespace Kernel */ } + +#endif // __KERNEL_STATS_HH__ diff --git a/src/kern/sparc/kernel_stats.hh b/src/kern/sparc/kernel_stats.hh deleted file mode 100644 index 72bffd2b2..000000000 --- a/src/kern/sparc/kernel_stats.hh +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2004-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: Gabe Black - */ - -#ifndef __ARCH_SPARC_KERNEL_STATS_HH__ -#define __ARCH_SPARC_KERNEL_STATS_HH__ - -#include -#include -#include -#include - -#include "kern/base_kernel_stats.hh" - -namespace SparcISA { -namespace Kernel { - -enum cpu_mode { hypervisor, kernel, user, idle, cpu_mode_num }; -extern const char *modestr[]; - -class Statistics : public ::Kernel::Statistics -{ - public: - Statistics(System *system) : ::Kernel::Statistics(system) - {} -}; - -} /* end namespace AlphaISA::Kernel */ -} /* end namespace AlphaISA */ - -#endif // __ARCH_SPARC_KERNEL_STATS_HH__ diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index 548d0c167..66036def1 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -34,14 +34,14 @@ #include -#include "sim/pseudo_inst.hh" #include "arch/vtophys.hh" #include "base/annotate.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" #include "cpu/quiesce_event.hh" -#include "kern/kernel_stats.hh" +#include "arch/kernel_stats.hh" #include "sim/param.hh" +#include "sim/pseudo_inst.hh" #include "sim/serialize.hh" #include "sim/sim_exit.hh" #include "sim/stat_control.hh" -- cgit v1.2.3 From 90408b7d029b94eae03121d913777f616ac1ce77 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 23:33:59 -0500 Subject: Fixed to account for branch delay slots. --HG-- extra : convert_revision : 36a91ad4ed56c61b6754548034a13c02cf580fc6 --- src/kern/system_events.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/kern/system_events.cc b/src/kern/system_events.cc index a6337a2fd..6fd9e1563 100644 --- a/src/kern/system_events.cc +++ b/src/kern/system_events.cc @@ -29,6 +29,8 @@ * Nathan Binkert */ +//For ISA_HAS_DELAY_SLOT +#include "arch/isa_traits.hh" #include "base/trace.hh" #include "cpu/thread_context.hh" #include "kern/system_events.hh" @@ -45,4 +47,7 @@ SkipFuncEvent::process(ThreadContext *tc) tc->setPC(newpc); tc->setNextPC(tc->readPC() + sizeof(TheISA::MachInst)); +#if ISA_HAS_DELAY_SLOT + tc->setNextPC(tc->readNextPC() + sizeof(TheISA::MachInst)); +#endif } -- cgit v1.2.3 From 1a5d5d0b561591a5775d4b5a253360b7cea9076e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Nov 2006 23:40:54 -0500 Subject: Force remote gdb code to use signal numbers and not ISA specific trap numbers. --HG-- extra : convert_revision : 4f45a4b48e3993ac6991db2afffbce2e666eab6c --- src/arch/alpha/kgdb.h | 11 ----------- src/arch/alpha/system.cc | 4 +++- 2 files changed, 3 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/kgdb.h b/src/arch/alpha/kgdb.h index 104244d0b..912cf6d45 100644 --- a/src/arch/alpha/kgdb.h +++ b/src/arch/alpha/kgdb.h @@ -160,15 +160,4 @@ /* Too much? Must be large enough for register transfer. */ #define KGDB_BUFLEN 1024 -/* - * Kernel Entry Vectors. [OSF/1 PALcode Specific] - */ - -#define ALPHA_KENTRY_INT 0 -#define ALPHA_KENTRY_ARITH 1 -#define ALPHA_KENTRY_MM 2 -#define ALPHA_KENTRY_IF 3 -#define ALPHA_KENTRY_UNA 4 -#define ALPHA_KENTRY_SYS 5 - #endif /* __KGDB_H__ */ diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc index 710f6ef46..cd923948c 100644 --- a/src/arch/alpha/system.cc +++ b/src/arch/alpha/system.cc @@ -29,6 +29,8 @@ * Nathan Binkert */ +#include + #include "arch/alpha/ev5.hh" #include "arch/alpha/system.hh" #include "arch/alpha/remote_gdb.hh" @@ -196,7 +198,7 @@ AlphaSystem::setAlphaAccess(Addr access) bool AlphaSystem::breakpoint() { - return remoteGDB[0]->trap(ALPHA_KENTRY_INT); + return remoteGDB[0]->trap(SIGTRAP); } void -- cgit v1.2.3 From 746ceb93fdb13f74ea2e18f980d122f8bfb5cd0a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 00:32:04 -0500 Subject: Replaced getArg with a SPARC implementation. --HG-- extra : convert_revision : ba31171a81b6c46de2997de2701d35fcf8c614b7 --- src/arch/sparc/arguments.cc | 16 +++++++++------- src/arch/sparc/arguments.hh | 4 ++-- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/arguments.cc b/src/arch/sparc/arguments.cc index a0a31567e..44adf4a15 100644 --- a/src/arch/sparc/arguments.cc +++ b/src/arch/sparc/arguments.cc @@ -54,16 +54,18 @@ Arguments::Data::alloc(size_t size) uint64_t Arguments::getArg(bool fp) { - //XXX This needs to be replaced with the sparc version + //The caller uses %o0-%05 for the first 6 arguments even if their floating + //point. Double precision floating point values take two registers/args. + //Quads, structs, and unions are passed as pointers. All arguments beyond + //the sixth are passed on the stack past the 16 word window save area, + //space for the struct/union return pointer, and space reserved for the + //first 6 arguments which the caller may use but doesn't have to. if (number < 6) { - if (fp) - return tc->readFloatRegBits(16 + number); - else - return tc->readIntReg(16 + number); + return tc->readIntReg(8 + number); } else { - Addr sp = tc->readIntReg(30); + Addr sp = tc->readIntReg(14); VirtualPort *vp = tc->getVirtPort(tc); - uint64_t arg = vp->read(sp + (number-6) * sizeof(uint64_t)); + uint64_t arg = vp->read(sp + 92 + (number-6) * sizeof(uint64_t)); tc->delVirtPort(vp); return arg; } diff --git a/src/arch/sparc/arguments.hh b/src/arch/sparc/arguments.hh index 0d059a564..8f925dd25 100644 --- a/src/arch/sparc/arguments.hh +++ b/src/arch/sparc/arguments.hh @@ -144,6 +144,6 @@ class Arguments } }; -}; // namespace AlphaISA +}; // namespace SparcISA -#endif // __ARCH_ALPHA_ARGUMENTS_HH__ +#endif // __ARCH_SPARC_ARGUMENTS_HH__ -- cgit v1.2.3 From 16a012e80da8beb2e147bf62ed0d054ed1c0d600 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 00:32:40 -0500 Subject: Stubs for SPARC's tlbs --HG-- extra : convert_revision : ba08da78693cc6f59f7358134f121f471910dbf6 --- src/arch/sparc/tlb.cc | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/arch/sparc/tlb.hh | 16 ++++++++++- 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 src/arch/sparc/tlb.cc (limited to 'src') diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc new file mode 100644 index 000000000..0b1a2ff5f --- /dev/null +++ b/src/arch/sparc/tlb.cc @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2001-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: Nathan Binkert + * Steve Reinhardt + * Andrew Schultz + */ + +#include "arch/sparc/tlb.hh" +#include "sim/builder.hh" + +namespace SparcISA +{ + DEFINE_SIM_OBJECT_CLASS_NAME("SparcTLB", TLB) + + BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITB) + + Param size; + + END_DECLARE_SIM_OBJECT_PARAMS(ITB) + + BEGIN_INIT_SIM_OBJECT_PARAMS(ITB) + + INIT_PARAM_DFLT(size, "TLB size", 48) + + END_INIT_SIM_OBJECT_PARAMS(ITB) + + + CREATE_SIM_OBJECT(ITB) + { + return new ITB(getInstanceName(), size); + } + + REGISTER_SIM_OBJECT("SparcITB", ITB) + + BEGIN_DECLARE_SIM_OBJECT_PARAMS(DTB) + + Param size; + + END_DECLARE_SIM_OBJECT_PARAMS(DTB) + + BEGIN_INIT_SIM_OBJECT_PARAMS(DTB) + + INIT_PARAM_DFLT(size, "TLB size", 64) + + END_INIT_SIM_OBJECT_PARAMS(DTB) + + + CREATE_SIM_OBJECT(DTB) + { + return new DTB(getInstanceName(), size); + } + + REGISTER_SIM_OBJECT("SparcDTB", DTB) +} diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh index 0d42e2c97..0fdba6baf 100644 --- a/src/arch/sparc/tlb.hh +++ b/src/arch/sparc/tlb.hh @@ -31,19 +31,29 @@ #ifndef __ARCH_SPARC_TLB_HH__ #define __ARCH_SPARC_TLB_HH__ +#include "mem/request.hh" #include "sim/faults.hh" +#include "sim/sim_object.hh" class ThreadContext; namespace SparcISA { - class TLB + class TLB : public SimObject { + public: + TLB(const std::string &name, int size) : SimObject(name) + { + } }; class ITB : public TLB { public: + ITB(const std::string &name, int size) : TLB(name, size) + { + } + Fault translate(RequestPtr &req, ThreadContext *tc) const { return NoFault; @@ -53,6 +63,10 @@ namespace SparcISA class DTB : public TLB { public: + DTB(const std::string &name, int size) : TLB(name, size) + { + } + Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const { return NoFault; -- cgit v1.2.3 From f1a55570d305dd15d7bc9667453a0ca14bf16462 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 00:52:04 -0500 Subject: Put the ProcessInfo and StackTrace objects into the ISA namespaces. --HG-- extra : convert_revision : 1626703583f02a1c9823874290462c1b6bdb6c3c --- src/arch/alpha/stacktrace.cc | 518 +++++++++++++++++++++--------------------- src/arch/alpha/stacktrace.hh | 130 +++++------ src/arch/sparc/stacktrace.cc | 521 ++++++++++++++++++++++--------------------- src/arch/sparc/stacktrace.hh | 131 +++++------ src/cpu/profile.hh | 4 +- src/mem/port_impl.hh | 7 +- 6 files changed, 662 insertions(+), 649 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/stacktrace.cc b/src/arch/alpha/stacktrace.cc index d70a4d6dd..c4612e156 100644 --- a/src/arch/alpha/stacktrace.cc +++ b/src/arch/alpha/stacktrace.cc @@ -40,329 +40,331 @@ #include "sim/system.hh" using namespace std; -using namespace AlphaISA; -ProcessInfo::ProcessInfo(ThreadContext *_tc) - : tc(_tc) +namespace AlphaISA { - Addr addr = 0; + ProcessInfo::ProcessInfo(ThreadContext *_tc) + : tc(_tc) + { + Addr addr = 0; - VirtualPort *vp; + VirtualPort *vp; - vp = tc->getVirtPort(); + vp = tc->getVirtPort(); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) - panic("thread info not compiled into kernel\n"); - thread_info_size = vp->readGtoH(addr); + if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) + panic("thread info not compiled into kernel\n"); + thread_info_size = vp->readGtoH(addr); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) - panic("thread info not compiled into kernel\n"); - task_struct_size = vp->readGtoH(addr); + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) + panic("thread info not compiled into kernel\n"); + task_struct_size = vp->readGtoH(addr); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) - panic("thread info not compiled into kernel\n"); - task_off = vp->readGtoH(addr); + if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) + panic("thread info not compiled into kernel\n"); + task_off = vp->readGtoH(addr); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) - panic("thread info not compiled into kernel\n"); - pid_off = vp->readGtoH(addr); + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) + panic("thread info not compiled into kernel\n"); + pid_off = vp->readGtoH(addr); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) - panic("thread info not compiled into kernel\n"); - name_off = vp->readGtoH(addr); + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) + panic("thread info not compiled into kernel\n"); + name_off = vp->readGtoH(addr); - tc->delVirtPort(vp); -} - -Addr -ProcessInfo::task(Addr ksp) const -{ - Addr base = ksp & ~0x3fff; - if (base == ULL(0xfffffc0000000000)) - return 0; + tc->delVirtPort(vp); + } - Addr tsk; + Addr + ProcessInfo::task(Addr ksp) const + { + Addr base = ksp & ~0x3fff; + if (base == ULL(0xfffffc0000000000)) + return 0; - VirtualPort *vp; + Addr tsk; - vp = tc->getVirtPort(); - tsk = vp->readGtoH(base + task_off); - tc->delVirtPort(vp); + VirtualPort *vp; - return tsk; -} + vp = tc->getVirtPort(); + tsk = vp->readGtoH(base + task_off); + tc->delVirtPort(vp); -int -ProcessInfo::pid(Addr ksp) const -{ - Addr task = this->task(ksp); - if (!task) - return -1; + return tsk; + } - uint16_t pd; + int + ProcessInfo::pid(Addr ksp) const + { + Addr task = this->task(ksp); + if (!task) + return -1; - VirtualPort *vp; + uint16_t pd; - vp = tc->getVirtPort(); - pd = vp->readGtoH(task + pid_off); - tc->delVirtPort(vp); + VirtualPort *vp; - return pd; -} + vp = tc->getVirtPort(); + pd = vp->readGtoH(task + pid_off); + tc->delVirtPort(vp); -string -ProcessInfo::name(Addr ksp) const -{ - Addr task = this->task(ksp); - if (!task) - return "console"; + return pd; + } - char comm[256]; - CopyStringOut(tc, comm, task + name_off, sizeof(comm)); - if (!comm[0]) - return "startup"; + string + ProcessInfo::name(Addr ksp) const + { + Addr task = this->task(ksp); + if (!task) + return "console"; - return comm; -} + char comm[256]; + CopyStringOut(tc, comm, task + name_off, sizeof(comm)); + if (!comm[0]) + return "startup"; -StackTrace::StackTrace() - : tc(0), stack(64) -{ -} + return comm; + } -StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) - : tc(0), stack(64) -{ - trace(_tc, inst); -} + StackTrace::StackTrace() + : tc(0), stack(64) + { + } -StackTrace::~StackTrace() -{ -} + StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) + : tc(0), stack(64) + { + trace(_tc, inst); + } -void -StackTrace::trace(ThreadContext *_tc, bool is_call) -{ - tc = _tc; + StackTrace::~StackTrace() + { + } - bool usermode = (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; + void + StackTrace::trace(ThreadContext *_tc, bool is_call) + { + tc = _tc; - Addr pc = tc->readNextPC(); - bool kernel = tc->getSystemPtr()->kernelStart <= pc && - pc <= tc->getSystemPtr()->kernelEnd; + bool usermode = (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; - if (usermode) { - stack.push_back(user); - return; - } + Addr pc = tc->readNextPC(); + bool kernel = tc->getSystemPtr()->kernelStart <= pc && + pc <= tc->getSystemPtr()->kernelEnd; - if (!kernel) { - stack.push_back(console); - return; - } + if (usermode) { + stack.push_back(user); + return; + } - SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; - Addr ksp = tc->readIntReg(TheISA::StackPointerReg); - Addr bottom = ksp & ~0x3fff; - Addr addr; + if (!kernel) { + stack.push_back(console); + return; + } - if (is_call) { - if (!symtab->findNearestAddr(pc, addr)) - panic("could not find address %#x", pc); + SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; + Addr ksp = tc->readIntReg(TheISA::StackPointerReg); + Addr bottom = ksp & ~0x3fff; + Addr addr; - stack.push_back(addr); - pc = tc->readPC(); - } + if (is_call) { + if (!symtab->findNearestAddr(pc, addr)) + panic("could not find address %#x", pc); - Addr ra; - int size; + stack.push_back(addr); + pc = tc->readPC(); + } - while (ksp > bottom) { - if (!symtab->findNearestAddr(pc, addr)) - panic("could not find symbol for pc=%#x", pc); - assert(pc >= addr && "symbol botch: callpc < func"); + Addr ra; + int size; - stack.push_back(addr); + while (ksp > bottom) { + if (!symtab->findNearestAddr(pc, addr)) + panic("could not find symbol for pc=%#x", pc); + assert(pc >= addr && "symbol botch: callpc < func"); - if (isEntry(addr)) - return; + stack.push_back(addr); - if (decodePrologue(ksp, pc, addr, size, ra)) { - if (!ra) + if (isEntry(addr)) return; - if (size <= 0) { + if (decodePrologue(ksp, pc, addr, size, ra)) { + if (!ra) + return; + + if (size <= 0) { + stack.push_back(unknown); + return; + } + + pc = ra; + ksp += size; + } else { stack.push_back(unknown); return; } - pc = ra; - ksp += size; - } else { - stack.push_back(unknown); - return; - } + bool kernel = tc->getSystemPtr()->kernelStart <= pc && + pc <= tc->getSystemPtr()->kernelEnd; + if (!kernel) + return; - bool kernel = tc->getSystemPtr()->kernelStart <= pc && - pc <= tc->getSystemPtr()->kernelEnd; - if (!kernel) - return; + if (stack.size() >= 1000) + panic("unwinding too far"); + } - if (stack.size() >= 1000) - panic("unwinding too far"); + panic("unwinding too far"); } - panic("unwinding too far"); -} + bool + StackTrace::isEntry(Addr addr) + { + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp12)) + return true; -bool -StackTrace::isEntry(Addr addr) -{ - if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp12)) - return true; + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp7)) + return true; - if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp7)) - return true; + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp11)) + return true; - if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp11)) - return true; + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp21)) + return true; - if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp21)) - return true; + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp9)) + return true; - if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp9)) - return true; - - if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp2)) - return true; + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp2)) + return true; - return false; -} - -bool -StackTrace::decodeStack(MachInst inst, int &disp) -{ - // lda $sp, -disp($sp) - // - // Opcode<31:26> == 0x08 - // RA<25:21> == 30 - // RB<20:16> == 30 - // Disp<15:0> - const MachInst mem_mask = 0xffff0000; - const MachInst lda_pattern = 0x23de0000; - const MachInst lda_disp_mask = 0x0000ffff; - - // subq $sp, disp, $sp - // addq $sp, disp, $sp - // - // Opcode<31:26> == 0x10 - // RA<25:21> == 30 - // Lit<20:13> - // One<12> = 1 - // Func<11:5> == 0x20 (addq) - // Func<11:5> == 0x29 (subq) - // RC<4:0> == 30 - const MachInst intop_mask = 0xffe01fff; - const MachInst addq_pattern = 0x43c0141e; - const MachInst subq_pattern = 0x43c0153e; - const MachInst intop_disp_mask = 0x001fe000; - const int intop_disp_shift = 13; - - if ((inst & mem_mask) == lda_pattern) - disp = -sext<16>(inst & lda_disp_mask); - else if ((inst & intop_mask) == addq_pattern) - disp = -int((inst & intop_disp_mask) >> intop_disp_shift); - else if ((inst & intop_mask) == subq_pattern) - disp = int((inst & intop_disp_mask) >> intop_disp_shift); - else return false; + } - return true; -} + bool + StackTrace::decodeStack(MachInst inst, int &disp) + { + // lda $sp, -disp($sp) + // + // Opcode<31:26> == 0x08 + // RA<25:21> == 30 + // RB<20:16> == 30 + // Disp<15:0> + const MachInst mem_mask = 0xffff0000; + const MachInst lda_pattern = 0x23de0000; + const MachInst lda_disp_mask = 0x0000ffff; + + // subq $sp, disp, $sp + // addq $sp, disp, $sp + // + // Opcode<31:26> == 0x10 + // RA<25:21> == 30 + // Lit<20:13> + // One<12> = 1 + // Func<11:5> == 0x20 (addq) + // Func<11:5> == 0x29 (subq) + // RC<4:0> == 30 + const MachInst intop_mask = 0xffe01fff; + const MachInst addq_pattern = 0x43c0141e; + const MachInst subq_pattern = 0x43c0153e; + const MachInst intop_disp_mask = 0x001fe000; + const int intop_disp_shift = 13; + + if ((inst & mem_mask) == lda_pattern) + disp = -sext<16>(inst & lda_disp_mask); + else if ((inst & intop_mask) == addq_pattern) + disp = -int((inst & intop_disp_mask) >> intop_disp_shift); + else if ((inst & intop_mask) == subq_pattern) + disp = int((inst & intop_disp_mask) >> intop_disp_shift); + else + return false; -bool -StackTrace::decodeSave(MachInst inst, int ®, int &disp) -{ - // lda $stq, disp($sp) - // - // Opcode<31:26> == 0x08 - // RA<25:21> == ? - // RB<20:16> == 30 - // Disp<15:0> - const MachInst stq_mask = 0xfc1f0000; - const MachInst stq_pattern = 0xb41e0000; - const MachInst stq_disp_mask = 0x0000ffff; - const MachInst reg_mask = 0x03e00000; - const int reg_shift = 21; - - if ((inst & stq_mask) == stq_pattern) { - reg = (inst & reg_mask) >> reg_shift; - disp = sext<16>(inst & stq_disp_mask); - } else { - return false; + return true; } - return true; -} + bool + StackTrace::decodeSave(MachInst inst, int ®, int &disp) + { + // lda $stq, disp($sp) + // + // Opcode<31:26> == 0x08 + // RA<25:21> == ? + // RB<20:16> == 30 + // Disp<15:0> + const MachInst stq_mask = 0xfc1f0000; + const MachInst stq_pattern = 0xb41e0000; + const MachInst stq_disp_mask = 0x0000ffff; + const MachInst reg_mask = 0x03e00000; + const int reg_shift = 21; + + if ((inst & stq_mask) == stq_pattern) { + reg = (inst & reg_mask) >> reg_shift; + disp = sext<16>(inst & stq_disp_mask); + } else { + return false; + } -/* - * Decode the function prologue for the function we're in, and note - * which registers are stored where, and how large the stack frame is. - */ -bool -StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, - int &size, Addr &ra) -{ - size = 0; - ra = 0; - - for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { - MachInst inst; - CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst)); - - int reg, disp; - if (decodeStack(inst, disp)) { - if (size) { - // panic("decoding frame size again"); - return true; - } - size += disp; - } else if (decodeSave(inst, reg, disp)) { - if (!ra && reg == ReturnAddressReg) { - CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr)); - if (!ra) { - // panic("no return address value pc=%#x\n", pc); - return false; + return true; + } + + /* + * Decode the function prologue for the function we're in, and note + * which registers are stored where, and how large the stack frame is. + */ + bool + StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, + int &size, Addr &ra) + { + size = 0; + ra = 0; + + for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { + MachInst inst; + CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst)); + + int reg, disp; + if (decodeStack(inst, disp)) { + if (size) { + // panic("decoding frame size again"); + return true; + } + size += disp; + } else if (decodeSave(inst, reg, disp)) { + if (!ra && reg == ReturnAddressReg) { + CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr)); + if (!ra) { + // panic("no return address value pc=%#x\n", pc); + return false; + } } } } - } - return true; -} + return true; + } #if TRACING_ON -void -StackTrace::dump() -{ - StringWrap name(tc->getCpuPtr()->name()); - SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; - - DPRINTFN("------ Stack ------\n"); - - string symbol; - for (int i = 0, size = stack.size(); i < size; ++i) { - Addr addr = stack[size - i - 1]; - if (addr == user) - symbol = "user"; - else if (addr == console) - symbol = "console"; - else if (addr == unknown) - symbol = "unknown"; - else - symtab->findSymbol(addr, symbol); - - DPRINTFN("%#x: %s\n", addr, symbol); + void + StackTrace::dump() + { + StringWrap name(tc->getCpuPtr()->name()); + SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; + + DPRINTFN("------ Stack ------\n"); + + string symbol; + for (int i = 0, size = stack.size(); i < size; ++i) { + Addr addr = stack[size - i - 1]; + if (addr == user) + symbol = "user"; + else if (addr == console) + symbol = "console"; + else if (addr == unknown) + symbol = "unknown"; + else + symtab->findSymbol(addr, symbol); + + DPRINTFN("%#x: %s\n", addr, symbol); + } } -} #endif +} diff --git a/src/arch/alpha/stacktrace.hh b/src/arch/alpha/stacktrace.hh index d12aee211..834abbc2f 100644 --- a/src/arch/alpha/stacktrace.hh +++ b/src/arch/alpha/stacktrace.hh @@ -35,87 +35,91 @@ #include "cpu/static_inst.hh" class ThreadContext; -class StackTrace; -class ProcessInfo +namespace AlphaISA { - private: - ThreadContext *tc; + class StackTrace; - int thread_info_size; - int task_struct_size; - int task_off; - int pid_off; - int name_off; + class ProcessInfo + { + private: + ThreadContext *tc; - public: - ProcessInfo(ThreadContext *_tc); + int thread_info_size; + int task_struct_size; + int task_off; + int pid_off; + int name_off; - Addr task(Addr ksp) const; - int pid(Addr ksp) const; - std::string name(Addr ksp) const; -}; + public: + ProcessInfo(ThreadContext *_tc); -class StackTrace -{ - protected: - typedef TheISA::MachInst MachInst; - private: - ThreadContext *tc; - std::vector stack; - - private: - bool isEntry(Addr addr); - bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); - bool decodeSave(MachInst inst, int ®, int &disp); - bool decodeStack(MachInst inst, int &disp); - - void trace(ThreadContext *tc, bool is_call); - - public: - StackTrace(); - StackTrace(ThreadContext *tc, StaticInstPtr inst); - ~StackTrace(); - - void clear() + Addr task(Addr ksp) const; + int pid(Addr ksp) const; + std::string name(Addr ksp) const; + }; + + class StackTrace { - tc = 0; - stack.clear(); - } + protected: + typedef TheISA::MachInst MachInst; + private: + ThreadContext *tc; + std::vector stack; + + private: + bool isEntry(Addr addr); + bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); + bool decodeSave(MachInst inst, int ®, int &disp); + bool decodeStack(MachInst inst, int &disp); + + void trace(ThreadContext *tc, bool is_call); - bool valid() const { return tc != NULL; } - bool trace(ThreadContext *tc, StaticInstPtr inst); + public: + StackTrace(); + StackTrace(ThreadContext *tc, StaticInstPtr inst); + ~StackTrace(); - public: - const std::vector &getstack() const { return stack; } + void clear() + { + tc = 0; + stack.clear(); + } - static const int user = 1; - static const int console = 2; - static const int unknown = 3; + bool valid() const { return tc != NULL; } + bool trace(ThreadContext *tc, StaticInstPtr inst); + + public: + const std::vector &getstack() const { return stack; } + + static const int user = 1; + static const int console = 2; + static const int unknown = 3; #if TRACING_ON - private: - void dump(); + private: + void dump(); - public: - void dprintf() { if (DTRACE(Stack)) dump(); } + public: + void dprintf() { if (DTRACE(Stack)) dump(); } #else - public: - void dprintf() {} + public: + void dprintf() {} #endif -}; + }; -inline bool -StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) -{ - if (!inst->isCall() && !inst->isReturn()) - return false; + inline bool + StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) + { + if (!inst->isCall() && !inst->isReturn()) + return false; - if (valid()) - clear(); + if (valid()) + clear(); - trace(tc, !inst->isReturn()); - return true; + trace(tc, !inst->isReturn()); + return true; + } } #endif // __ARCH_ALPHA_STACKTRACE_HH__ diff --git a/src/arch/sparc/stacktrace.cc b/src/arch/sparc/stacktrace.cc index 0985eb149..2eb697bf2 100644 --- a/src/arch/sparc/stacktrace.cc +++ b/src/arch/sparc/stacktrace.cc @@ -40,332 +40,333 @@ #include "sim/system.hh" using namespace std; -using namespace SparcISA; - -ProcessInfo::ProcessInfo(ThreadContext *_tc) - : tc(_tc) +namespace SparcISA { - Addr addr = 0; + ProcessInfo::ProcessInfo(ThreadContext *_tc) + : tc(_tc) + { + Addr addr = 0; - VirtualPort *vp; + VirtualPort *vp; - vp = tc->getVirtPort(); + vp = tc->getVirtPort(); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) - panic("thread info not compiled into kernel\n"); - thread_info_size = vp->readGtoH(addr); + if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) + panic("thread info not compiled into kernel\n"); + thread_info_size = vp->readGtoH(addr); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) - panic("thread info not compiled into kernel\n"); - task_struct_size = vp->readGtoH(addr); + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) + panic("thread info not compiled into kernel\n"); + task_struct_size = vp->readGtoH(addr); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) - panic("thread info not compiled into kernel\n"); - task_off = vp->readGtoH(addr); + if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) + panic("thread info not compiled into kernel\n"); + task_off = vp->readGtoH(addr); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) - panic("thread info not compiled into kernel\n"); - pid_off = vp->readGtoH(addr); + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) + panic("thread info not compiled into kernel\n"); + pid_off = vp->readGtoH(addr); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) - panic("thread info not compiled into kernel\n"); - name_off = vp->readGtoH(addr); + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) + panic("thread info not compiled into kernel\n"); + name_off = vp->readGtoH(addr); - tc->delVirtPort(vp); -} + tc->delVirtPort(vp); + } -Addr -ProcessInfo::task(Addr ksp) const -{ - Addr base = ksp & ~0x3fff; - if (base == ULL(0xfffffc0000000000)) - return 0; + Addr + ProcessInfo::task(Addr ksp) const + { + Addr base = ksp & ~0x3fff; + if (base == ULL(0xfffffc0000000000)) + return 0; - Addr tsk; + Addr tsk; - VirtualPort *vp; + VirtualPort *vp; - vp = tc->getVirtPort(); - tsk = vp->readGtoH(base + task_off); - tc->delVirtPort(vp); + vp = tc->getVirtPort(); + tsk = vp->readGtoH(base + task_off); + tc->delVirtPort(vp); - return tsk; -} + return tsk; + } -int -ProcessInfo::pid(Addr ksp) const -{ - Addr task = this->task(ksp); - if (!task) - return -1; + int + ProcessInfo::pid(Addr ksp) const + { + Addr task = this->task(ksp); + if (!task) + return -1; - uint16_t pd; + uint16_t pd; - VirtualPort *vp; + VirtualPort *vp; - vp = tc->getVirtPort(); - pd = vp->readGtoH(task + pid_off); - tc->delVirtPort(vp); + vp = tc->getVirtPort(); + pd = vp->readGtoH(task + pid_off); + tc->delVirtPort(vp); - return pd; -} + return pd; + } -string -ProcessInfo::name(Addr ksp) const -{ - Addr task = this->task(ksp); - if (!task) - return "console"; + string + ProcessInfo::name(Addr ksp) const + { + Addr task = this->task(ksp); + if (!task) + return "console"; - char comm[256]; - CopyStringOut(tc, comm, task + name_off, sizeof(comm)); - if (!comm[0]) - return "startup"; + char comm[256]; + CopyStringOut(tc, comm, task + name_off, sizeof(comm)); + if (!comm[0]) + return "startup"; - return comm; -} + return comm; + } -StackTrace::StackTrace() - : tc(0), stack(64) -{ -} + StackTrace::StackTrace() + : tc(0), stack(64) + { + } -StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) - : tc(0), stack(64) -{ - trace(_tc, inst); -} + StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) + : tc(0), stack(64) + { + trace(_tc, inst); + } -StackTrace::~StackTrace() -{ -} + StackTrace::~StackTrace() + { + } -void -StackTrace::trace(ThreadContext *_tc, bool is_call) -{ + void + StackTrace::trace(ThreadContext *_tc, bool is_call) + { #if 0 - tc = _tc; + tc = _tc; - bool usermode = (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; + bool usermode = (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; - Addr pc = tc->readNextPC(); - bool kernel = tc->getSystemPtr()->kernelStart <= pc && - pc <= tc->getSystemPtr()->kernelEnd; + Addr pc = tc->readNextPC(); + bool kernel = tc->getSystemPtr()->kernelStart <= pc && + pc <= tc->getSystemPtr()->kernelEnd; - if (usermode) { - stack.push_back(user); - return; - } + if (usermode) { + stack.push_back(user); + return; + } - if (!kernel) { - stack.push_back(console); - return; - } + if (!kernel) { + stack.push_back(console); + return; + } - SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; - Addr ksp = tc->readIntReg(TheISA::StackPointerReg); - Addr bottom = ksp & ~0x3fff; - Addr addr; + SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; + Addr ksp = tc->readIntReg(TheISA::StackPointerReg); + Addr bottom = ksp & ~0x3fff; + Addr addr; - if (is_call) { - if (!symtab->findNearestAddr(pc, addr)) - panic("could not find address %#x", pc); + if (is_call) { + if (!symtab->findNearestAddr(pc, addr)) + panic("could not find address %#x", pc); - stack.push_back(addr); - pc = tc->readPC(); - } + stack.push_back(addr); + pc = tc->readPC(); + } - Addr ra; - int size; + Addr ra; + int size; - while (ksp > bottom) { - if (!symtab->findNearestAddr(pc, addr)) - panic("could not find symbol for pc=%#x", pc); - assert(pc >= addr && "symbol botch: callpc < func"); + while (ksp > bottom) { + if (!symtab->findNearestAddr(pc, addr)) + panic("could not find symbol for pc=%#x", pc); + assert(pc >= addr && "symbol botch: callpc < func"); - stack.push_back(addr); + stack.push_back(addr); - if (isEntry(addr)) - return; - - if (decodePrologue(ksp, pc, addr, size, ra)) { - if (!ra) + if (isEntry(addr)) return; - if (size <= 0) { + if (decodePrologue(ksp, pc, addr, size, ra)) { + if (!ra) + return; + + if (size <= 0) { + stack.push_back(unknown); + return; + } + + pc = ra; + ksp += size; + } else { stack.push_back(unknown); return; } - pc = ra; - ksp += size; - } else { - stack.push_back(unknown); - return; - } - - bool kernel = tc->getSystemPtr()->kernelStart <= pc && - pc <= tc->getSystemPtr()->kernelEnd; - if (!kernel) - return; + bool kernel = tc->getSystemPtr()->kernelStart <= pc && + pc <= tc->getSystemPtr()->kernelEnd; + if (!kernel) + return; - if (stack.size() >= 1000) - panic("unwinding too far"); - } + if (stack.size() >= 1000) + panic("unwinding too far"); + } - panic("unwinding too far"); + panic("unwinding too far"); #endif -} + } -bool -StackTrace::isEntry(Addr addr) -{ + bool + StackTrace::isEntry(Addr addr) + { #if 0 - if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp12)) - return true; + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp12)) + return true; - if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp7)) - return true; + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp7)) + return true; - if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp11)) - return true; + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp11)) + return true; - if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp21)) - return true; + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp21)) + return true; - if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp9)) - return true; + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp9)) + return true; - if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp2)) - return true; + if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp2)) + return true; #endif - return false; -} - -bool -StackTrace::decodeStack(MachInst inst, int &disp) -{ - // lda $sp, -disp($sp) - // - // Opcode<31:26> == 0x08 - // RA<25:21> == 30 - // RB<20:16> == 30 - // Disp<15:0> - const MachInst mem_mask = 0xffff0000; - const MachInst lda_pattern = 0x23de0000; - const MachInst lda_disp_mask = 0x0000ffff; - - // subq $sp, disp, $sp - // addq $sp, disp, $sp - // - // Opcode<31:26> == 0x10 - // RA<25:21> == 30 - // Lit<20:13> - // One<12> = 1 - // Func<11:5> == 0x20 (addq) - // Func<11:5> == 0x29 (subq) - // RC<4:0> == 30 - const MachInst intop_mask = 0xffe01fff; - const MachInst addq_pattern = 0x43c0141e; - const MachInst subq_pattern = 0x43c0153e; - const MachInst intop_disp_mask = 0x001fe000; - const int intop_disp_shift = 13; - - if ((inst & mem_mask) == lda_pattern) - disp = -sext<16>(inst & lda_disp_mask); - else if ((inst & intop_mask) == addq_pattern) - disp = -int((inst & intop_disp_mask) >> intop_disp_shift); - else if ((inst & intop_mask) == subq_pattern) - disp = int((inst & intop_disp_mask) >> intop_disp_shift); - else return false; + } - return true; -} + bool + StackTrace::decodeStack(MachInst inst, int &disp) + { + // lda $sp, -disp($sp) + // + // Opcode<31:26> == 0x08 + // RA<25:21> == 30 + // RB<20:16> == 30 + // Disp<15:0> + const MachInst mem_mask = 0xffff0000; + const MachInst lda_pattern = 0x23de0000; + const MachInst lda_disp_mask = 0x0000ffff; + + // subq $sp, disp, $sp + // addq $sp, disp, $sp + // + // Opcode<31:26> == 0x10 + // RA<25:21> == 30 + // Lit<20:13> + // One<12> = 1 + // Func<11:5> == 0x20 (addq) + // Func<11:5> == 0x29 (subq) + // RC<4:0> == 30 + const MachInst intop_mask = 0xffe01fff; + const MachInst addq_pattern = 0x43c0141e; + const MachInst subq_pattern = 0x43c0153e; + const MachInst intop_disp_mask = 0x001fe000; + const int intop_disp_shift = 13; + + if ((inst & mem_mask) == lda_pattern) + disp = -sext<16>(inst & lda_disp_mask); + else if ((inst & intop_mask) == addq_pattern) + disp = -int((inst & intop_disp_mask) >> intop_disp_shift); + else if ((inst & intop_mask) == subq_pattern) + disp = int((inst & intop_disp_mask) >> intop_disp_shift); + else + return false; -bool -StackTrace::decodeSave(MachInst inst, int ®, int &disp) -{ - // lda $stq, disp($sp) - // - // Opcode<31:26> == 0x08 - // RA<25:21> == ? - // RB<20:16> == 30 - // Disp<15:0> - const MachInst stq_mask = 0xfc1f0000; - const MachInst stq_pattern = 0xb41e0000; - const MachInst stq_disp_mask = 0x0000ffff; - const MachInst reg_mask = 0x03e00000; - const int reg_shift = 21; - - if ((inst & stq_mask) == stq_pattern) { - reg = (inst & reg_mask) >> reg_shift; - disp = sext<16>(inst & stq_disp_mask); - } else { - return false; + return true; } - return true; -} + bool + StackTrace::decodeSave(MachInst inst, int ®, int &disp) + { + // lda $stq, disp($sp) + // + // Opcode<31:26> == 0x08 + // RA<25:21> == ? + // RB<20:16> == 30 + // Disp<15:0> + const MachInst stq_mask = 0xfc1f0000; + const MachInst stq_pattern = 0xb41e0000; + const MachInst stq_disp_mask = 0x0000ffff; + const MachInst reg_mask = 0x03e00000; + const int reg_shift = 21; + + if ((inst & stq_mask) == stq_pattern) { + reg = (inst & reg_mask) >> reg_shift; + disp = sext<16>(inst & stq_disp_mask); + } else { + return false; + } -/* - * Decode the function prologue for the function we're in, and note - * which registers are stored where, and how large the stack frame is. - */ -bool -StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, - int &size, Addr &ra) -{ - size = 0; - ra = 0; - - for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { - MachInst inst; - CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst)); - - int reg, disp; - if (decodeStack(inst, disp)) { - if (size) { - // panic("decoding frame size again"); - return true; - } - size += disp; - } else if (decodeSave(inst, reg, disp)) { - if (!ra && reg == ReturnAddressReg) { - CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr)); - if (!ra) { - // panic("no return address value pc=%#x\n", pc); - return false; + return true; + } + + /* + * Decode the function prologue for the function we're in, and note + * which registers are stored where, and how large the stack frame is. + */ + bool + StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, + int &size, Addr &ra) + { + size = 0; + ra = 0; + + for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { + MachInst inst; + CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst)); + + int reg, disp; + if (decodeStack(inst, disp)) { + if (size) { + // panic("decoding frame size again"); + return true; + } + size += disp; + } else if (decodeSave(inst, reg, disp)) { + if (!ra && reg == ReturnAddressReg) { + CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr)); + if (!ra) { + // panic("no return address value pc=%#x\n", pc); + return false; + } } } } - } - return true; -} + return true; + } #if TRACING_ON -void -StackTrace::dump() -{ - StringWrap name(tc->getCpuPtr()->name()); - SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; - - DPRINTFN("------ Stack ------\n"); - - string symbol; - for (int i = 0, size = stack.size(); i < size; ++i) { - Addr addr = stack[size - i - 1]; - if (addr == user) - symbol = "user"; - else if (addr == console) - symbol = "console"; - else if (addr == unknown) - symbol = "unknown"; - else - symtab->findSymbol(addr, symbol); - - DPRINTFN("%#x: %s\n", addr, symbol); + void + StackTrace::dump() + { + StringWrap name(tc->getCpuPtr()->name()); + SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; + + DPRINTFN("------ Stack ------\n"); + + string symbol; + for (int i = 0, size = stack.size(); i < size; ++i) { + Addr addr = stack[size - i - 1]; + if (addr == user) + symbol = "user"; + else if (addr == console) + symbol = "console"; + else if (addr == unknown) + symbol = "unknown"; + else + symtab->findSymbol(addr, symbol); + + DPRINTFN("%#x: %s\n", addr, symbol); + } } -} #endif +} diff --git a/src/arch/sparc/stacktrace.hh b/src/arch/sparc/stacktrace.hh index 54d3d17be..4bc5d779b 100644 --- a/src/arch/sparc/stacktrace.hh +++ b/src/arch/sparc/stacktrace.hh @@ -35,87 +35,90 @@ #include "cpu/static_inst.hh" class ThreadContext; -class StackTrace; - -class ProcessInfo +namespace SparcISA { - private: - ThreadContext *tc; + class StackTrace; - int thread_info_size; - int task_struct_size; - int task_off; - int pid_off; - int name_off; + class ProcessInfo + { + private: + ThreadContext *tc; - public: - ProcessInfo(ThreadContext *_tc); + int thread_info_size; + int task_struct_size; + int task_off; + int pid_off; + int name_off; - Addr task(Addr ksp) const; - int pid(Addr ksp) const; - std::string name(Addr ksp) const; -}; + public: + ProcessInfo(ThreadContext *_tc); -class StackTrace -{ - protected: - typedef TheISA::MachInst MachInst; - private: - ThreadContext *tc; - std::vector stack; - - private: - bool isEntry(Addr addr); - bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); - bool decodeSave(MachInst inst, int ®, int &disp); - bool decodeStack(MachInst inst, int &disp); - - void trace(ThreadContext *tc, bool is_call); - - public: - StackTrace(); - StackTrace(ThreadContext *tc, StaticInstPtr inst); - ~StackTrace(); - - void clear() + Addr task(Addr ksp) const; + int pid(Addr ksp) const; + std::string name(Addr ksp) const; + }; + + class StackTrace { - tc = 0; - stack.clear(); - } + protected: + typedef TheISA::MachInst MachInst; + private: + ThreadContext *tc; + std::vector stack; + + private: + bool isEntry(Addr addr); + bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); + bool decodeSave(MachInst inst, int ®, int &disp); + bool decodeStack(MachInst inst, int &disp); - bool valid() const { return tc != NULL; } - bool trace(ThreadContext *tc, StaticInstPtr inst); + void trace(ThreadContext *tc, bool is_call); - public: - const std::vector &getstack() const { return stack; } + public: + StackTrace(); + StackTrace(ThreadContext *tc, StaticInstPtr inst); + ~StackTrace(); - static const int user = 1; - static const int console = 2; - static const int unknown = 3; + void clear() + { + tc = 0; + stack.clear(); + } + + bool valid() const { return tc != NULL; } + bool trace(ThreadContext *tc, StaticInstPtr inst); + + public: + const std::vector &getstack() const { return stack; } + + static const int user = 1; + static const int console = 2; + static const int unknown = 3; #if TRACING_ON - private: - void dump(); + private: + void dump(); - public: - void dprintf() { if (DTRACE(Stack)) dump(); } + public: + void dprintf() { if (DTRACE(Stack)) dump(); } #else - public: - void dprintf() {} + public: + void dprintf() {} #endif -}; + }; -inline bool -StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) -{ - if (!inst->isCall() && !inst->isReturn()) - return false; + inline bool + StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) + { + if (!inst->isCall() && !inst->isReturn()) + return false; - if (valid()) - clear(); + if (valid()) + clear(); - trace(tc, !inst->isReturn()); - return true; + trace(tc, !inst->isReturn()); + return true; + } } #endif // __ARCH_SPARC_STACKTRACE_HH__ diff --git a/src/cpu/profile.hh b/src/cpu/profile.hh index 7f9625241..27bb4efec 100644 --- a/src/cpu/profile.hh +++ b/src/cpu/profile.hh @@ -33,9 +33,9 @@ #include +#include "arch/stacktrace.hh" #include "cpu/static_inst.hh" #include "sim/host.hh" -#include "arch/stacktrace.hh" class ThreadContext; @@ -66,7 +66,7 @@ class FunctionProfile const SymbolTable *symtab; ProfileNode top; std::map pc_count; - StackTrace trace; + TheISA::StackTrace trace; public: FunctionProfile(const SymbolTable *symtab); diff --git a/src/mem/port_impl.hh b/src/mem/port_impl.hh index b7980bdd2..989cfd338 100644 --- a/src/mem/port_impl.hh +++ b/src/mem/port_impl.hh @@ -28,6 +28,9 @@ * Authors: Ali Saidi */ +//To get endianness +#include "arch/isa_traits.hh" + #include "mem/port.hh" #include "sim/byteswap.hh" @@ -35,7 +38,7 @@ template void FunctionalPort::writeHtoG(Addr addr, T d) { - d = htog(d); + d = TheISA::htog(d); writeBlob(addr, (uint8_t*)&d, sizeof(T)); } @@ -46,6 +49,6 @@ FunctionalPort::readGtoH(Addr addr) { T d; readBlob(addr, (uint8_t*)&d, sizeof(T)); - return gtoh(d); + return TheISA::gtoh(d); } -- cgit v1.2.3 From 8cb7ac090059db62f869f726ffef6f93c0e49beb Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 02:13:47 -0500 Subject: Changed the getReg and setReg functions so that they work like netbsd. Apparently, gdb expects to do single stepping on its own, so those functions panic for SPARC. acc still needs to be implemented. --HG-- extra : convert_revision : c6e98e37b8ab3d6f8d6b3cd2c961faa65b08a179 --- src/arch/sparc/remote_gdb.cc | 97 +++++--------------------------------------- src/arch/sparc/remote_gdb.hh | 27 ++++-------- 2 files changed, 20 insertions(+), 104 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc index 5f9c532b8..c76f8b820 100644 --- a/src/arch/sparc/remote_gdb.cc +++ b/src/arch/sparc/remote_gdb.cc @@ -149,46 +149,9 @@ RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) bool RemoteGDB::acc(Addr va, size_t len) { -#if 0 - Addr last_va; - - va = TheISA::TruncPage(va); - last_va = TheISA::RoundPage(va + len); - - do { - if (TheISA::IsK0Seg(va)) { - if (va < (TheISA::K0SegBase + pmem->size())) { - DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= " - "%#x < K0SEG + size\n", va); - return true; - } else { - DPRINTF(GDBAcc, "acc: Mapping invalid %#x > K0SEG + size\n", - va); - return false; - } - } - - /** - * This code says that all accesses to palcode (instruction and data) - * are valid since there isn't a va->pa mapping because palcode is - * accessed physically. At some point this should probably be cleaned up - * but there is no easy way to do it. - */ - - if (AlphaISA::PcPAL(va) || va < 0x10000) - return true; - - Addr ptbr = context->readMiscReg(AlphaISA::IPR_PALtemp20); - TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va); - if (!pte.valid()) { - DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); - return false; - } - va += TheISA::PageBytes; - } while (va < last_va); - - DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va); -#endif + //@Todo In NetBSD, this function checks if all addresses + //from va to va + len have valid page mape entries. Not + //sure how this will work for other OSes or in general. return true; } @@ -204,12 +167,11 @@ RemoteGDB::getregs() gdbregs.regs[RegPc] = context->readPC(); gdbregs.regs[RegNpc] = context->readNextPC(); - for(int x = RegG0; x <= RegI7; x++) + for(int x = RegG0; x <= RegI0 + 7; x++) gdbregs.regs[x] = context->readIntReg(x - RegG0); - for(int x = RegF0; x <= RegF31; x++) - gdbregs.regs[x] = context->readFloatRegBits(x - RegF0); - gdbregs.regs[RegY] = context->readMiscReg(MISCREG_Y); - //XXX need to also load up Psr, Wim, Tbr, Fpsr, and Cpsr + //Floating point registers are left at 0 in netbsd + //All registers other than the pc, npc and int regs + //are ignored as well. } /////////////////////////////////////////////////////////// @@ -223,56 +185,19 @@ RemoteGDB::setregs() { context->setPC(gdbregs.regs[RegPc]); context->setNextPC(gdbregs.regs[RegNpc]); - for(int x = RegG0; x <= RegI7; x++) + for(int x = RegG0; x <= RegI0 + 7; x++) context->setIntReg(x - RegG0, gdbregs.regs[x]); - for(int x = RegF0; x <= RegF31; x++) - context->setFloatRegBits(x - RegF0, gdbregs.regs[x]); - context->setMiscRegWithEffect(MISCREG_Y, gdbregs.regs[RegY]); - //XXX need to also set Psr, Wim, Tbr, Fpsr, and Cpsr + //Only the integer registers, pc and npc are set in netbsd } void RemoteGDB::clearSingleStep() { -#if 0 - DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n", - takenBkpt.address, notTakenBkpt.address); - - if (takenBkpt.address != 0) - clearTempBreakpoint(takenBkpt); - - if (notTakenBkpt.address != 0) - clearTempBreakpoint(notTakenBkpt); -#endif + panic("SPARC does not support hardware single stepping\n"); } void RemoteGDB::setSingleStep() { -#if 0 - Addr pc = context->readPC(); - Addr npc, bpc; - bool set_bt = false; - - npc = pc + sizeof(MachInst); - - // User was stopped at pc, e.g. the instruction at pc was not - // executed. - MachInst inst = read(pc); - StaticInstPtr si(inst); - if (si->hasBranchTarget(pc, context, bpc)) { - // Don't bother setting a breakpoint on the taken branch if it - // is the same as the next pc - if (bpc != npc) - set_bt = true; - } - - DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n", - takenBkpt.address, notTakenBkpt.address); - - setTempBreakpoint(notTakenBkpt, npc); - - if (set_bt) - setTempBreakpoint(takenBkpt, bpc); -#endif + panic("SPARC does not support hardware single stepping\n"); } diff --git a/src/arch/sparc/remote_gdb.hh b/src/arch/sparc/remote_gdb.hh index 3ded1e218..e4b66b783 100644 --- a/src/arch/sparc/remote_gdb.hh +++ b/src/arch/sparc/remote_gdb.hh @@ -49,22 +49,15 @@ namespace SparcISA protected: enum RegisterConstants { - RegG0, RegG1, RegG2, RegG3, RegG4, RegG5, RegG6, RegG7, - RegO0, RegO1, RegO2, RegO3, RegO4, RegO5, RegO6, RegO7, - RegL0, RegL1, RegL2, RegL3, RegL4, RegL5, RegL6, RegL7, - RegI0, RegI1, RegI2, RegI3, RegI4, RegI5, RegI6, RegI7, - RegF0, RegF1, RegF2, RegF3, RegF4, RegF5, RegF6, RegF7, - RegF8, RegF9, RegF10, RegF11, RegF12, RegF13, RegF14, RegF15, - RegF16, RegF17, RegF18, RegF19, RegF20, RegF21, RegF22, RegF23, - RegF24, RegF25, RegF26, RegF27, RegF28, RegF29, RegF30, RegF31, - RegY, - RegPsr, - RegWim, - RegTbr, - RegPc, - RegNpc, - RegFpsr, - RegCpsr, + RegG0 = 0, RegO0 = 8, RegL0 = 16, RegI0 = 24, + RegF0 = 32, RegF32 = 64, + RegPc = 80, RegNpc, RegCcr, RegFsr, RegFprs, RegY, RegAsi, + RegVer, RegTick, RegPil, RegPstate, + RegTstate, RegTba, RegTl, RegTt, RegTpc, RegTnpc, RegWstate, + RegCwp, RegCansave, RegCanrestore, RegCleanwin, RegOtherwin, + RegAsr16 = 103, + RegIcc = 119, RegXcc, + RegFcc0 = 121, NumGDBRegs }; @@ -79,8 +72,6 @@ namespace SparcISA void clearSingleStep(); void setSingleStep(); - - Addr singleStepBreaks[2]; }; } -- cgit v1.2.3 From f0c4d3664930f28229c7e336c4d4372b2e1d4c21 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 04:18:15 -0500 Subject: The new global level is computed with min, not max. --HG-- extra : convert_revision : 6339c82d3655694445c3eb43e467b9aa6b4c8224 --- src/arch/sparc/faults.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index da7fc730d..1a44d34cf 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -291,9 +291,9 @@ void doNormalFault(ThreadContext *tc, TrapType tt) //Update the global register level if(1/*We're delivering the trap in priveleged mode*/) - tc->setMiscReg(MISCREG_GL, max(GL+1, MaxGL)); + tc->setMiscReg(MISCREG_GL, min(GL+1, MaxGL)); else - tc->setMiscReg(MISCREG_GL, max(GL+1, MaxPGL)); + tc->setMiscReg(MISCREG_GL, min(GL+1, MaxPGL)); //PSTATE.mm is unchanged //PSTATE.pef = whether or not an fpu is present -- cgit v1.2.3 From 635df9ba1753915002d10611308cba98527929d3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 08:12:19 -0500 Subject: Major clean up of the fault code. --HG-- extra : convert_revision : eb7e016a127417cbb0e1e2c733b17f82469c2f24 --- src/arch/sparc/faults.cc | 281 +++++++++--------------- src/arch/sparc/faults.hh | 539 +++++++---------------------------------------- 2 files changed, 180 insertions(+), 640 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 2c8da44c5..169ad7986 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -48,192 +48,119 @@ using namespace std; namespace SparcISA { -FaultName InternalProcessorError::_name = "intprocerr"; -TrapType InternalProcessorError::_trapType = 0x029; -FaultPriority InternalProcessorError::_priority = 4; -FaultStat InternalProcessorError::_count; - -FaultName MemAddressNotAligned::_name = "unalign"; -TrapType MemAddressNotAligned::_trapType = 0x034; -FaultPriority MemAddressNotAligned::_priority = 10; -FaultStat MemAddressNotAligned::_count; - -FaultName PowerOnReset::_name = "pow_reset"; -TrapType PowerOnReset::_trapType = 0x001; -FaultPriority PowerOnReset::_priority = 0; -FaultStat PowerOnReset::_count; - -FaultName WatchDogReset::_name = "watch_dog_reset"; -TrapType WatchDogReset::_trapType = 0x002; -FaultPriority WatchDogReset::_priority = 1; -FaultStat WatchDogReset::_count; - -FaultName ExternallyInitiatedReset::_name = "extern_reset"; -TrapType ExternallyInitiatedReset::_trapType = 0x003; -FaultPriority ExternallyInitiatedReset::_priority = 1; -FaultStat ExternallyInitiatedReset::_count; - -FaultName SoftwareInitiatedReset::_name = "software_reset"; -TrapType SoftwareInitiatedReset::_trapType = 0x004; -FaultPriority SoftwareInitiatedReset::_priority = 1; -FaultStat SoftwareInitiatedReset::_count; - -FaultName REDStateException::_name = "red_counte"; -TrapType REDStateException::_trapType = 0x005; -FaultPriority REDStateException::_priority = 1; -FaultStat REDStateException::_count; - -FaultName InstructionAccessException::_name = "inst_access"; -TrapType InstructionAccessException::_trapType = 0x008; -FaultPriority InstructionAccessException::_priority = 5; -FaultStat InstructionAccessException::_count; - -FaultName InstructionAccessMMUMiss::_name = "inst_mmu"; -TrapType InstructionAccessMMUMiss::_trapType = 0x009; -FaultPriority InstructionAccessMMUMiss::_priority = 2; -FaultStat InstructionAccessMMUMiss::_count; - -FaultName InstructionAccessError::_name = "inst_error"; -TrapType InstructionAccessError::_trapType = 0x00A; -FaultPriority InstructionAccessError::_priority = 3; -FaultStat InstructionAccessError::_count; - -FaultName IllegalInstruction::_name = "illegal_inst"; -TrapType IllegalInstruction::_trapType = 0x010; -FaultPriority IllegalInstruction::_priority = 7; -FaultStat IllegalInstruction::_count; - -FaultName PrivilegedOpcode::_name = "priv_opcode"; -TrapType PrivilegedOpcode::_trapType = 0x011; -FaultPriority PrivilegedOpcode::_priority = 6; -FaultStat PrivilegedOpcode::_count; - -FaultName UnimplementedLDD::_name = "unimp_ldd"; -TrapType UnimplementedLDD::_trapType = 0x012; -FaultPriority UnimplementedLDD::_priority = 6; -FaultStat UnimplementedLDD::_count; - -FaultName UnimplementedSTD::_name = "unimp_std"; -TrapType UnimplementedSTD::_trapType = 0x013; -FaultPriority UnimplementedSTD::_priority = 6; -FaultStat UnimplementedSTD::_count; - -FaultName FpDisabled::_name = "fp_disabled"; -TrapType FpDisabled::_trapType = 0x020; -FaultPriority FpDisabled::_priority = 8; -FaultStat FpDisabled::_count; - -FaultName FpExceptionIEEE754::_name = "fp_754"; -TrapType FpExceptionIEEE754::_trapType = 0x021; -FaultPriority FpExceptionIEEE754::_priority = 11; -FaultStat FpExceptionIEEE754::_count; - -FaultName FpExceptionOther::_name = "fp_other"; -TrapType FpExceptionOther::_trapType = 0x022; -FaultPriority FpExceptionOther::_priority = 11; -FaultStat FpExceptionOther::_count; - -FaultName TagOverflow::_name = "tag_overflow"; -TrapType TagOverflow::_trapType = 0x023; -FaultPriority TagOverflow::_priority = 14; -FaultStat TagOverflow::_count; - -FaultName DivisionByZero::_name = "div_by_zero"; -TrapType DivisionByZero::_trapType = 0x028; -FaultPriority DivisionByZero::_priority = 15; -FaultStat DivisionByZero::_count; - -FaultName DataAccessException::_name = "data_access"; -TrapType DataAccessException::_trapType = 0x030; -FaultPriority DataAccessException::_priority = 12; -FaultStat DataAccessException::_count; - -FaultName DataAccessMMUMiss::_name = "data_mmu"; -TrapType DataAccessMMUMiss::_trapType = 0x031; -FaultPriority DataAccessMMUMiss::_priority = 12; -FaultStat DataAccessMMUMiss::_count; - -FaultName DataAccessError::_name = "data_error"; -TrapType DataAccessError::_trapType = 0x032; -FaultPriority DataAccessError::_priority = 12; -FaultStat DataAccessError::_count; - -FaultName DataAccessProtection::_name = "data_protection"; -TrapType DataAccessProtection::_trapType = 0x033; -FaultPriority DataAccessProtection::_priority = 12; -FaultStat DataAccessProtection::_count; - -FaultName LDDFMemAddressNotAligned::_name = "unalign_lddf"; -TrapType LDDFMemAddressNotAligned::_trapType = 0x035; -FaultPriority LDDFMemAddressNotAligned::_priority = 10; -FaultStat LDDFMemAddressNotAligned::_count; - -FaultName STDFMemAddressNotAligned::_name = "unalign_stdf"; -TrapType STDFMemAddressNotAligned::_trapType = 0x036; -FaultPriority STDFMemAddressNotAligned::_priority = 10; -FaultStat STDFMemAddressNotAligned::_count; - -FaultName PrivilegedAction::_name = "priv_action"; -TrapType PrivilegedAction::_trapType = 0x037; -FaultPriority PrivilegedAction::_priority = 11; -FaultStat PrivilegedAction::_count; - -FaultName LDQFMemAddressNotAligned::_name = "unalign_ldqf"; -TrapType LDQFMemAddressNotAligned::_trapType = 0x038; -FaultPriority LDQFMemAddressNotAligned::_priority = 10; -FaultStat LDQFMemAddressNotAligned::_count; - -FaultName STQFMemAddressNotAligned::_name = "unalign_stqf"; -TrapType STQFMemAddressNotAligned::_trapType = 0x039; -FaultPriority STQFMemAddressNotAligned::_priority = 10; -FaultStat STQFMemAddressNotAligned::_count; - -FaultName AsyncDataError::_name = "async_data"; -TrapType AsyncDataError::_trapType = 0x040; -FaultPriority AsyncDataError::_priority = 2; -FaultStat AsyncDataError::_count; - -FaultName CleanWindow::_name = "clean_win"; -TrapType CleanWindow::_trapType = 0x024; -FaultPriority CleanWindow::_priority = 10; -FaultStat CleanWindow::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"intprocerr", 0x029, 4}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"unalign", 0x034, 10}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"pow_reset", 0x001, 0}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"watch_dog_reset", 0x002, 1}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"extern_reset", 0x003, 1}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"software_reset", 0x004, 1}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"red_counte", 0x005, 1}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"inst_access", 0x008, 5}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"inst_mmu", 0x009, 2}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"inst_error", 0x00A, 3}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"illegal_inst", 0x010, 7}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"priv_opcode", 0x011, 6}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"unimp_ldd", 0x012, 6}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"unimp_std", 0x013, 6}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"fp_disabled", 0x020, 8}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"fp_754", 0x021, 11}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"fp_other", 0x022, 11}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"tag_overflow", 0x023, 14}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"div_by_zero", 0x028, 15}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"data_access", 0x030, 12}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"data_mmu", 0x031, 12}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"data_error", 0x032, 12}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"data_protection", 0x033, 12}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"unalign_lddf", 0x035, 10}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"unalign_stdf", 0x036, 10}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"priv_action", 0x037, 11}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"unalign_ldqf", 0x038, 10}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"unalign_stqf", 0x039, 10}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"async_data", 0x040, 2}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"clean_win", 0x024, 10}; //The enumerated faults -FaultName InterruptLevelN::_name = "interrupt_n"; -TrapType InterruptLevelN::_baseTrapType = 0x041; -FaultStat InterruptLevelN::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"interrupt_n", 0x041, 0}; -FaultName SpillNNormal::_name = "spill_n_normal"; -TrapType SpillNNormal::_baseTrapType = 0x080; -FaultPriority SpillNNormal::_priority = 9; -FaultStat SpillNNormal::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"spill_n_normal", 0x080, 9}; -FaultName SpillNOther::_name = "spill_n_other"; -TrapType SpillNOther::_baseTrapType = 0x0A0; -FaultPriority SpillNOther::_priority = 9; -FaultStat SpillNOther::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"spill_n_other", 0x0A0, 9}; -FaultName FillNNormal::_name = "fill_n_normal"; -TrapType FillNNormal::_baseTrapType = 0x0C0; -FaultPriority FillNNormal::_priority = 9; -FaultStat FillNNormal::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"fill_n_normal", 0x0C0, 9}; -FaultName FillNOther::_name = "fill_n_other"; -TrapType FillNOther::_baseTrapType = 0x0E0; -FaultPriority FillNOther::_priority = 9; -FaultStat FillNOther::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"fill_n_other", 0x0E0, 9}; -FaultName TrapInstruction::_name = "trap_inst_n"; -TrapType TrapInstruction::_baseTrapType = 0x100; -FaultPriority TrapInstruction::_priority = 16; -FaultStat TrapInstruction::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"trap_inst_n", 0x100, 16}; #if !FULL_SYSTEM -FaultName PageTableFault::_name = "page_table_fault"; -TrapType PageTableFault::_trapType = 0x0000; -FaultPriority PageTableFault::_priority = 0; -FaultStat PageTableFault::_count; +template<> SparcFaultBase::FaultVals + SparcFault::vals = {"page_table_fault", 0x0000, 0}; #endif /** @@ -353,7 +280,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt) #if FULL_SYSTEM -void SparcFault::invoke(ThreadContext * tc) +void SparcFaultBase::invoke(ThreadContext * tc) { FaultBase::invoke(tc); countStat()++; diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index 394a06294..22f83c1e5 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -42,63 +42,58 @@ namespace SparcISA typedef uint32_t TrapType; typedef uint32_t FaultPriority; -class SparcFault : public FaultBase +class SparcFaultBase : public FaultBase { public: + struct FaultVals + { + const FaultName name; + const TrapType trapType; + const FaultPriority priority; + FaultStat count; + }; #if FULL_SYSTEM void invoke(ThreadContext * tc); #endif + virtual FaultName name() = 0; virtual TrapType trapType() = 0; virtual FaultPriority priority() = 0; virtual FaultStat & countStat() = 0; }; -class InternalProcessorError : public SparcFault +template +class SparcFault : public SparcFaultBase +{ + protected: + static FaultVals vals; + public: + FaultName name() {return vals.name;} + TrapType trapType() {return vals.trapType;} + FaultPriority priority() {return vals.priority;} + FaultStat & countStat() {return vals.count;} +}; + +class InternalProcessorError : + public SparcFault { - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} bool isMachineCheckFault() {return true;} }; -class MemAddressNotAligned : public SparcFault +class MemAddressNotAligned : + public SparcFault { - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} bool isAlignmentFault() {return true;} }; #if !FULL_SYSTEM -class PageTableFault : public SparcFault +class PageTableFault : public SparcFault { private: Addr vaddr; - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; public: - PageTableFault(Addr va) - : vaddr(va) {} - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} + PageTableFault(Addr va) : vaddr(va) {} void invoke(ThreadContext * tc); }; @@ -118,499 +113,117 @@ static inline Fault genAlignmentFault() return new MemAddressNotAligned; } -class PowerOnReset : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class PowerOnReset : public SparcFault {}; -class WatchDogReset : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class WatchDogReset : public SparcFault {}; -class ExternallyInitiatedReset : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class ExternallyInitiatedReset : public SparcFault {}; -class SoftwareInitiatedReset : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class SoftwareInitiatedReset : public SparcFault {}; -class REDStateException : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class REDStateException : public SparcFault {}; -class InstructionAccessException : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class InstructionAccessException : public SparcFault {}; -class InstructionAccessMMUMiss : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class InstructionAccessMMUMiss : public SparcFault {}; -class InstructionAccessError : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class InstructionAccessError : public SparcFault {}; -class IllegalInstruction : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class IllegalInstruction : public SparcFault {}; -class PrivilegedOpcode : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class PrivilegedOpcode : public SparcFault {}; -class UnimplementedLDD : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class UnimplementedLDD : public SparcFault {}; -class UnimplementedSTD : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class UnimplementedSTD : public SparcFault {}; -class FpDisabled : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class FpDisabled : public SparcFault {}; -class FpExceptionIEEE754 : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class FpExceptionIEEE754 : public SparcFault {}; -class FpExceptionOther : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class FpExceptionOther : public SparcFault {}; -class TagOverflow : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class TagOverflow : public SparcFault {}; -class DivisionByZero : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class DivisionByZero : public SparcFault {}; -class DataAccessException : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class DataAccessException : public SparcFault {}; -class DataAccessMMUMiss : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class DataAccessMMUMiss : public SparcFault {}; -class DataAccessError : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class DataAccessError : public SparcFault {}; -class DataAccessProtection : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class DataAccessProtection : public SparcFault {}; -class LDDFMemAddressNotAligned : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class LDDFMemAddressNotAligned : public SparcFault {}; -class STDFMemAddressNotAligned : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class STDFMemAddressNotAligned : public SparcFault {}; -class PrivilegedAction : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class PrivilegedAction : public SparcFault {}; -class LDQFMemAddressNotAligned : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class LDQFMemAddressNotAligned : public SparcFault {}; -class STQFMemAddressNotAligned : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class STQFMemAddressNotAligned : public SparcFault {}; -class AsyncDataError : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class AsyncDataError : public SparcFault {}; -class CleanWindow : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - public: - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -}; +class CleanWindow : public SparcFault {}; -class EnumeratedFault : public SparcFault +template +class EnumeratedFault : public SparcFault { protected: uint32_t _n; - virtual TrapType baseTrapType() = 0; public: - EnumeratedFault(uint32_t n) : SparcFault() {_n = n;} - TrapType trapType() {return baseTrapType() + _n;} + EnumeratedFault(uint32_t n) : SparcFault(), _n(n) {} + TrapType trapType() {return SparcFault::trapType() + _n;} }; -class InterruptLevelN : public EnumeratedFault +class InterruptLevelN : public EnumeratedFault { - private: - static FaultName _name; - static TrapType _baseTrapType; - static FaultStat _count; - TrapType baseTrapType() {return _baseTrapType;} public: - InterruptLevelN(uint32_t n) : EnumeratedFault(n) {;} - FaultName name() {return _name;} + InterruptLevelN(uint32_t n) : + EnumeratedFault(n) {;} FaultPriority priority() {return 32 - _n;} - FaultStat & countStat() {return _count;} }; -class SpillNNormal : public EnumeratedFault +class SpillNNormal : public EnumeratedFault { - private: - static FaultName _name; - static TrapType _baseTrapType; - static FaultPriority _priority; - static FaultStat _count; - TrapType baseTrapType() {return _baseTrapType;} public: - SpillNNormal(uint32_t n) : EnumeratedFault(n) {;} - FaultName name() {return _name;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} + SpillNNormal(uint32_t n) : + EnumeratedFault(n) {;} void invoke(ThreadContext * tc); }; -class SpillNOther : public EnumeratedFault +class SpillNOther : public EnumeratedFault { - private: - static FaultName _name; - static TrapType _baseTrapType; - static FaultPriority _priority; - static FaultStat _count; - TrapType baseTrapType() {return _baseTrapType;} public: - SpillNOther(uint32_t n) : EnumeratedFault(n) {;} - FaultName name() {return _name;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} + SpillNOther(uint32_t n) : + EnumeratedFault(n) {;} }; -class FillNNormal : public EnumeratedFault +class FillNNormal : public EnumeratedFault { - private: - static FaultName _name; - static TrapType _baseTrapType; - static FaultPriority _priority; - static FaultStat _count; - TrapType baseTrapType() {return _baseTrapType;} public: - FillNNormal(uint32_t n) : EnumeratedFault(n) {;} - FaultName name() {return _name;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} + FillNNormal(uint32_t n) : + EnumeratedFault(n) {;} void invoke(ThreadContext * tc); }; -class FillNOther : public EnumeratedFault +class FillNOther : public EnumeratedFault { - private: - static FaultName _name; - static TrapType _baseTrapType; - static FaultPriority _priority; - static FaultStat _count; - TrapType baseTrapType() {return _baseTrapType;} public: - FillNOther(uint32_t n) : EnumeratedFault(n) {;} - FaultName name() {return _name;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} + FillNOther(uint32_t n) : + EnumeratedFault(n) {;} }; -class TrapInstruction : public EnumeratedFault +class TrapInstruction : public EnumeratedFault { private: - static FaultName _name; - static TrapType _baseTrapType; - static FaultPriority _priority; - static FaultStat _count; uint64_t syscall_num; - TrapType baseTrapType() {return _baseTrapType;} public: TrapInstruction(uint32_t n, uint64_t syscall) : - EnumeratedFault(n), syscall_num(syscall) {;} - FaultName name() {return _name;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} + EnumeratedFault(n), syscall_num(syscall) {;} #if !FULL_SYSTEM void invoke(ThreadContext * tc); #endif -- cgit v1.2.3 From 9375caa3f1ac8ff8fe5bcf3b7de1f51a20b6cd91 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 08:25:37 -0500 Subject: Fix for slightly mangled merge. --HG-- extra : convert_revision : 1dea04ca222dd423c3d462114bc1c65afa52825d --- src/arch/sparc/faults.hh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index 677f8e77e..9cc7739d9 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -228,9 +228,10 @@ class FillNOther : public EnumeratedFault class TrapInstruction : public EnumeratedFault { + public: - TrapInstruction(uint32_t n, uint64_t syscall) : - EnumeratedFault(n), syscall_num(syscall) {;} + TrapInstruction(uint32_t n) : + EnumeratedFault(n) {;} }; -- cgit v1.2.3 From 770b575c30e734b3ed9528558a72c476a9e4bf41 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 10:27:38 -0500 Subject: Sorted faults by the trap type constant, expanded their names, added in new faults for ua2005, and commented out ones which are apparently dropped. --HG-- extra : convert_revision : 32bd0c3a75d7c036ad4a3cb0bc1c32e0b6cb3d87 --- src/arch/sparc/faults.cc | 180 +++++++++++++++++++++++++++++++++++++---------- src/arch/sparc/faults.hh | 161 ++++++++++++++++++++++++++---------------- 2 files changed, 244 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 6a905a76c..ebd9926b2 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -50,118 +50,222 @@ namespace SparcISA { template<> SparcFaultBase::FaultVals - SparcFault::vals = {"intprocerr", 0x029, 4}; + SparcFault::vals = + {"power_on_reset", 0x001, 0, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"unalign", 0x034, 10}; + SparcFault::vals = + {"watch_dog_reset", 0x002, 120, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"pow_reset", 0x001, 0}; + SparcFault::vals = + {"externally_initiated_reset", 0x003, 110, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"watch_dog_reset", 0x002, 1}; + SparcFault::vals = + {"software_initiated_reset", 0x004, 130, {SH, SH, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"extern_reset", 0x003, 1}; + SparcFault::vals = + {"RED_state_exception", 0x005, 1, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"software_reset", 0x004, 1}; + SparcFault::vals = + {"store_error", 0x007, 201, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"red_counte", 0x005, 1}; + SparcFault::vals = + {"instruction_access_exception", 0x008, 300, {H, H, H}}; + +//XXX This trap is apparently dropped from ua2005 +/*template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"inst_mmu", 0x009, 2, {H, H, H}};*/ + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"instruction_access_error", 0x00A, 400, {H, H, H}}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"illegal_instruction", 0x010, 620, {H, H, H}}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"privileged_opcode", 0x011, 700, {P, SH, SH}}; + +//XXX This trap is apparently dropped from ua2005 +/*template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"unimp_ldd", 0x012, 6, {H, H, H}};*/ + +//XXX This trap is apparently dropped from ua2005 +/*template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"unimp_std", 0x013, 6, {H, H, H}};*/ + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"fp_disabled", 0x020, 800, {P, P, H}}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"fp_exception_ieee_754", 0x021, 1110, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"inst_access", 0x008, 5}; + SparcFault::vals = + {"fp_exception_other", 0x022, 1110, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"inst_mmu", 0x009, 2}; + SparcFault::vals = + {"tag_overflow", 0x023, 1400, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"inst_error", 0x00A, 3}; + SparcFault::vals = + {"clean_window", 0x024, 1010, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"illegal_inst", 0x010, 7}; + SparcFault::vals = + {"division_by_zero", 0x028, 1500, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"priv_opcode", 0x011, 6}; + SparcFault::vals = + {"internal_processor_error", 0x029, 4, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"unimp_ldd", 0x012, 6}; + SparcFault::vals = + {"instruction_invalid_tsb_entry", 0x02A, 210, {H, H, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"unimp_std", 0x013, 6}; + SparcFault::vals = + {"data_invalid_tsb_entry", 0x02B, 1203, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"fp_disabled", 0x020, 8}; + SparcFault::vals = + {"data_access_exception", 0x030, 1201, {H, H, H}}; + +//XXX This trap is apparently dropped from ua2005 +/*template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"data_mmu", 0x031, 12, {H, H, H}};*/ + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"data_access_error", 0x032, 1210, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"fp_754", 0x021, 11}; + SparcFault::vals = + {"data_access_protection", 0x033, 1207, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"fp_other", 0x022, 11}; + SparcFault::vals = + {"mem_address_not_aligned", 0x034, 1020, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"tag_overflow", 0x023, 14}; + SparcFault::vals = + {"LDDF_mem_address_not_aligned", 0x035, 1010, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"div_by_zero", 0x028, 15}; + SparcFault::vals = + {"STDF_mem_address_not_aligned", 0x036, 1010, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"data_access", 0x030, 12}; + SparcFault::vals = + {"privileged_action", 0x037, 1110, {H, H, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"data_mmu", 0x031, 12}; + SparcFault::vals = + {"LDQF_mem_address_not_aligned", 0x038, 1010, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"data_error", 0x032, 12}; + SparcFault::vals = + {"STQF_mem_address_not_aligned", 0x039, 1010, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"data_protection", 0x033, 12}; + SparcFault::vals = + {"instruction_real_translation_miss", 0x03E, 208, {H, H, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"unalign_lddf", 0x035, 10}; + SparcFault::vals = + {"data_real_translation_miss", 0x03F, 1203, {H, H, H}}; + +//XXX This trap is apparently dropped from ua2005 +/*template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"async_data", 0x040, 2, {H, H, H}};*/ template<> SparcFaultBase::FaultVals - SparcFault::vals = {"unalign_stdf", 0x036, 10}; + SparcFault::vals = + {"interrupt_level_n", 0x041, 0, {P, P, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"priv_action", 0x037, 11}; + SparcFault::vals = + {"hstick_match", 0x05E, 1601, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"unalign_ldqf", 0x038, 10}; + SparcFault::vals = + {"trap_level_zero", 0x05F, 202, {H, H, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"unalign_stqf", 0x039, 10}; + SparcFault::vals = + {"PA_watchpoint", 0x061, 1209, {H, H, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"async_data", 0x040, 2}; + SparcFault::vals = + {"VA_watchpoint", 0x062, 1120, {P, P, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"clean_win", 0x024, 10}; + SparcFault::vals = + {"fast_instruction_access_MMU_miss", 0x064, 208, {H, H, SH}}; -//The enumerated faults +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"fast_data_access_MMU_miss", 0x068, 1203, {H, H, H}}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"fast_data_access_protection", 0x06C, 1207, {H, H, H}}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"instruction_break", 0x076, 610, {H, H, H}}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"cpu_mondo", 0x07C, 1608, {P, P, SH}}; + +template<> SparcFaultBase::FaultVals + SparcFault::vals = + {"dev_mondo", 0x07D, 1611, {P, P, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"interrupt_n", 0x041, 0}; + SparcFault::vals = + {"resume_error", 0x07E, 3330, {P, P, SH}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"spill_n_normal", 0x080, 9}; + SparcFault::vals = + {"spill_n_normal", 0x080, 900, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"spill_n_other", 0x0A0, 9}; + SparcFault::vals = + {"spill_n_other", 0x0A0, 900, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"fill_n_normal", 0x0C0, 9}; + SparcFault::vals = + {"fill_n_normal", 0x0C0, 900, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"fill_n_other", 0x0E0, 9}; + SparcFault::vals = + {"fill_n_other", 0x0E0, 900, {P, P, H}}; template<> SparcFaultBase::FaultVals - SparcFault::vals = {"trap_inst_n", 0x100, 16}; + SparcFault::vals = + {"trap_instruction", 0x100, 1602, {P, P, H}}; #if !FULL_SYSTEM template<> SparcFaultBase::FaultVals - SparcFault::vals = {"page_table_fault", 0x0000, 0}; + SparcFault::vals = + {"page_table_fault", 0x0000, 0, {SH, SH, SH}}; #endif /** diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index 9cc7739d9..e632502aa 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -45,11 +45,21 @@ typedef uint32_t FaultPriority; class SparcFaultBase : public FaultBase { public: + enum PrivilegeLevel + { + U, User = U, + P, Privileged = P, + H, Hyperprivileged = H, + NumLevels, + SH = -1, + ShouldntHappen = SH + }; struct FaultVals { const FaultName name; const TrapType trapType; const FaultPriority priority; + const PrivilegeLevel nextPrivilegeLevel[NumLevels]; FaultStat count; }; #if FULL_SYSTEM @@ -59,6 +69,7 @@ class SparcFaultBase : public FaultBase virtual TrapType trapType() = 0; virtual FaultPriority priority() = 0; virtual FaultStat & countStat() = 0; + virtual PrivilegeLevel getNextLevel(PrivilegeLevel current) = 0; }; template @@ -71,48 +82,12 @@ class SparcFault : public SparcFaultBase TrapType trapType() {return vals.trapType;} FaultPriority priority() {return vals.priority;} FaultStat & countStat() {return vals.count;} + PrivilegeLevel getNextLevel(PrivilegeLevel current) + { + return vals.nextPrivilegeLevel[current]; + } }; -class InternalProcessorError : - public SparcFault -{ - public: - bool isMachineCheckFault() {return true;} -}; - -class MemAddressNotAligned : - public SparcFault -{ - public: - bool isAlignmentFault() {return true;} -}; - -#if !FULL_SYSTEM -class PageTableFault : public SparcFault -{ - private: - Addr vaddr; - public: - PageTableFault(Addr va) : vaddr(va) {} - void invoke(ThreadContext * tc); -}; - -static inline Fault genPageTableFault(Addr va) -{ - return new PageTableFault(va); -} -#endif - -static inline Fault genMachineCheckFault() -{ - return new InternalProcessorError; -} - -static inline Fault genAlignmentFault() -{ - return new MemAddressNotAligned; -} - class PowerOnReset : public SparcFault { void invoke(ThreadContext * tc); @@ -126,9 +101,11 @@ class SoftwareInitiatedReset : public SparcFault {}; class REDStateException : public SparcFault {}; +class StoreError : public SparcFault {}; + class InstructionAccessException : public SparcFault {}; -class InstructionAccessMMUMiss : public SparcFault {}; +//class InstructionAccessMMUMiss : public SparcFault {}; class InstructionAccessError : public SparcFault {}; @@ -136,9 +113,9 @@ class IllegalInstruction : public SparcFault {}; class PrivilegedOpcode : public SparcFault {}; -class UnimplementedLDD : public SparcFault {}; +//class UnimplementedLDD : public SparcFault {}; -class UnimplementedSTD : public SparcFault {}; +//class UnimplementedSTD : public SparcFault {}; class FpDisabled : public SparcFault {}; @@ -148,16 +125,36 @@ class FpExceptionOther : public SparcFault {}; class TagOverflow : public SparcFault {}; +class CleanWindow : public SparcFault {}; + class DivisionByZero : public SparcFault {}; +class InternalProcessorError : + public SparcFault +{ + public: + bool isMachineCheckFault() {return true;} +}; + +class InstructionInvalidTSBEntry : public SparcFault {}; + +class DataInvalidTSBEntry : public SparcFault {}; + class DataAccessException : public SparcFault {}; -class DataAccessMMUMiss : public SparcFault {}; +//class DataAccessMMUMiss : public SparcFault {}; class DataAccessError : public SparcFault {}; class DataAccessProtection : public SparcFault {}; +class MemAddressNotAligned : + public SparcFault +{ + public: + bool isAlignmentFault() {return true;} +}; + class LDDFMemAddressNotAligned : public SparcFault {}; class STDFMemAddressNotAligned : public SparcFault {}; @@ -168,9 +165,12 @@ class LDQFMemAddressNotAligned : public SparcFault {}; class STQFMemAddressNotAligned : public SparcFault {}; -class AsyncDataError : public SparcFault {}; +class InstructionRealTranslationMiss : + public SparcFault {}; -class CleanWindow : public SparcFault {}; +class DataRealTranslationMiss : public SparcFault {}; + +//class AsyncDataError : public SparcFault {}; template class EnumeratedFault : public SparcFault @@ -185,16 +185,37 @@ class EnumeratedFault : public SparcFault class InterruptLevelN : public EnumeratedFault { public: - InterruptLevelN(uint32_t n) : - EnumeratedFault(n) {;} - FaultPriority priority() {return 32 - _n;} + InterruptLevelN(uint32_t n) : EnumeratedFault(n) {;} + FaultPriority priority() {return 3200 - _n*100;} }; +class HstickMatch : public SparcFault {}; + +class TrapLevelZero : public SparcFault {}; + +class PAWatchpoint : public SparcFault {}; + +class VAWatchpoint : public SparcFault {}; + +class FastInstructionAccessMMUMiss : + public SparcFault {}; + +class FastDataAccessMMUMiss : public SparcFault {}; + +class FastDataAccessProtection : public SparcFault {}; + +class InstructionBreakpoint : public SparcFault {}; + +class CpuMondo : public SparcFault {}; + +class DevMondo : public SparcFault {}; + +class ResumeableError : public SparcFault {}; + class SpillNNormal : public EnumeratedFault { public: - SpillNNormal(uint32_t n) : - EnumeratedFault(n) {;} + SpillNNormal(uint32_t n) : EnumeratedFault(n) {;} //These need to be handled specially to enable spill traps in SE #if !FULL_SYSTEM void invoke(ThreadContext * tc); @@ -204,15 +225,13 @@ class SpillNNormal : public EnumeratedFault class SpillNOther : public EnumeratedFault { public: - SpillNOther(uint32_t n) : - EnumeratedFault(n) {;} + SpillNOther(uint32_t n) : EnumeratedFault(n) {;} }; class FillNNormal : public EnumeratedFault { public: - FillNNormal(uint32_t n) : - EnumeratedFault(n) {;} + FillNNormal(uint32_t n) : EnumeratedFault(n) {;} //These need to be handled specially to enable fill traps in SE #if !FULL_SYSTEM void invoke(ThreadContext * tc); @@ -222,18 +241,42 @@ class FillNNormal : public EnumeratedFault class FillNOther : public EnumeratedFault { public: - FillNOther(uint32_t n) : - EnumeratedFault(n) {;} + FillNOther(uint32_t n) : EnumeratedFault(n) {;} }; class TrapInstruction : public EnumeratedFault { public: - TrapInstruction(uint32_t n) : - EnumeratedFault(n) {;} + TrapInstruction(uint32_t n) : EnumeratedFault(n) {;} +}; + +#if !FULL_SYSTEM +class PageTableFault : public SparcFault +{ + private: + Addr vaddr; + public: + PageTableFault(Addr va) : vaddr(va) {} + void invoke(ThreadContext * tc); }; +static inline Fault genPageTableFault(Addr va) +{ + return new PageTableFault(va); +} +#endif + +static inline Fault genMachineCheckFault() +{ + return new InternalProcessorError; +} + +static inline Fault genAlignmentFault() +{ + return new MemAddressNotAligned; +} + } // SparcISA namespace -- cgit v1.2.3 From 344f72dd62f6cc9ab8c7ab5454a320b2e5674a37 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Wed, 8 Nov 2006 13:04:36 -0500 Subject: Remove mem parameter. Should have been removed earlier. src/python/m5/objects/BaseCPU.py: These parameters should have been removed in an earlier push. --HG-- extra : convert_revision : 781b39ca370361e9568b1af0be96ff5848b1f3f4 --- src/python/m5/objects/BaseCPU.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/python/m5/objects/BaseCPU.py b/src/python/m5/objects/BaseCPU.py index b6dc08e46..4e34e8a4e 100644 --- a/src/python/m5/objects/BaseCPU.py +++ b/src/python/m5/objects/BaseCPU.py @@ -8,7 +8,6 @@ from Bus import Bus class BaseCPU(SimObject): type = 'BaseCPU' abstract = True - mem = Param.MemObject("memory") system = Param.System(Parent.any, "system object") cpu_id = Param.Int("CPU identifier") @@ -47,7 +46,6 @@ class BaseCPU(SimObject): self.icache_port = ic.cpu_side self.dcache_port = dc.cpu_side self._mem_ports = ['icache.mem_side', 'dcache.mem_side'] -# self.mem = dc def addTwoLevelCacheHierarchy(self, ic, dc, l2c): self.addPrivateSplitL1Caches(ic, dc) -- cgit v1.2.3 From 67b9a2ebd850b6b0a01324b46ac3d6f87b3a8cb5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 13:55:48 -0500 Subject: Move the check to see if you're in user mode into the isa directory. --HG-- extra : convert_revision : b5b7cdf4a5e5e54228c592093516bf18d0f7dbe6 --- src/arch/alpha/utility.hh | 6 ++++++ src/arch/sparc/utility.hh | 8 ++++++++ src/cpu/o3/commit_impl.hh | 4 ++-- src/cpu/simple/base.cc | 3 +-- 4 files changed, 17 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh index cb86c7e9e..100736555 100644 --- a/src/arch/alpha/utility.hh +++ b/src/arch/alpha/utility.hh @@ -42,6 +42,12 @@ namespace AlphaISA { + static inline bool + inUserMode(ThreadContext *tc) + { + return (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; + } + static inline ExtMachInst makeExtMI(MachInst inst, Addr pc) { #if FULL_SYSTEM diff --git a/src/arch/sparc/utility.hh b/src/arch/sparc/utility.hh index e2b0b2307..e51677cdf 100644 --- a/src/arch/sparc/utility.hh +++ b/src/arch/sparc/utility.hh @@ -39,6 +39,14 @@ namespace SparcISA { + + static inline bool + inUserMode(ThreadContext *tc) + { + return !(tc->readMiscReg(MISCREG_PSTATE & (1 << 2)) || + tc->readMiscReg(MISCREG_HPSTATE & (1 << 2))); + } + inline ExtMachInst makeExtMI(MachInst inst, ThreadContext * xc) { ExtMachInst emi = (unsigned MachInst) inst; diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index bd5c4f9ce..30052a148 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -35,6 +35,7 @@ #include #include +#include "arch/utility.hh" #include "base/loader/symtab.hh" #include "base/timebuf.hh" #include "cpu/exetrace.hh" @@ -1084,8 +1085,7 @@ DefaultCommit::commitHead(DynInstPtr &head_inst, unsigned inst_num) #if FULL_SYSTEM if (thread[tid]->profile) { -// bool usermode = -// (cpu->readMiscReg(AlphaISA::IPR_DTB_CM, tid) & 0x18) != 0; +// bool usermode = TheISA::inUserMode(thread[tid]->getTC()); // thread[tid]->profilePC = usermode ? 1 : head_inst->readPC(); thread[tid]->profilePC = head_inst->readPC(); ProfileNode *node = thread[tid]->profile->consume(thread[tid]->getTC(), diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 00fa4d247..ab438aa77 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -407,8 +407,7 @@ BaseSimpleCPU::postExecute() { #if FULL_SYSTEM if (thread->profile) { - bool usermode = - (thread->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; + bool usermode = TheISA::inUserMode(tc); thread->profilePC = usermode ? 1 : thread->readPC(); ProfileNode *node = thread->profile->consume(tc, inst); if (node) -- cgit v1.2.3 From 63bbc8929d778c15f5c7479819226c19a42dc2b9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 13:58:00 -0500 Subject: First cut at full blown SPARC faults. There are a few details that are missing. --HG-- extra : convert_revision : 8023db1479cb9bf99fc9edfeb521c4e5b581f895 --- src/arch/sparc/faults.cc | 240 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 211 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index ebd9926b2..e895c02db 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -33,6 +33,7 @@ #include "arch/sparc/faults.hh" #include "arch/sparc/isa_traits.hh" +#include "arch/sparc/types.hh" #include "base/bitfield.hh" #include "base/trace.hh" #include "config/full_system.hh" @@ -268,26 +269,133 @@ template<> SparcFaultBase::FaultVals {"page_table_fault", 0x0000, 0, {SH, SH, SH}}; #endif +/** + * This causes the thread context to enter RED state. This causes the side + * effects which go with entering RED state because of a trap. + */ + +void enterREDState(ThreadContext *tc) +{ + //@todo Disable the mmu? + //@todo Disable watchpoints? + MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); + //HPSTATE.red = 1 + HPSTATE |= (1 << 5); + //HPSTATE.hpriv = 1 + HPSTATE |= (1 << 2); + tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); +} + +/** + * This sets everything up for a RED state trap except for actually jumping to + * the handler. + */ + +void doREDFault(ThreadContext *tc, TrapType tt) +{ + MiscReg TL = tc->readMiscReg(MISCREG_TL); + MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE); + MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); + MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); + MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + MiscReg ASI = tc->readMiscReg(MISCREG_ASI); + MiscReg CWP = tc->readMiscReg(MISCREG_CWP); + MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + MiscReg GL = tc->readMiscReg(MISCREG_GL); + MiscReg PC = tc->readPC(); + MiscReg NPC = tc->readNextPC(); + + TL++; + + //set TSTATE.gl to gl + replaceBits(TSTATE, 42, 40, GL); + //set TSTATE.ccr to ccr + replaceBits(TSTATE, 39, 32, CCR); + //set TSTATE.asi to asi + replaceBits(TSTATE, 31, 24, ASI); + //set TSTATE.pstate to pstate + replaceBits(TSTATE, 20, 8, PSTATE); + //set TSTATE.cwp to cwp + replaceBits(TSTATE, 4, 0, CWP); + + //Write back TSTATE + tc->setMiscReg(MISCREG_TSTATE, TSTATE); + + //set TPC to PC + tc->setMiscReg(MISCREG_TPC, PC); + //set TNPC to NPC + tc->setMiscReg(MISCREG_TNPC, NPC); + + //set HTSTATE.hpstate to hpstate + tc->setMiscReg(MISCREG_HTSTATE, HPSTATE); + + //TT = trap type; + tc->setMiscReg(MISCREG_TT, tt); + + //Update GL + tc->setMiscRegWithEffect(MISCREG_GL, min(GL+1, MaxGL)); + + //set PSTATE.mm to 00 + //set PSTATE.pef to 1 + PSTATE |= (1 << 4); + //set PSTATE.am to 0 + PSTATE &= ~(1 << 3); + //set PSTATE.priv to 0 + PSTATE &= ~(1 << 2); + //set PSTATE.ie to 0 + PSTATE &= ~(1 << 1); + //set PSTATE.cle to 0 + PSTATE &= ~(1 << 9); + //PSTATE.tle is unchanged + //XXX Where is the tct bit? + //set PSTATE.tct to 0 + tc->setMiscReg(MISCREG_PSTATE, PSTATE); + + //set HPSTATE.red to 1 + HPSTATE |= (1 << 5); + //set HPSTATE.hpriv to 1 + HPSTATE |= (1 << 2); + //set HPSTATE.ibe to 0 + HPSTATE &= ~(1 << 10); + //set HPSTATE.tlz to 0 + HPSTATE &= ~(1 << 0); + tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); + + bool changedCWP = true; + if(tt == 0x24) + CWP++; + else if(0x80 <= tt && tt <= 0xbf) + CWP += (CANSAVE + 2); + else if(0xc0 <= tt && tt <= 0xff) + CWP--; + else + changedCWP = false; + + if(changedCWP) + { + CWP = (CWP + NWindows) % NWindows; + tc->setMiscRegWithEffect(MISCREG_CWP, CWP); + } +} + /** * This sets everything up for a normal trap except for actually jumping to - * the handler. It will need to be expanded to include the state machine in - * the manual. Right now it assumes that traps will always be to the - * privileged level. + * the handler. */ -void doNormalFault(ThreadContext *tc, TrapType tt) +void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) { - uint64_t TL = tc->readMiscReg(MISCREG_TL); - uint64_t TSTATE = tc->readMiscReg(MISCREG_TSTATE); - uint64_t PSTATE = tc->readMiscReg(MISCREG_PSTATE); - uint64_t HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); - uint64_t CCR = tc->readMiscReg(MISCREG_CCR); - uint64_t ASI = tc->readMiscReg(MISCREG_ASI); - uint64_t CWP = tc->readMiscReg(MISCREG_CWP); - uint64_t CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); - uint64_t GL = tc->readMiscReg(MISCREG_GL); - uint64_t PC = tc->readPC(); - uint64_t NPC = tc->readNextPC(); + MiscReg TL = tc->readMiscReg(MISCREG_TL); + MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE); + MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); + MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); + MiscReg CCR = tc->readMiscReg(MISCREG_CCR); + MiscReg ASI = tc->readMiscReg(MISCREG_ASI); + MiscReg CWP = tc->readMiscReg(MISCREG_CWP); + MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + MiscReg GL = tc->readMiscReg(MISCREG_GL); + MiscReg PC = tc->readPC(); + MiscReg NPC = tc->readNextPC(); //Increment the trap level TL++; @@ -321,10 +429,10 @@ void doNormalFault(ThreadContext *tc, TrapType tt) tc->setMiscReg(MISCREG_TT, tt); //Update the global register level - if(1/*We're delivering the trap in priveleged mode*/) - tc->setMiscReg(MISCREG_GL, min(GL+1, MaxGL)); + if(!gotoHpriv) + tc->setMiscRegWithEffect(MISCREG_GL, min(GL+1, MaxPGL)); else - tc->setMiscReg(MISCREG_GL, min(GL+1, MaxPGL)); + tc->setMiscRegWithEffect(MISCREG_GL, min(GL+1, MaxGL)); //PSTATE.mm is unchanged //PSTATE.pef = whether or not an fpu is present @@ -333,7 +441,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt) PSTATE |= (1 << 4); //PSTATE.am = 0 PSTATE &= ~(1 << 3); - if(1/*We're delivering the trap in priveleged mode*/) + if(!gotoHpriv) { //PSTATE.priv = 1 PSTATE |= (1 << 2); @@ -354,7 +462,7 @@ void doNormalFault(ThreadContext *tc, TrapType tt) //XXX Where exactly is this field? tc->setMiscReg(MISCREG_PSTATE, PSTATE); - if(0/*We're delivering the trap in hyperprivileged mode*/) + if(gotoHpriv) { //HPSTATE.red = 0 HPSTATE &= ~(1 << 5); @@ -383,6 +491,29 @@ void doNormalFault(ThreadContext *tc, TrapType tt) } } +void getREDVector(Addr & PC, Addr & NPC) +{ + const Addr RSTVAddr = 0xFFFFFFFFF0000000ULL; + PC = RSTVAddr | 0xA0; + NPC = PC + sizeof(MachInst); +} + +void getHyperVector(Addr & PC, Addr & NPC, MiscReg TT) +{ + Addr HTBA ; + PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14)); + NPC = PC + sizeof(MachInst); +} + +void getPrivVector(Addr & PC, Addr & NPC, MiscReg TT, MiscReg TL) +{ + Addr TBA ; + PC = (TBA & ~mask(15)) | + (TL > 1 ? (1 << 14) : 0) | + ((TT << 5) & mask(14)); + NPC = PC + sizeof(MachInst); +} + #if FULL_SYSTEM void SparcFaultBase::invoke(ThreadContext * tc) @@ -390,11 +521,64 @@ void SparcFaultBase::invoke(ThreadContext * tc) FaultBase::invoke(tc); countStat()++; - //Use the SPARC trap state machine + //We can refer to this to see what the trap level -was-, but something + //in the middle could change it in the regfile out from under us. + MiscReg TL = tc->readMiscReg(MISCREG_TL); + MiscReg TT = tc->readMiscReg(MISCREG_TT); + MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE); + MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); + + Addr PC, NPC; + + PrivilegeLevel current; + if(!(PSTATE & (1 << 2))) + current = User; + else if(!(HPSTATE & (1 << 2))) + current = Privileged; + else + current = Hyperprivileged; + + PrivilegeLevel level = getNextLevel(current); + + if(HPSTATE & (1 << 5) || TL == MaxTL - 1) + { + getREDVector(PC, NPC); + enterREDState(tc); + doREDFault(tc, TT); + } + else if(TL == MaxTL) + { + //Do error_state somehow? + //Probably inject a WDR fault using the interrupt mechanism. + //What should the PC and NPC be set to? + } + else if(TL > MaxPTL && level == Privileged) + { + //guest_watchdog fault + doNormalFault(tc, trapType(), true); + getHyperVector(PC, NPC, 2); + } + else if(level == Hyperprivileged) + { + doNormalFault(tc, trapType(), true); + getHyperVector(PC, NPC, trapType()); + } + else + { + doNormalFault(tc, trapType(), false); + getPrivVector(PC, NPC, trapType(), TL+1); + } + + tc->setPC(PC); + tc->setNextPC(NPC); + tc->setNextNPC(NPC + sizeof(MachInst)); } void PowerOnReset::invoke(ThreadContext * tc) { + //First, enter RED state. + enterREDState(tc); + //For SPARC, when a system is first started, there is a power //on reset Trap which sets the processor into the following state. //Bits that aren't set aren't defined on startup. @@ -426,17 +610,15 @@ void PowerOnReset::invoke(ThreadContext * tc) */ } -#endif - -#if !FULL_SYSTEM +#else // !FULL_SYSTEM void SpillNNormal::invoke(ThreadContext *tc) { - doNormalFault(tc, trapType()); + doNormalFault(tc, trapType(), false); Process *p = tc->getProcessPtr(); - //This will only work in faults from a SparcLiveProcess + //XXX This will only work in faults from a SparcLiveProcess SparcLiveProcess *lp = dynamic_cast(p); assert(lp); @@ -449,15 +631,15 @@ void SpillNNormal::invoke(ThreadContext *tc) void FillNNormal::invoke(ThreadContext *tc) { - doNormalFault(tc, trapType()); + doNormalFault(tc, trapType(), false); Process * p = tc->getProcessPtr(); - //This will only work in faults from a SparcLiveProcess + //XXX This will only work in faults from a SparcLiveProcess SparcLiveProcess *lp = dynamic_cast(p); assert(lp); - //The adjust the PC and NPC + //Then adjust the PC and NPC Addr fillStart = lp->readFillStart(); tc->setPC(fillStart); tc->setNextPC(fillStart + sizeof(MachInst)); -- cgit v1.2.3 From 64c0d82dec8ae042d41b6dbaa17a40095bb09091 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Wed, 8 Nov 2006 15:05:23 -0500 Subject: simplify maxtick parsing in both the python and the c++. configs/common/Simulation.py: simplify maxtick code a little bit - instead of checking for -1, just set it at MaxTick. src/python/m5/__init__.py: make a new m5 param called MaxTick. src/sim/host.hh: fix the M5 def. of MaxTick src/sim/main.cc: Simplify the MaxTick/num_cycles parsing within main.cc --HG-- extra : convert_revision : f800addfbc1323591c2e05b892276b439b671668 --- src/python/m5/__init__.py | 3 +++ src/sim/host.hh | 2 +- src/sim/main.cc | 12 ++++-------- 3 files changed, 8 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py index 42abfe2cc..579562b38 100644 --- a/src/python/m5/__init__.py +++ b/src/python/m5/__init__.py @@ -39,6 +39,9 @@ from cc_main import simulate, SimLoopExitEvent # import the m5 compile options import defines +# define a MaxTick parameter +MaxTick = 2**63 - 1 + # define this here so we can use it right away if necessary def panic(string): print >>sys.stderr, 'panic:', string diff --git a/src/sim/host.hh b/src/sim/host.hh index 9c79580b1..a2faa206b 100644 --- a/src/sim/host.hh +++ b/src/sim/host.hh @@ -56,7 +56,7 @@ typedef int64_t Counter; */ typedef int64_t Tick; -const Tick MaxTick = (1LL << 62); +const Tick MaxTick = (1LL << 63) - 1; /** * Address type diff --git a/src/sim/main.cc b/src/sim/main.cc index 133141e57..5b44102a8 100644 --- a/src/sim/main.cc +++ b/src/sim/main.cc @@ -309,18 +309,14 @@ finalInit() * @return The SimLoopExitEvent that caused the loop to exit. */ SimLoopExitEvent * -simulate(Tick num_cycles = -1) +simulate(Tick num_cycles = MaxTick) { warn("Entering event queue @ %d. Starting simulation...\n", curTick); - // Fix up num_cycles. Special default value -1 means simulate - // "forever"... schedule event at MaxTick just to be safe. - // Otherwise it's a delta for additional cycles to simulate past - // curTick, and thus must be non-negative. - if (num_cycles == -1) - num_cycles = MaxTick; - else if (num_cycles < 0) + if (num_cycles < 0) fatal("simulate: num_cycles must be >= 0 (was %d)\n", num_cycles); + else if (curTick + num_cycles < 0) //Overflow + num_cycles = MaxTick; else num_cycles = curTick + num_cycles; -- cgit v1.2.3 From 100f9bfb0b87cfd393226efe714eb9259b978aff Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 8 Nov 2006 15:05:54 -0500 Subject: DWARF2 symbol support seems to be broken on Solaris. Use stabs+ align the character arrays that are used by placement-new for classes lest we have an unaligned fault on SPARC/Solaris src/SConscript: DWARF2 symbol support seems to be broken on Solaris. Use stabs+ src/base/statistics.hh: align the character arrays that are used by placement-new for classes lest we have an unaligned fault on SPARC/Solaris --HG-- extra : convert_revision : bc875a4fdfb4553062d3278537bc32a5ab9b6cca --- src/SConscript | 9 ++++++++- src/base/statistics.hh | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/SConscript b/src/SConscript index d938d533f..8d2c8566b 100644 --- a/src/SConscript +++ b/src/SConscript @@ -399,8 +399,15 @@ def makeEnv(label, objsfx, strip = False, **kwargs): envList.append(newEnv) # Debug binary +# Solaris seems to have some issue with DWARF2 debugging information, it's ok +# with stabs though +if sys.platform == 'sunos5': + debug_flag = '-gstabs+' +else: + debug_flag = '-ggdb3' + makeEnv('debug', '.do', - CCFLAGS = Split('-g3 -gdwarf-2 -O0'), + CCFLAGS = Split('%s -O0' % debug_flag), CPPDEFINES = 'DEBUG') # Optimized binary diff --git a/src/base/statistics.hh b/src/base/statistics.hh index 59f219c07..577ea5eab 100644 --- a/src/base/statistics.hh +++ b/src/base/statistics.hh @@ -696,7 +696,7 @@ class ScalarBase : public DataAccess protected: /** The storage of this stat. */ - char storage[sizeof(Storage)]; + char storage[sizeof(Storage)] __attribute__ ((aligned (8))); /** The parameters for this stat. */ Params params; @@ -1637,7 +1637,7 @@ class DistBase : public DataAccess protected: /** The storage for this stat. */ - char storage[sizeof(Storage)]; + char storage[sizeof(Storage)] __attribute__ ((aligned (8))); /** The parameters for this stat. */ Params params; -- cgit v1.2.3 From 42c73c6a9215a46ec83e31e03aef9eddc281336f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 15:31:52 -0500 Subject: Make a function to say how big gdbregs is in bytes vs. regs. --HG-- extra : convert_revision : 10c50c2d45a8e510d71cccde520059363116da8a --- src/arch/alpha/remote_gdb.cc | 4 ++-- src/base/remote_gdb.cc | 10 +++++----- src/base/remote_gdb.hh | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc index 829e41ca8..f23fc3205 100644 --- a/src/arch/alpha/remote_gdb.cc +++ b/src/arch/alpha/remote_gdb.cc @@ -141,7 +141,7 @@ using namespace TheISA; RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) : BaseRemoteGDB(_system, c, KGDB_NUMREGS) { - memset(gdbregs.regs, 0, gdbregs.size); + memset(gdbregs.regs, 0, gdbregs.bytes()); } /////////////////////////////////////////////////////////// @@ -201,7 +201,7 @@ RemoteGDB::acc(Addr va, size_t len) void RemoteGDB::getregs() { - memset(gdbregs.regs, 0, gdbregs.size); + memset(gdbregs.regs, 0, gdbregs.bytes()); gdbregs.regs[KGDB_REG_PC] = context->readPC(); diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index fae814904..55fb97ce9 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -247,7 +247,7 @@ BaseRemoteGDB::BaseRemoteGDB(System *_system, ThreadContext *c, size_t cacheSize system(_system), pmem(_system->physmem), context(c), gdbregs(cacheSize) { - memset(gdbregs.regs, 0, gdbregs.size); + memset(gdbregs.regs, 0, gdbregs.bytes()); } BaseRemoteGDB::~BaseRemoteGDB() @@ -610,7 +610,7 @@ BaseRemoteGDB::trap(int type) uint64_t val; size_t datalen, len; char data[GDBPacketBufLen + 1]; - char buffer[gdbregs.size * 2 + 256]; + char buffer[gdbregs.bytes() * 2 + 256]; const char *p; char command, subcmd; string var; @@ -662,15 +662,15 @@ BaseRemoteGDB::trap(int type) continue; case GDBRegR: - if (2 * gdbregs.size > sizeof(buffer)) + if (2 * gdbregs.bytes() > sizeof(buffer)) panic("buffer too small"); - mem2hex(buffer, gdbregs.regs, gdbregs.size); + mem2hex(buffer, gdbregs.regs, gdbregs.bytes()); send(buffer); continue; case GDBRegW: - p = hex2mem(gdbregs.regs, p, gdbregs.size); + p = hex2mem(gdbregs.regs, p, gdbregs.bytes()); if (p == NULL || *p != '\0') send("E01"); else { diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh index 4a1754afd..9a3201c95 100644 --- a/src/base/remote_gdb.hh +++ b/src/base/remote_gdb.hh @@ -145,6 +145,7 @@ class BaseRemoteGDB uint64_t * regs; size_t size; + size_t bytes() { return size * sizeof(uint64_t); } }; GdbRegCache gdbregs; -- cgit v1.2.3 From 5b90922ad59189f5967dc97a00bbfead062f4ba3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Nov 2006 16:15:20 -0500 Subject: Put the MIPS stacktrace into the MipsISA namespace to fit with Alpha and SPARC. --HG-- extra : convert_revision : 86f5585fe9ceb2ee30836d35384ebcddc1357c2a --- src/arch/mips/stacktrace.hh | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/arch/mips/stacktrace.hh b/src/arch/mips/stacktrace.hh index f9e092dbd..c854f63ca 100644 --- a/src/arch/mips/stacktrace.hh +++ b/src/arch/mips/stacktrace.hh @@ -37,6 +37,9 @@ class ThreadContext; class StackTrace; +namespace MipsISA +{ + class ProcessInfo { private: @@ -118,4 +121,6 @@ StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) return true; } +} + #endif // __ARCH_MIPS_STACKTRACE_HH__ -- cgit v1.2.3 From f4aa4e43c41fa688abbee9dfa5b2a35a44b2dcf5 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 9 Nov 2006 08:43:35 -0800 Subject: Factor out all of the encumbered stuff into separate SConscript files so the directories can easily be deleted. Remove the FullCPU from the ALL_CPU_LIST and only add it if it exists. --HG-- extra : convert_revision : b16f56bb92a0063803c5099732dc289fe4363768 --- src/SConscript | 88 +++++++--------------------------------------------------- 1 file changed, 10 insertions(+), 78 deletions(-) (limited to 'src') diff --git a/src/SConscript b/src/SConscript index b9664dd39..6d7783113 100644 --- a/src/SConscript +++ b/src/SConscript @@ -30,7 +30,7 @@ import os import sys -from os.path import isdir +from os.path import isfile, join as joinpath # This file defines how to build a particular configuration of M5 # based on variable settings in the 'env' build environment. @@ -146,45 +146,6 @@ base_sources = Split(''' sim/trace_context.cc ''') -# Old FullCPU sources -full_cpu_sources = Split(''' - encumbered/cpu/full/bpred.cc - encumbered/cpu/full/commit.cc - encumbered/cpu/full/cpu.cc - encumbered/cpu/full/create_vector.cc - encumbered/cpu/full/cv_spec_state.cc - encumbered/cpu/full/dd_queue.cc - encumbered/cpu/full/dep_link.cc - encumbered/cpu/full/dispatch.cc - encumbered/cpu/full/dyn_inst.cc - encumbered/cpu/full/execute.cc - encumbered/cpu/full/fetch.cc - encumbered/cpu/full/floss_reasons.cc - encumbered/cpu/full/fu_pool.cc - encumbered/cpu/full/inst_fifo.cc - encumbered/cpu/full/instpipe.cc - encumbered/cpu/full/issue.cc - encumbered/cpu/full/ls_queue.cc - encumbered/cpu/full/machine_queue.cc - encumbered/cpu/full/pipetrace.cc - encumbered/cpu/full/readyq.cc - encumbered/cpu/full/reg_info.cc - encumbered/cpu/full/rob_station.cc - encumbered/cpu/full/spec_memory.cc - encumbered/cpu/full/spec_state.cc - encumbered/cpu/full/storebuffer.cc - encumbered/cpu/full/writeback.cc - encumbered/cpu/full/iq/iq_station.cc - encumbered/cpu/full/iq/iqueue.cc - encumbered/cpu/full/iq/segmented/chain_info.cc - encumbered/cpu/full/iq/segmented/chain_wire.cc - encumbered/cpu/full/iq/segmented/iq_seg.cc - encumbered/cpu/full/iq/segmented/iq_segmented.cc - encumbered/cpu/full/iq/segmented/seg_chain.cc - encumbered/cpu/full/iq/seznec/iq_seznec.cc - encumbered/cpu/full/iq/standard/iq_standard.cc - ''') - trace_reader_sources = Split(''' cpu/trace/reader/mem_trace_reader.cc cpu/trace/reader/ibm_reader.cc @@ -229,26 +190,6 @@ if env['TARGET_ISA'] == 'alpha': kern/tru64/tru64_syscalls.cc ''') -# turbolaser encumbered sources -turbolaser_sources = Split(''' - encumbered/dev/dma.cc - encumbered/dev/etherdev.cc - encumbered/dev/scsi.cc - encumbered/dev/scsi_ctrl.cc - encumbered/dev/scsi_disk.cc - encumbered/dev/scsi_none.cc - encumbered/dev/tlaser_clock.cc - encumbered/dev/tlaser_ipi.cc - encumbered/dev/tlaser_mbox.cc - encumbered/dev/tlaser_mc146818.cc - encumbered/dev/tlaser_node.cc - encumbered/dev/tlaser_pcia.cc - encumbered/dev/tlaser_pcidev.cc - encumbered/dev/tlaser_serial.cc - encumbered/dev/turbolaser.cc - encumbered/dev/uart8530.cc - ''') - # Syscall emulation (non-full-system) sources syscall_emulation_sources = Split(''' mem/translating_port.cc @@ -262,15 +203,6 @@ syscall_emulation_sources = Split(''' # kern/tru64/tru64.cc # ''') -alpha_eio_sources = Split(''' - encumbered/eio/exolex.cc - encumbered/eio/libexo.cc - encumbered/eio/eio.cc - ''') - -if env['TARGET_ISA'] == 'alpha': - syscall_emulation_sources += alpha_eio_sources - memtest_sources = Split(''' cpu/memtest/memtest.cc ''') @@ -289,24 +221,24 @@ arch_sources = SConscript(os.path.join('arch', 'SConscript'), exports = 'env') cpu_sources = SConscript(os.path.join('cpu', 'SConscript'), exports = 'env') if env['FULL_SYSTEM']: - dev_sources = SConscript(os.path.join('dev', 'SConscript'), exports = 'env') + dev_sources = SConscript(os.path.join('dev', 'SConscript'), + exports = 'env') full_system_sources += dev_sources - kern_sources = SConscript(os.path.join('kern', 'SConscript'), exports = 'env') + kern_sources = SConscript(os.path.join('kern', 'SConscript'), + exports = 'env') full_system_sources += kern_sources -# This is outside of cpu/SConscript since the source directory isn't -# underneath 'cpu'. -if 'FullCPU' in env['CPU_MODELS']: - cpu_sources += full_cpu_sources - # Set up complete list of sources based on configuration. sources = base_sources + arch_sources + cpu_sources +# encumbered should be last because we're adding to some of the other groups +if isfile(joinpath(env['SRCDIR'], 'encumbered/SConscript')): + sources += SConscript('encumbered/SConscript', exports = 'env') + + if env['FULL_SYSTEM']: sources += full_system_sources - if env['ALPHA_TLASER']: - sources += turbolaser_sources else: sources += syscall_emulation_sources -- cgit v1.2.3 From cb172d0332ecf4ff7f6329f1172d8e1cf78767e2 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 9 Nov 2006 18:22:46 -0500 Subject: Get SPARC to the point that it starts running. Add ability to load the ROM bin files, cleanup lockstep printing a bit Since we don't have a platform yet, you need to comment out the default responder stuff in Bus.py to make it work. SConstruct: Add TARGET_ISA to the list of environment variables that end up in the build_env for python configs/common/FSConfig.py: add a simple SPARC system to being testing with, you'll need to change makeLinuxAlphaSystem to makeSparcSystem in fs.py for now src/SConscript: add a raw file object, at least until we get more info about how to compile openboot properly src/arch/sparc/system.cc: src/arch/sparc/system.hh: add parameters for ROM files (OBP/Reset/Hypervisor), a ROM, load files into ROM src/base/loader/object_file.cc: src/base/loader/object_file.hh: add option to try raw when nothing works src/cpu/exetrace.cc: cleanup lockstep printing a little bit src/cpu/m5legion_interface.h: change the instruction to be 32 bits because it is src/mem/physical.cc: fix assert that doesn't work if memory starts somewhere above 0 src/python/m5/objects/BaseCPU.py: Add if statement to choose between sparc tlbs and alpha tlbs src/python/m5/objects/System.py: Add a sparc system that sets the rom addresses correctly src/python/m5/params.py: add the ability to add Addr() together --HG-- extra : convert_revision : bbbd8a56134f2dda2728091f740e2f7119b0c4af --- src/SConscript | 1 + src/arch/sparc/system.cc | 42 ++++++++++----- src/arch/sparc/system.hh | 9 +++- src/base/loader/object_file.cc | 6 ++- src/base/loader/object_file.hh | 4 +- src/base/loader/raw_object.cc | 72 +++++++++++++++++++++++++ src/base/loader/raw_object.hh | 53 ++++++++++++++++++ src/cpu/exetrace.cc | 111 ++++++++++++++++++++++---------------- src/cpu/m5legion_interface.h | 4 +- src/mem/physical.cc | 4 +- src/python/m5/objects/BaseCPU.py | 13 ++++- src/python/m5/objects/SparcTLB.py | 14 +++++ src/python/m5/objects/System.py | 19 +++++++ src/python/m5/params.py | 5 ++ 14 files changed, 290 insertions(+), 67 deletions(-) create mode 100644 src/base/loader/raw_object.cc create mode 100644 src/base/loader/raw_object.hh create mode 100644 src/python/m5/objects/SparcTLB.py (limited to 'src') diff --git a/src/SConscript b/src/SConscript index 6d7783113..44bcb5320 100644 --- a/src/SConscript +++ b/src/SConscript @@ -74,6 +74,7 @@ base_sources = Split(''' base/loader/aout_object.cc base/loader/ecoff_object.cc base/loader/elf_object.cc + base/loader/raw_object.cc base/loader/object_file.cc base/loader/symtab.cc base/stats/events.cc diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc index 952ac2deb..4e907f002 100644 --- a/src/arch/sparc/system.cc +++ b/src/arch/sparc/system.cc @@ -42,39 +42,46 @@ using namespace BigEndianGuest; SparcSystem::SparcSystem(Params *p) - : System(p), sysTick(0) + : System(p), sysTick(0),funcRomPort(p->name + "-fport") { resetSymtab = new SymbolTable; hypervisorSymtab = new SymbolTable; openbootSymtab = new SymbolTable; + Port *rom_port; + rom_port = params()->rom->getPort("functional"); + funcRomPort.setPeer(rom_port); + rom_port->setPeer(&funcRomPort); /** * Load the boot code, and hypervisor into memory. */ // Read the reset binary - reset = createObjectFile(params()->reset_bin); + reset = createObjectFile(params()->reset_bin, true); if (reset == NULL) fatal("Could not load reset binary %s", params()->reset_bin); // Read the openboot binary - openboot = createObjectFile(params()->openboot_bin); + openboot = createObjectFile(params()->openboot_bin, true); if (openboot == NULL) fatal("Could not load openboot bianry %s", params()->openboot_bin); // Read the hypervisor binary - hypervisor = createObjectFile(params()->hypervisor_bin); + hypervisor = createObjectFile(params()->hypervisor_bin, true); if (hypervisor == NULL) fatal("Could not load hypervisor binary %s", params()->hypervisor_bin); // Load reset binary into memory - reset->loadSections(&functionalPort, SparcISA::LoadAddrMask); + reset->setTextBase(params()->reset_addr); + reset->loadSections(&funcRomPort); // Load the openboot binary - openboot->loadSections(&functionalPort, SparcISA::LoadAddrMask); + openboot->setTextBase(params()->openboot_addr); + openboot->loadSections(&funcRomPort); // Load the hypervisor binary - hypervisor->loadSections(&functionalPort, SparcISA::LoadAddrMask); + hypervisor->setTextBase(params()->hypervisor_addr); + hypervisor->loadSections(&funcRomPort); // load symbols if (!reset->loadGlobalSymbols(resetSymtab)) @@ -141,8 +148,13 @@ SparcSystem::unserialize(Checkpoint *cp, const std::string §ion) BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcSystem) SimObjectParam physmem; + SimObjectParam rom; SimpleEnumParam mem_mode; + Param reset_addr; + Param hypervisor_addr; + Param openboot_addr; + Param kernel; Param reset_bin; Param hypervisor_bin; @@ -150,8 +162,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcSystem) Param boot_cpu_frequency; Param boot_osflags; - Param system_type; - Param system_rev; Param readfile; Param init_param; @@ -160,8 +170,14 @@ END_DECLARE_SIM_OBJECT_PARAMS(SparcSystem) BEGIN_INIT_SIM_OBJECT_PARAMS(SparcSystem) INIT_PARAM(physmem, "phsyical memory"), + INIT_PARAM(rom, "ROM for boot code"), INIT_ENUM_PARAM(mem_mode, "Memory Mode, (1=atomic, 2=timing)", System::MemoryModeStrings), + + INIT_PARAM(reset_addr, "Address that reset should be loaded at"), + INIT_PARAM(hypervisor_addr, "Address that hypervisor should be loaded at"), + INIT_PARAM(openboot_addr, "Address that openboot should be loaded at"), + INIT_PARAM(kernel, "file that contains the kernel code"), INIT_PARAM(reset_bin, "file that contains the reset code"), INIT_PARAM(hypervisor_bin, "file that contains the hypervisor code"), @@ -169,8 +185,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SparcSystem) INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", "a"), - INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), - INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0) @@ -182,16 +196,18 @@ CREATE_SIM_OBJECT(SparcSystem) p->name = getInstanceName(); p->boot_cpu_frequency = boot_cpu_frequency; p->physmem = physmem; + p->rom = rom; p->mem_mode = mem_mode; p->kernel_path = kernel; + p->reset_addr = reset_addr; + p->hypervisor_addr = hypervisor_addr; + p->openboot_addr = openboot_addr; p->reset_bin = reset_bin; p->hypervisor_bin = hypervisor_bin; p->openboot_bin = openboot_bin; p->boot_osflags = boot_osflags; p->init_param = init_param; p->readfile = readfile; - p->system_type = system_type; - p->system_rev = system_rev; return new SparcSystem(p); } diff --git a/src/arch/sparc/system.hh b/src/arch/sparc/system.hh index 0b79eda38..9cf3bb568 100644 --- a/src/arch/sparc/system.hh +++ b/src/arch/sparc/system.hh @@ -45,12 +45,14 @@ class SparcSystem : public System public: struct Params : public System::Params { + PhysicalMemory *rom; + Addr reset_addr; + Addr hypervisor_addr; + Addr openboot_addr; std::string reset_bin; std::string hypervisor_bin; std::string openboot_bin; std::string boot_osflags; - uint64_t system_type; - uint64_t system_rev; }; SparcSystem(Params *p); @@ -87,6 +89,9 @@ class SparcSystem : public System /** System Tick for syncronized tick across all cpus. */ Tick sysTick; + /** functional port to ROM */ + FunctionalPort funcRomPort; + protected: const Params *params() const { return (const Params *)_params; } diff --git a/src/base/loader/object_file.cc b/src/base/loader/object_file.cc index 42c74d418..ad2cd34ba 100644 --- a/src/base/loader/object_file.cc +++ b/src/base/loader/object_file.cc @@ -45,6 +45,7 @@ #include "base/loader/ecoff_object.hh" #include "base/loader/aout_object.hh" #include "base/loader/elf_object.hh" +#include "base/loader/raw_object.hh" #include "mem/translating_port.hh" @@ -107,7 +108,7 @@ ObjectFile::close() ObjectFile * -createObjectFile(const string &fname) +createObjectFile(const string &fname, bool raw) { // open the file int fd = open(fname.c_str(), O_RDONLY); @@ -141,6 +142,9 @@ createObjectFile(const string &fname) return fileObj; } + if (raw) + return RawObject::tryFile(fname, fd, len, fileData); + // don't know what it is close(fd); munmap(fileData, len); diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh index 79fa394c6..64085185d 100644 --- a/src/base/loader/object_file.hh +++ b/src/base/loader/object_file.hh @@ -114,9 +114,11 @@ class ObjectFile size_t textSize() const { return text.size; } size_t dataSize() const { return data.size; } size_t bssSize() const { return bss.size; } + + void setTextBase(Addr a) { text.baseAddr = a; } }; -ObjectFile *createObjectFile(const std::string &fname); +ObjectFile *createObjectFile(const std::string &fname, bool raw = false); #endif // __OBJECT_FILE_HH__ diff --git a/src/base/loader/raw_object.cc b/src/base/loader/raw_object.cc new file mode 100644 index 000000000..79ddb81fe --- /dev/null +++ b/src/base/loader/raw_object.cc @@ -0,0 +1,72 @@ +/* + * Copyright (c) 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 + */ + +#include "base/loader/raw_object.hh" +#include "base/trace.hh" + +ObjectFile * +RawObject::tryFile(const std::string &fname, int fd, size_t len, uint8_t *data) +{ + return new RawObject(fname, fd, len, data, ObjectFile::UnknownArch, + ObjectFile::UnknownOpSys); +} + +RawObject::RawObject(const std::string &_filename, int _fd, size_t _len, + uint8_t *_data, Arch _arch, OpSys _opSys) + : ObjectFile(_filename, _fd, _len, _data, _arch, _opSys) +{ + text.baseAddr = 0; + text.size = len; + text.fileImage = fileData; + + data.baseAddr = 0; + data.size = 0; + data.fileImage = NULL; + + bss.baseAddr = 0; + bss.size = 0; + bss.fileImage = NULL; + + DPRINTFR(Loader, "text: 0x%x %d\ndata: 0x%x %d\nbss: 0x%x %d\n", + text.baseAddr, text.size, data.baseAddr, data.size, + bss.baseAddr, bss.size); +} + +bool +RawObject::loadGlobalSymbols(SymbolTable *symtab) +{ + return true; +} + +bool +RawObject::loadLocalSymbols(SymbolTable *symtab) +{ + return true; +} diff --git a/src/base/loader/raw_object.hh b/src/base/loader/raw_object.hh new file mode 100644 index 000000000..c7fff4e66 --- /dev/null +++ b/src/base/loader/raw_object.hh @@ -0,0 +1,53 @@ +/* + * Copyright (c) 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: Ali Saidi + */ + +#ifndef __BASE_LOADER_RAW_OBJECT_HH__ +#define __BASE_LOADER_RAW_OBJECT_HH__ + +#include "base/loader/object_file.hh" + +class RawObject: public ObjectFile +{ + protected: + RawObject(const std::string &_filename, int _fd, size_t _len, + uint8_t *_data, Arch _arch, OpSys _opSys); + public: + virtual ~RawObject() {} + + virtual bool loadGlobalSymbols(SymbolTable *symtab); + virtual bool loadLocalSymbols(SymbolTable *symtab); + + static ObjectFile *tryFile(const std::string &fname, int fd, size_t len, + uint8_t *data); +}; + + + +#endif // __BASE_LOADER_RAW_OBJECT_HH__ diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 80b144e85..881fbbd9b 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -37,6 +37,7 @@ #include #include "arch/regfile.hh" +#include "arch/utility.hh" #include "base/loader/symtab.hh" #include "cpu/base.hh" #include "cpu/exetrace.hh" @@ -231,6 +232,7 @@ Trace::InstRecord::dump(ostream &outs) // outs << endl; } +#if THE_ISA == SPARC_ISA // Compare if (flags[LEGION_LOCKSTEP]) { @@ -239,57 +241,76 @@ Trace::InstRecord::dump(ostream &outs) bool diffInst = false; bool diffRegs = false; - while (!compared) { - if (shared_data->flags == OWN_M5) { - if (shared_data->pc != PC) - diffPC = true; - if (shared_data->instruction != staticInst->machInst) - diffInst = true; - for (int i = 0; i < TheISA::NumIntRegs; i++) { - if (thread->readIntReg(i) != shared_data->intregs[i]) - diffRegs = true; - } - - if (diffPC || diffInst || diffRegs ) { - outs << "Differences found between M5 and Legion:"; - if (diffPC) - outs << " PC"; - if (diffInst) - outs << " Instruction"; - if (diffRegs) - outs << " IntRegs"; - outs << endl; - - outs << "M5 PC: " << setw(20) << "0x" << hex << PC; - outs << "Legion PC: " << setw(20) << "0x" << hex << - shared_data->pc << endl; - - - - outs << "M5 Instruction: " << staticInst->machInst << "(" - << staticInst->disassemble(PC, debugSymbolTable) - << ")" << "Legion Instruction: " << - shared_data->instruction << "(" - /*<< legionInst->disassemble(shared_data->pc, - debugSymbolTable)*/ - << ")" << endl; - + if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) { + while (!compared) { + if (shared_data->flags == OWN_M5) { + if (shared_data->pc != PC) + diffPC = true; + if (shared_data->instruction != staticInst->machInst) + diffInst = true; for (int i = 0; i < TheISA::NumIntRegs; i++) { - outs << setw(16) << "0x" << hex << thread->readIntReg(i) - << setw(16) << "0x" << hex << shared_data->intregs[i]; - if (thread->readIntReg(i) != shared_data->intregs[i]) - outs << "<--- Different"; - outs << endl; + diffRegs = true; } - } - compared = true; - shared_data->flags = OWN_LEGION; - } - } + if (diffPC || diffInst || diffRegs ) { + outs << "Differences found between M5 and Legion:"; + if (diffPC) + outs << " [PC]"; + if (diffInst) + outs << " [Instruction]"; + if (diffRegs) + outs << " [IntRegs]"; + outs << endl << endl;; + + outs << setfill(' ') << setw(15) + << "M5 PC: " << "0x"<< setw(16) << setfill('0') + << hex << PC << endl; + outs << setfill(' ') << setw(15) + << "Legion PC: " << "0x"<< setw(16) << setfill('0') << hex + << shared_data->pc << endl << endl; + + outs << setfill(' ') << setw(15) + << "M5 Inst: " << "0x"<< setw(8) + << setfill('0') << hex << staticInst->machInst + << staticInst->disassemble(PC, debugSymbolTable) + << endl; + + StaticInstPtr legionInst = StaticInst::decode(makeExtMI(shared_data->instruction, thread)); + outs << setfill(' ') << setw(15) + << " Legion Inst: " + << "0x" << setw(8) << setfill('0') << hex + << shared_data->instruction + << legionInst->disassemble(shared_data->pc, debugSymbolTable) + << endl; + + outs << endl; + static const char * regtypes[4] = {"%g", "%o", "%l", "%i"}; + for(int y = 0; y < 4; y++) + { + for(int x = 0; x < 8; x++) + { + outs << regtypes[y] << x << " " ; + outs << "0x" << hex << setw(16) << thread->readIntReg(y*8+x); + if (thread->readIntReg(y*8 + x) != shared_data->intregs[y*8+x]) + outs << " X "; + else + outs << " | "; + outs << "0x" << setw(16) << hex << shared_data->intregs[y*8+x] + << endl; + } + } + fatal("Differences found between Legion and M5\n"); + } + + compared = true; + shared_data->flags = OWN_LEGION; + } + } // while + } // if not microop } +#endif } diff --git a/src/cpu/m5legion_interface.h b/src/cpu/m5legion_interface.h index 0fa0e7279..9338d9ca0 100644 --- a/src/cpu/m5legion_interface.h +++ b/src/cpu/m5legion_interface.h @@ -30,7 +30,7 @@ #include -#define VERSION 0xA1000001 +#define VERSION 0xA1000002 #define OWN_M5 0x000000AA #define OWN_LEGION 0x00000055 @@ -41,7 +41,7 @@ typedef struct { uint32_t version; uint64_t pc; - uint64_t instruction; + uint32_t instruction; uint64_t intregs[32]; } SharedData; diff --git a/src/mem/physical.cc b/src/mem/physical.cc index 0302f7351..39eb63108 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -191,7 +191,9 @@ PhysicalMemory::checkLockedAddrList(Request *req) void PhysicalMemory::doFunctionalAccess(PacketPtr pkt) { - assert(pkt->getAddr() + pkt->getSize() <= params()->addrRange.size()); + assert(pkt->getAddr() + pkt->getSize() > params()->addrRange.start && + pkt->getAddr() + pkt->getSize() <= params()->addrRange.start + + params()->addrRange.size()); if (pkt->isRead()) { if (pkt->req->isLocked()) { diff --git a/src/python/m5/objects/BaseCPU.py b/src/python/m5/objects/BaseCPU.py index 4e34e8a4e..b6e05627d 100644 --- a/src/python/m5/objects/BaseCPU.py +++ b/src/python/m5/objects/BaseCPU.py @@ -3,7 +3,9 @@ from m5.params import * from m5.proxy import * from m5 import build_env from AlphaTLB import AlphaDTB, AlphaITB +from SparcTLB import SparcDTB, SparcITB from Bus import Bus +import sys class BaseCPU(SimObject): type = 'BaseCPU' @@ -13,8 +15,15 @@ class BaseCPU(SimObject): cpu_id = Param.Int("CPU identifier") if build_env['FULL_SYSTEM']: - dtb = Param.AlphaDTB(AlphaDTB(), "Data TLB") - itb = Param.AlphaITB(AlphaITB(), "Instruction TLB") + if build_env['TARGET_ISA'] == 'sparc': + dtb = Param.SparcDTB(SparcDTB(), "Data TLB") + itb = Param.SparcITB(SparcITB(), "Instruction TLB") + elif build_env['TARGET_ISA'] == 'alpha': + dtb = Param.AlphaDTB(AlphaDTB(), "Data TLB") + itb = Param.AlphaITB(AlphaITB(), "Instruction TLB") + else: + print "Unknown architecture, can't pick TLBs" + sys.exit(1) else: workload = VectorParam.Process("processes to run") diff --git a/src/python/m5/objects/SparcTLB.py b/src/python/m5/objects/SparcTLB.py new file mode 100644 index 000000000..de732e8de --- /dev/null +++ b/src/python/m5/objects/SparcTLB.py @@ -0,0 +1,14 @@ +from m5.SimObject import SimObject +from m5.params import * +class SparcTLB(SimObject): + type = 'SparcTLB' + abstract = True + size = Param.Int("TLB size") + +class SparcDTB(SparcTLB): + type = 'SparcDTB' + size = 64 + +class SparcITB(SparcTLB): + type = 'SparcITB' + size = 48 diff --git a/src/python/m5/objects/System.py b/src/python/m5/objects/System.py index e7dd1bc60..908c3d4ad 100644 --- a/src/python/m5/objects/System.py +++ b/src/python/m5/objects/System.py @@ -2,6 +2,7 @@ from m5.SimObject import SimObject from m5.params import * from m5.proxy import * from m5 import build_env +from PhysicalMemory import * class MemoryMode(Enum): vals = ['invalid', 'atomic', 'timing'] @@ -24,3 +25,21 @@ class AlphaSystem(System): pal = Param.String("file that contains palcode") system_type = Param.UInt64("Type of system we are emulating") system_rev = Param.UInt64("Revision of system we are emulating") + +class SparcSystem(System): + type = 'SparcSystem' + _rom_base = 0xfff0000000 + # ROM for OBP/Reset/Hypervisor + rom = Param.PhysicalMemory(PhysicalMemory(range = AddrRange(_rom_base, size = '8MB')), + "Memory to hold the ROM data") + + reset_addr = Param.Addr(_rom_base, "Address to load ROM at") + hypervisor_addr = Param.Addr(Addr('64kB') + _rom_base, + "Address to load hypervisor at") + openboot_addr = Param.Addr(Addr('512kB') + _rom_base, + "Address to load openboot at") + + reset_bin = Param.String("file that contains the reset code") + hypervisor_bin = Param.String("file that contains the hypervisor code") + openboot_bin = Param.String("file that contains the openboot code") + diff --git a/src/python/m5/params.py b/src/python/m5/params.py index 93d784181..4b5953bcb 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -369,6 +369,11 @@ class Addr(CheckedInt): except TypeError: self.value = long(value) self._check() + def __add__(self, other): + if isinstance(other, Addr): + return self.value + other.value + else: + return self.value + other class MetaRange(type): -- cgit v1.2.3 From 50462c15aafc4ea076fb4bce69abe9cc32c33788 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 9 Nov 2006 19:24:35 -0500 Subject: Fix a couple uninitialized variables. --HG-- extra : convert_revision : d17d28a9520524e5f56bd79beb9b2be6ce76a22f --- src/arch/sparc/faults.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index e895c02db..57ee040f1 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -493,21 +493,22 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv) void getREDVector(Addr & PC, Addr & NPC) { + //XXX The following constant might belong in a header file. const Addr RSTVAddr = 0xFFFFFFFFF0000000ULL; PC = RSTVAddr | 0xA0; NPC = PC + sizeof(MachInst); } -void getHyperVector(Addr & PC, Addr & NPC, MiscReg TT) +void getHyperVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT) { - Addr HTBA ; + Addr HTBA = tc->readMiscReg(MISCREG_HTBA); PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14)); NPC = PC + sizeof(MachInst); } -void getPrivVector(Addr & PC, Addr & NPC, MiscReg TT, MiscReg TL) +void getPrivVector(ThreadContext * tc, Addr & PC, Addr & NPC, MiscReg TT, MiscReg TL) { - Addr TBA ; + Addr TBA = tc->readMiscReg(MISCREG_TBA); PC = (TBA & ~mask(15)) | (TL > 1 ? (1 << 14) : 0) | ((TT << 5) & mask(14)); @@ -556,17 +557,17 @@ void SparcFaultBase::invoke(ThreadContext * tc) { //guest_watchdog fault doNormalFault(tc, trapType(), true); - getHyperVector(PC, NPC, 2); + getHyperVector(tc, PC, NPC, 2); } else if(level == Hyperprivileged) { doNormalFault(tc, trapType(), true); - getHyperVector(PC, NPC, trapType()); + getHyperVector(tc, PC, NPC, trapType()); } else { doNormalFault(tc, trapType(), false); - getPrivVector(PC, NPC, trapType(), TL+1); + getPrivVector(tc, PC, NPC, trapType(), TL+1); } tc->setPC(PC); -- cgit v1.2.3 From 232c3f1b270aa04b924442bb6520c65c5a1414e1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 9 Nov 2006 21:30:48 -0500 Subject: Moved the Alpha MiscRegFile into it's own file, and got rid of the Alpha specific DepTag constants. --HG-- extra : convert_revision : e4af5e2fb2a6953f8837ad9bda309b7d6fa7abfb --- src/arch/alpha/SConscript | 1 + src/arch/alpha/ev5.cc | 2 +- src/arch/alpha/isa/fp.isa | 2 +- src/arch/alpha/isa/main.isa | 11 +-- src/arch/alpha/isa_traits.hh | 8 +-- src/arch/alpha/locked_mem.hh | 12 ++-- src/arch/alpha/miscregfile.cc | 161 ++++++++++++++++++++++++++++++++++++++++++ src/arch/alpha/miscregfile.hh | 118 +++++++++++++++++++++++++++++++ src/arch/alpha/regfile.hh | 56 +-------------- src/arch/sparc/miscregfile.hh | 83 ++++++++++------------ src/kern/tru64/tru64.hh | 6 +- 11 files changed, 335 insertions(+), 125 deletions(-) create mode 100644 src/arch/alpha/miscregfile.cc create mode 100644 src/arch/alpha/miscregfile.hh (limited to 'src') diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript index 3947ec23a..d9c9765a1 100644 --- a/src/arch/alpha/SConscript +++ b/src/arch/alpha/SConscript @@ -49,6 +49,7 @@ Import('env') base_sources = Split(''' faults.cc isa_traits.cc + miscregfile.cc ''') # Full-system sources diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 59f9d2fb5..3d71fbda5 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -557,7 +557,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) void AlphaISA::copyIprs(ThreadContext *src, ThreadContext *dest) { - for (int i = IPR_Base_DepTag; i < NumInternalProcRegs; ++i) { + for (int i = 0; i < NumInternalProcRegs; ++i) { dest->setMiscReg(i, src->readMiscReg(i)); } } diff --git a/src/arch/alpha/isa/fp.isa b/src/arch/alpha/isa/fp.isa index 103f85775..3b5575f62 100644 --- a/src/arch/alpha/isa/fp.isa +++ b/src/arch/alpha/isa/fp.isa @@ -229,7 +229,7 @@ def template FloatingPointExecute {{ %(code)s; } else { fesetround(getC99RoundingMode( - xc->readMiscReg(AlphaISA::Fpcr_DepTag))); + xc->readMiscReg(AlphaISA::MISCREG_FPCR))); %(code)s; fesetround(FE_TONEAREST); } diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index 06d3e8243..6e65cf9d3 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -184,9 +184,9 @@ def operands {{ 'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3), 'Mem': ('Mem', 'uq', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), 'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4), - 'Runiq': ('ControlReg', 'uq', 'AlphaISA::Uniq_DepTag', None, 1), - 'FPCR': ('ControlReg', 'uq', 'AlphaISA::Fpcr_DepTag', None, 1), - 'IntrFlag': ('ControlReg', 'uq', 'AlphaISA::Intr_Flag_DepTag', None, 1), + 'Runiq': ('ControlReg', 'uq', 'MISCREG_UNIQ', None, 1), + 'FPCR': ('ControlReg', 'uq', 'MISCREG_FPCR', None, 1), + 'IntrFlag': ('ControlReg', 'uq', 'MISCREG_INTR', None, 1), # The next two are hacks for non-full-system call-pal emulation 'R0': ('IntReg', 'uq', '0', None, 1), 'R16': ('IntReg', 'uq', '16', None, 1), @@ -216,11 +216,6 @@ output header {{ /// live here and not in the AlphaISA namespace. enum DependenceTags { FP_Base_DepTag = AlphaISA::FP_Base_DepTag, - Fpcr_DepTag = AlphaISA::Fpcr_DepTag, - Uniq_DepTag = AlphaISA::Uniq_DepTag, - Lock_Flag_DepTag = AlphaISA::Lock_Flag_DepTag, - Lock_Addr_DepTag = AlphaISA::Lock_Addr_DepTag, - IPR_Base_DepTag = AlphaISA::IPR_Base_DepTag }; /// Constructor. diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh index a919a4a1f..3759b022b 100644 --- a/src/arch/alpha/isa_traits.hh +++ b/src/arch/alpha/isa_traits.hh @@ -50,13 +50,7 @@ namespace AlphaISA // 0..31 are the integer regs 0..31 // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag) FP_Base_DepTag = 40, - Ctrl_Base_DepTag = 72, - Fpcr_DepTag = 72, // floating point control register - Uniq_DepTag = 73, - Lock_Flag_DepTag = 74, - Lock_Addr_DepTag = 75, - Intr_Flag_DepTag = 76, - IPR_Base_DepTag = 77 + Ctrl_Base_DepTag = 72 }; StaticInstPtr decodeInst(ExtMachInst); diff --git a/src/arch/alpha/locked_mem.hh b/src/arch/alpha/locked_mem.hh index 368ea2895..52fe24173 100644 --- a/src/arch/alpha/locked_mem.hh +++ b/src/arch/alpha/locked_mem.hh @@ -37,7 +37,7 @@ * ISA-specific helper functions for locked memory accesses. */ -#include "arch/isa_traits.hh" +#include "arch/alpha/miscregfile.hh" #include "base/misc.hh" #include "mem/request.hh" @@ -48,8 +48,8 @@ template inline void handleLockedRead(XC *xc, Request *req) { - xc->setMiscReg(Lock_Addr_DepTag, req->getPaddr() & ~0xf); - xc->setMiscReg(Lock_Flag_DepTag, true); + xc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr() & ~0xf); + xc->setMiscReg(MISCREG_LOCKFLAG, true); } @@ -63,13 +63,13 @@ handleLockedWrite(XC *xc, Request *req) req->setScResult(2); } else { // standard store conditional - bool lock_flag = xc->readMiscReg(Lock_Flag_DepTag); - Addr lock_addr = xc->readMiscReg(Lock_Addr_DepTag); + bool lock_flag = xc->readMiscReg(MISCREG_LOCKFLAG); + Addr lock_addr = xc->readMiscReg(MISCREG_LOCKADDR); if (!lock_flag || (req->getPaddr() & ~0xf) != lock_addr) { // Lock flag not set or addr mismatch in CPU; // don't even bother sending to memory system req->setScResult(0); - xc->setMiscReg(Lock_Flag_DepTag, false); + xc->setMiscReg(MISCREG_LOCKFLAG, false); // the rest of this code is not architectural; // it's just a debugging aid to help detect // livelock by warning on long sequences of failed diff --git a/src/arch/alpha/miscregfile.cc b/src/arch/alpha/miscregfile.cc new file mode 100644 index 000000000..4cf57a690 --- /dev/null +++ b/src/arch/alpha/miscregfile.cc @@ -0,0 +1,161 @@ +/* + * 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: Steve Reinhardt + * Gabe Black + * Kevin Lim + */ + +#include "arch/alpha/miscregfile.hh" +#include "base/misc.hh" + +namespace AlphaISA +{ + + void + MiscRegFile::serialize(std::ostream &os) + { + SERIALIZE_SCALAR(fpcr); + SERIALIZE_SCALAR(uniq); + SERIALIZE_SCALAR(lock_flag); + SERIALIZE_SCALAR(lock_addr); +#if FULL_SYSTEM + SERIALIZE_ARRAY(ipr, NumInternalProcRegs); +#endif + } + + void + MiscRegFile::unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_SCALAR(fpcr); + UNSERIALIZE_SCALAR(uniq); + UNSERIALIZE_SCALAR(lock_flag); + UNSERIALIZE_SCALAR(lock_addr); +#if FULL_SYSTEM + UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs); +#endif + } + + MiscReg + MiscRegFile::readReg(int misc_reg) + { + 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 + default: + assert(misc_reg < NumInternalProcRegs); + return ipr[misc_reg]; +#else + default: + panic("Attempt to read an invalid misc register!"); + return 0; +#endif + } + } + + MiscReg + MiscRegFile::readRegWithEffect(int misc_reg, ThreadContext *tc) + { +#if FULL_SYSTEM + return readIpr(misc_reg, tc); +#else + panic("No faulting misc regs in SE mode!"); + return 0; +#endif + } + + void + MiscRegFile::setReg(int misc_reg, const MiscReg &val) + { + switch(misc_reg) { + case MISCREG_FPCR: + fpcr = val; + return; + case MISCREG_UNIQ: + uniq = val; + return; + case MISCREG_LOCKFLAG: + lock_flag = val; + return; + case MISCREG_LOCKADDR: + lock_addr = val; + return; + case MISCREG_INTR: + intr_flag = val; + return; +#if FULL_SYSTEM + default: + assert(misc_reg < NumInternalProcRegs); + ipr[misc_reg] = val; + return; +#else + default: + panic("Attempt to write to an invalid misc register!"); +#endif + } + } + + void + MiscRegFile::setRegWithEffect(int misc_reg, const MiscReg &val, + ThreadContext *tc) + { +#if FULL_SYSTEM + switch(misc_reg) { + case MISCREG_FPCR: + fpcr = val; + return; + case MISCREG_UNIQ: + uniq = val; + return; + case MISCREG_LOCKFLAG: + lock_flag = val; + return; + case MISCREG_LOCKADDR: + lock_addr = val; + return; + case MISCREG_INTR: + intr_flag = val; + return; + default: + return setIpr(misc_reg, val, tc); + } +#else + //panic("No registers with side effects in SE mode!"); + return; +#endif + } + +} diff --git a/src/arch/alpha/miscregfile.hh b/src/arch/alpha/miscregfile.hh new file mode 100644 index 000000000..85cb054bb --- /dev/null +++ b/src/arch/alpha/miscregfile.hh @@ -0,0 +1,118 @@ +/* + * 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: Steve Reinhardt + * Gabe Black + */ + +#ifndef __ARCH_ALPHA_MISCREGFILE_HH__ +#define __ARCH_ALPHA_MISCREGFILE_HH__ + +#include "arch/alpha/ipr.hh" +#include "arch/alpha/types.hh" +#include "config/full_system.hh" +#include "sim/host.hh" +#include "sim/serialize.hh" + +#include + +class Checkpoint; +class ThreadContext; + +namespace AlphaISA +{ + enum MiscRegIndex + { + MISCREG_FPCR = NumInternalProcRegs, + MISCREG_UNIQ, + MISCREG_LOCKFLAG, + MISCREG_LOCKADDR, + MISCREG_INTR + }; + + class MiscRegFile { + protected: + uint64_t fpcr; // floating point condition codes + uint64_t uniq; // process-unique register + bool lock_flag; // lock flag for LL/SC + Addr lock_addr; // lock address for LL/SC + int intr_flag; + + public: + MiscRegFile() + { +#if FULL_SYSTEM + initializeIprTable(); +#endif + } + + MiscReg readReg(int misc_reg); + + MiscReg readRegWithEffect(int misc_reg, ThreadContext *tc); + + //These functions should be removed once the simplescalar cpu model + //has been replaced. + int getInstAsid(); + int getDataAsid(); + + void setReg(int misc_reg, const MiscReg &val); + + void setRegWithEffect(int misc_reg, const MiscReg &val, + ThreadContext *tc); + + void clear() + { + fpcr = uniq = 0; + lock_flag = 0; + lock_addr = 0; + intr_flag = 0; + } + + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); +#if FULL_SYSTEM + protected: + typedef uint64_t InternalProcReg; + + InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs + + private: + InternalProcReg readIpr(int idx, ThreadContext *tc); + + void setIpr(int idx, InternalProcReg val, ThreadContext *tc); +#endif + friend class RegFile; + }; + +#if FULL_SYSTEM + void copyIprs(ThreadContext *src, ThreadContext *dest); +#endif + +} + +#endif diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index e806adbcb..af28f6c6f 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -33,6 +33,7 @@ #include "arch/alpha/isa_traits.hh" #include "arch/alpha/ipr.hh" +#include "arch/alpha/miscregfile.hh" #include "arch/alpha/types.hh" #include "sim/faults.hh" @@ -104,61 +105,6 @@ namespace AlphaISA { bzero(d, sizeof(d)); } }; - class MiscRegFile { - protected: - uint64_t fpcr; // floating point condition codes - uint64_t uniq; // process-unique register - bool lock_flag; // lock flag for LL/SC - Addr lock_addr; // lock address for LL/SC - int intr_flag; - - public: - MiscRegFile() - { -#if FULL_SYSTEM - initializeIprTable(); -#endif - } - - MiscReg readReg(int misc_reg); - - MiscReg readRegWithEffect(int misc_reg, ThreadContext *tc); - - //These functions should be removed once the simplescalar cpu model - //has been replaced. - int getInstAsid(); - int getDataAsid(); - - void setReg(int misc_reg, const MiscReg &val); - - void setRegWithEffect(int misc_reg, const MiscReg &val, - ThreadContext *tc); - - void clear() - { - fpcr = uniq = 0; - lock_flag = 0; - lock_addr = 0; - intr_flag = 0; - } - - void serialize(std::ostream &os); - - void unserialize(Checkpoint *cp, const std::string §ion); -#if FULL_SYSTEM - protected: - typedef uint64_t InternalProcReg; - - InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs - - private: - InternalProcReg readIpr(int idx, ThreadContext *tc); - - void setIpr(int idx, InternalProcReg val, ThreadContext *tc); -#endif - friend class RegFile; - }; - class RegFile { protected: diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index 0e424dbd2..6d624787d 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -46,59 +46,54 @@ namespace SparcISA //These functions map register indices to names std::string getMiscRegName(RegIndex); - const int AsrStart = 0; - const int PrStart = 32; - const int HprStart = 64; - const int MiscStart = 96; - enum MiscRegIndex { /** Ancillary State Registers */ - MISCREG_Y = AsrStart + 0, - MISCREG_CCR = AsrStart + 2, - MISCREG_ASI = AsrStart + 3, - MISCREG_TICK = AsrStart + 4, - MISCREG_FPRS = AsrStart + 6, - MISCREG_PCR = AsrStart + 16, - MISCREG_PIC = AsrStart + 17, - MISCREG_GSR = AsrStart + 19, - MISCREG_SOFTINT_SET = AsrStart + 20, - MISCREG_SOFTINT_CLR = AsrStart + 21, - MISCREG_SOFTINT = AsrStart + 22, - MISCREG_TICK_CMPR = AsrStart + 23, - MISCREG_STICK = AsrStart + 24, - MISCREG_STICK_CMPR = AsrStart + 25, + MISCREG_Y, + MISCREG_CCR, + MISCREG_ASI, + MISCREG_TICK, + MISCREG_FPRS, + MISCREG_PCR, + MISCREG_PIC, + MISCREG_GSR, + MISCREG_SOFTINT_SET, + MISCREG_SOFTINT_CLR, + MISCREG_SOFTINT, + MISCREG_TICK_CMPR, + MISCREG_STICK, + MISCREG_STICK_CMPR, /** Privilged Registers */ - MISCREG_TPC = PrStart + 0, - MISCREG_TNPC = PrStart + 1, - MISCREG_TSTATE = PrStart + 2, - MISCREG_TT = PrStart + 3, - MISCREG_PRIVTICK = PrStart + 4, - MISCREG_TBA = PrStart + 5, - MISCREG_PSTATE = PrStart + 6, - MISCREG_TL = PrStart + 7, - MISCREG_PIL = PrStart + 8, - MISCREG_CWP = PrStart + 9, - MISCREG_CANSAVE = PrStart + 10, - MISCREG_CANRESTORE = PrStart + 11, - MISCREG_CLEANWIN = PrStart + 12, - MISCREG_OTHERWIN = PrStart + 13, - MISCREG_WSTATE = PrStart + 14, - MISCREG_GL = PrStart + 16, + MISCREG_TPC, + MISCREG_TNPC, + MISCREG_TSTATE, + MISCREG_TT, + MISCREG_PRIVTICK, + MISCREG_TBA, + MISCREG_PSTATE, + MISCREG_TL, + MISCREG_PIL, + MISCREG_CWP, + MISCREG_CANSAVE, + MISCREG_CANRESTORE, + MISCREG_CLEANWIN, + MISCREG_OTHERWIN, + MISCREG_WSTATE, + MISCREG_GL, /** Hyper privileged registers */ - MISCREG_HPSTATE = HprStart + 0, - MISCREG_HTSTATE = HprStart + 1, - MISCREG_HINTP = HprStart + 3, - MISCREG_HTBA = HprStart + 5, - MISCREG_HVER = HprStart + 6, - MISCREG_STRAND_STS_REG = HprStart + 16, - MISCREG_HSTICK_CMPR = HprStart + 31, + MISCREG_HPSTATE, + MISCREG_HTSTATE, + MISCREG_HINTP, + MISCREG_HTBA, + MISCREG_HVER, + MISCREG_STRAND_STS_REG, + MISCREG_HSTICK_CMPR, /** Floating Point Status Register */ - MISCREG_FSR = MiscStart + 0 - + MISCREG_FSR, + NumMiscRegs }; // The control registers, broken out into fields diff --git a/src/kern/tru64/tru64.hh b/src/kern/tru64/tru64.hh index 6d6d0d96d..82db34bf6 100644 --- a/src/kern/tru64/tru64.hh +++ b/src/kern/tru64/tru64.hh @@ -511,7 +511,7 @@ class Tru64 : public OperatingSystem tc->setFloatRegBits(i, htog(sc->sc_fpregs[i])); } - tc->setMiscReg(TheISA::Fpcr_DepTag, htog(sc->sc_fpcr)); + tc->setMiscReg(AlphaISA::MISCREG_FPCR, htog(sc->sc_fpcr)); return 0; } @@ -653,7 +653,7 @@ class Tru64 : public OperatingSystem ssp->nxm_sysevent = htog(0); if (i == 0) { - uint64_t uniq = tc->readMiscReg(TheISA::Uniq_DepTag); + uint64_t uniq = tc->readMiscReg(AlphaISA::MISCREG_UNIQ); ssp->nxm_u.pth_id = htog(uniq + gtoh(attrp->nxm_uniq_offset)); ssp->nxm_u.nxm_active = htog(uniq | 1); } @@ -693,7 +693,7 @@ class Tru64 : public OperatingSystem tc->setIntReg(TheISA::ArgumentReg0, gtoh(attrp->registers.a0)); tc->setIntReg(27/*t12*/, gtoh(attrp->registers.pc)); tc->setIntReg(TheISA::StackPointerReg, gtoh(attrp->registers.sp)); - tc->setMiscReg(TheISA::Uniq_DepTag, uniq_val); + tc->setMiscReg(AlphaISA::MISCREG_UNIQ, uniq_val); tc->setPC(gtoh(attrp->registers.pc)); tc->setNextPC(gtoh(attrp->registers.pc) + sizeof(TheISA::MachInst)); -- cgit v1.2.3 From 4aea5deccb948035459583d811837cb6affd1c07 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Nov 2006 04:02:39 -0500 Subject: Fix up instructions to read and write control registers, and got rid of the control register fields which won't work on a big endian host. --HG-- extra : convert_revision : 1b518873b6e1a073b58cbe27642537d5ae3a604d --- src/arch/sparc/isa/decoder.isa | 197 ++++++++++++++++++++++++++++---- src/arch/sparc/isa/formats/priv.isa | 24 +++- src/arch/sparc/isa/includes.isa | 1 + src/arch/sparc/isa/operands.isa | 50 +++++--- src/arch/sparc/miscregfile.cc | 41 ++++--- src/arch/sparc/miscregfile.hh | 222 ++++-------------------------------- 6 files changed, 271 insertions(+), 264 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index a5f43367d..4f3ea7810 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -346,22 +346,93 @@ decode OP default Unknown::unknown() 0x0: sra({{Rd = Rs1.sw >> (I ? SHCNT32 : Rs2<4:0>);}}); 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}}); } - // XXX might want a format rdipr thing here 0x28: decode RS1 { - 0xF: decode I { + 0x00: NoPriv::rdy({{Rd = Y;}}); + //1 should cause an illegal instruction exception + 0x02: NoPriv::rdccr({{Rd = Ccr;}}); + 0x03: NoPriv::rdasi({{Rd = Asi;}}); + 0x04: PrivCheck::rdtick({{Rd = Tick;}}, {{Tick<63:>}}); + 0x05: NoPriv::rdpc({{ + if(Pstate<3:>) + Rd = (xc->readPC())<31:0>; + else + Rd = xc->readPC();}}); + 0x06: NoPriv::rdfprs({{ + //Wait for all fpops to finish. + Rd = Fprs; + }}); + //7-14 should cause an illegal instruction exception + 0x0F: decode I { 0x0: Nop::stbar({{/*stuff*/}}); 0x1: Nop::membar({{/*stuff*/}}); } - default: rdasr({{ - Rd = xc->readMiscRegWithEffect(RS1 + AsrStart); + 0x10: Priv::rdpcr({{Rd = Pcr;}}); + 0x11: PrivCheck::rdpic({{Rd = Pic;}}, {{Pcr<0:>}}); + //0x12 should cause an illegal instruction exception + 0x13: NoPriv::rdgsr({{ + if(Fprs<2:> == 0 || Pstate<4:> == 0) + Rd = Gsr; + else + fault = new FpDisabled; }}); + //0x14-0x15 should cause an illegal instruction exception + 0x16: Priv::rdsoftint({{Rd = Softint;}}); + 0x17: Priv::rdtick_cmpr({{Rd = TickCmpr;}}); + 0x18: PrivCheck::rdstick({{Rd = Stick}}, {{Stick<63:>}}); + 0x19: Priv::rdstick_cmpr({{Rd = StickCmpr;}}); + //0x1A-0x1F should cause an illegal instruction exception + } + 0x29: decode RS1 { + 0x00: HPriv::rdhprhpstate({{Rd = Hpstate;}}); + 0x01: HPriv::rdhprhtstate({{ + if(Tl == 0) + return new IllegalInstruction; + Rd = Htstate; + }}); + //0x02 should cause an illegal instruction exception + 0x03: HPriv::rdhprhintp({{Rd = Hintp;}}); + //0x04 should cause an illegal instruction exception + 0x05: HPriv::rdhprhtba({{Rd = Htba;}}); + 0x06: HPriv::rdhprhver({{Rd = Hver;}}); + //0x07-0x1E should cause an illegal instruction exception + 0x1F: HPriv::rdhprhstick_cmpr({{Rd = HstickCmpr;}}); + } + 0x2A: decode RS1 { + 0x00: Priv::rdprtpc({{ + if(Tl == 0) + return new IllegalInstruction; + Rd = Tpc; + }}); + 0x01: Priv::rdprtnpc({{ + if(Tl == 0) + return new IllegalInstruction; + Rd = Tnpc; + }}); + 0x02: Priv::rdprtstate({{ + if(Tl == 0) + return new IllegalInstruction; + Rd = Tstate; + }}); + 0x03: Priv::rdprtt({{ + if(Tl == 0) + return new IllegalInstruction; + Rd = Tt; + }}); + 0x04: Priv::rdprtick({{Rd = Tick;}}); + 0x05: Priv::rdprtba({{Rd = Tba;}}); + 0x06: Priv::rdprpstate({{Rd = Pstate;}}); + 0x07: Priv::rdprtl({{Rd = Tl;}}); + 0x08: Priv::rdprpil({{Rd = Pil;}}); + 0x09: Priv::rdprcwp({{Rd = Cwp;}}); + 0x0A: Priv::rdprcansave({{Rd = Cansave;}}); + 0x0B: Priv::rdprcanrestore({{Rd = Canrestore;}}); + 0x0C: Priv::rdprcleanwin({{Rd = Cleanwin;}}); + 0x0D: Priv::rdprotherwin({{Rd = Otherwin;}}); + 0x0E: Priv::rdprwstate({{Rd = Wstate;}}); + //0x0F should cause an illegal instruction exception + 0x10: Priv::rdprgl({{Rd = Gl;}}); + //0x11-0x1F should cause an illegal instruction exception } - 0x29: HPriv::rdhpr({{ - Rd = xc->readMiscRegWithEffect(RS1 + HprStart); - }}); - 0x2A: Priv::rdpr({{ - Rd = xc->readMiscRegWithEffect(RS1 + PrStart); - }}); 0x2B: BasicOperate::flushw({{ if(NWindows - 2 - Cansave == 0) { @@ -417,9 +488,35 @@ decode OP default Unknown::unknown() 0x6: movrg({{Rd = (Rs1.sdw > 0) ? Rs2_or_imm10 : Rd;}}); 0x7: movrge({{Rd = (Rs1.sdw >= 0) ? Rs2_or_imm10 : Rd;}}); } - 0x30: wrasr({{ - xc->setMiscRegWithEffect(RD + AsrStart, Rs1 ^ Rs2_or_imm13); - }}); + 0x30: decode RD { + 0x00: NoPriv::wry({{Y = Rs1 ^ Rs2_or_imm13;}}); + //0x01 should cause an illegal instruction exception + 0x02: NoPriv::wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}}); + 0x03: NoPriv::wrasi({{Ccr = Rs1 ^ Rs2_or_imm13;}}); + //0x04-0x05 should cause an illegal instruction exception + 0x06: NoPriv::wrfprs({{Fprs = Rs1 ^ Rs2_or_imm13;}}); + //0x07-0x0E should cause an illegal instruction exception + 0x0F: Trap::softreset({{fault = new SoftwareInitiatedReset;}}); + 0x10: Priv::wrpcr({{Pcr = Rs1 ^ Rs2_or_imm13;}}); + 0x11: PrivCheck::wrpic({{Pic = Rs1 ^ Rs2_or_imm13;}}, {{Pcr<0:>}}); + //0x12 should cause an illegal instruction exception + 0x13: NoPriv::wrgsr({{ + if(Fprs<2:> == 0 || Pstate<4:> == 0) + return new FpDisabled; + Gsr = Rs1 ^ Rs2_or_imm13; + }}); + 0x14: Priv::wrsoftint_set({{SoftintSet = Rs1 ^ Rs2_or_imm13;}}); + 0x15: Priv::wrsoftint_clr({{SoftintClr = Rs1 ^ Rs2_or_imm13;}}); + 0x16: Priv::wrsoftint({{Softint = Rs1 ^ Rs2_or_imm13;}}); + 0x17: Priv::wrtick_cmpr({{TickCmpr = Rs1 ^ Rs2_or_imm13;}}); + 0x18: NoPriv::wrstick({{ + if(!Hpstate<2:>) + return new IllegalInstruction; + Stick = Rs1 ^ Rs2_or_imm13; + }}); + 0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}}); + //0x1A-0x1F should cause an illegal instruction exception + } 0x31: decode FCN { 0x0: Priv::saved({{ assert(Cansave < NWindows - 2); @@ -440,16 +537,70 @@ decode OP default Unknown::unknown() Otherwin = Otherwin - 1; }}); } - 0x32: Priv::wrpr({{ - // XXX Need to protect with format that traps non-priv - // access - xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13); - }}); - 0x33: HPriv::wrhpr({{ - // XXX Need to protect with format that traps non-priv/priv - // access - xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13); - }}); + 0x32: decode RD { + 0x00: Priv::wrprtpc({{ + if(Tl == 0) + return new IllegalInstruction; + else + Tpc = Rs1 ^ Rs2_or_imm13; + }}); + 0x01: Priv::wrprtnpc({{ + if(Tl == 0) + return new IllegalInstruction; + else + Tnpc = Rs1 ^ Rs2_or_imm13; + }}); + 0x02: Priv::wrprtstate({{ + if(Tl == 0) + return new IllegalInstruction; + else + Tstate = Rs1 ^ Rs2_or_imm13; + }}); + 0x03: Priv::wrprtt({{ + if(Tl == 0) + return new IllegalInstruction; + else + Tt = Rs1 ^ Rs2_or_imm13; + }}); + 0x04: HPriv::wrprtick({{Tick = Rs1 ^ Rs2_or_imm13;}}); + 0x05: Priv::wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}}); + 0x06: Priv::wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}}); + 0x07: Priv::wrprtl({{ + if(Pstate<2:> && !Hpstate<2:>) + Tl = std::min(Rs1 ^ Rs2_or_imm13, MaxPTL); + else + Tl = std::min(Rs1 ^ Rs2_or_imm13, MaxTL); + }}); + 0x08: Priv::wrprpil({{Pil = Rs1 ^ Rs2_or_imm13;}}); + 0x09: Priv::wrprcwp({{Cwp = Rs1 ^ Rs2_or_imm13;}}); + 0x0A: Priv::wrprcansave({{Cansave = Rs1 ^ Rs2_or_imm13;}}); + 0x0B: Priv::wrprcanrestore({{Canrestore = Rs1 ^ Rs2_or_imm13;}}); + 0x0C: Priv::wrprcleanwin({{Cleanwin = Rs1 ^ Rs2_or_imm13;}}); + 0x0D: Priv::wrprotherwin({{Otherwin = Rs1 ^ Rs2_or_imm13;}}); + 0x0E: Priv::wrprwstate({{Wstate = Rs1 ^ Rs2_or_imm13;}}); + //0x0F should cause an illegal instruction exception + 0x10: Priv::wrprgl({{ + if(Pstate<2:> && !Hpstate<2:>) + Gl = std::min(Rs1 ^ Rs2_or_imm13, MaxPGL); + else + Gl = std::min(Rs1 ^ Rs2_or_imm13, MaxGL); + }}); + //0x11-0x1F should cause an illegal instruction exception + } + 0x33: decode RD { + 0x00: HPriv::wrhprhpstate({{Hpstate = Rs1 ^ Rs2_or_imm13;}}); + 0x01: HPriv::wrhprhtstate({{ + if(Tl == 0) + return new IllegalInstruction; + Htstate = Rs1 ^ Rs2_or_imm13; + }}); + //0x02 should cause an illegal instruction exception + 0x03: HPriv::wrhprhintp({{Hintp = Rs1 ^ Rs2_or_imm13;}}); + //0x04 should cause an illegal instruction exception + 0x05: HPriv::wrhprhtba({{Htba = Rs1 ^ Rs2_or_imm13;}}); + //0x06-0x01D should cause an illegal instruction exception + 0x1F: HPriv::wrhprhstick_cmpr({{HstickCmpr = Rs1 ^ Rs2_or_imm13;}}); + } 0x34: decode OPF{ format BasicOperate{ 0x01: fmovs({{ diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa index 04c67d332..55bf968f4 100644 --- a/src/arch/sparc/isa/formats/priv.isa +++ b/src/arch/sparc/isa/formats/priv.isa @@ -119,18 +119,34 @@ let {{ return (header_output, decoder_output, exec_output, decode_block) }}; -// Primary format for integer operate instructions: def format Priv(code, *opt_flags) {{ - checkCode = "!(Pstate<2:2> || Hpstate<2:2>)" + checkCode = "!(Pstate<2:> || Hpstate<2:>)" (header_output, decoder_output, exec_output, decode_block) = doPrivFormat(code, - checkCode, name, Name, opt_flags + ('IprAccessOp',)) + checkCode, name, Name, opt_flags) +}}; + +def format NoPriv(code, *opt_flags) {{ + #Instructions which use this format don't really check for + #any particular mode, but the disassembly is performed + #using the control registers actual name + checkCode = "false" + (header_output, decoder_output, + exec_output, decode_block) = doPrivFormat(code, + checkCode, name, Name, opt_flags) +}}; + +def format PrivCheck(code, extraCheckCode, *opt_flags) {{ + checkCode = "(%s) && !(Pstate<2:> || Hpstate<2:>)" % extraCheckCode + (header_output, decoder_output, + exec_output, decode_block) = doPrivFormat(code, + checkCode, name, Name, opt_flags) }}; def format HPriv(code, *opt_flags) {{ checkCode = "!Hpstate<2:2>" (header_output, decoder_output, exec_output, decode_block) = doPrivFormat(code, - checkCode, name, Name, opt_flags + ('IprAccessOp',)) + checkCode, name, Name, opt_flags) }}; diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa index a324756ec..624afb693 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -54,6 +54,7 @@ output decoder {{ #if defined(linux) #include #endif +#include using namespace SparcISA; }}; diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index 80b499b91..caee20b0c 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.isa @@ -80,8 +80,6 @@ def operands {{ 'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12), 'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31), 'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32), - #'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1), - #'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1), 'R0': ('IntReg', 'udw', '0', None, 6), 'R1': ('IntReg', 'udw', '1', None, 7), 'R15': ('IntReg', 'udw', '15', 'IsInteger', 8), @@ -91,24 +89,42 @@ def operands {{ 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40), 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41), 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 42), + 'Fprs': ('ControlReg', 'udw', 'MISCREG_FPRS', None, 43), + 'Pcr': ('ControlReg', 'udw', 'MISCREG_PCR', None, 44), + 'Pic': ('ControlReg', 'udw', 'MISCREG_PIC', None, 45), + 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 46), + 'Softint': ('ControlReg', 'udw', 'MISCREG_SOFTINT', None, 47), + 'SoftintSet': ('ControlReg', 'udw', 'MISCREG_SOFTINT_SET', None, 48), + 'SoftintClr': ('ControlReg', 'udw', 'MISCREG_SOFTINT_CLR', None, 49), + 'TickCmpr': ('ControlReg', 'udw', 'MISCREG_TICK_CMPR', None, 50), + 'Stick': ('ControlReg', 'udw', 'MISCREG_STICK', None, 51), + 'StickCmpr': ('ControlReg', 'udw', 'MISCREG_STICK_CMPR', None, 52), - 'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 43), - 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 44), - 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 45), - 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 46), - 'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 47), - 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 48), + 'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 53), + 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 54), + 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 55), + 'Tt': ('ControlReg', 'udw', 'MISCREG_TT', None, 56), + 'Tick': ('ControlReg', 'udw', 'MISCREG_TICK', None, 57), + 'Tba': ('ControlReg', 'udw', 'MISCREG_TBA', None, 58), + 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 59), + 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 60), + 'Pil': ('ControlReg', 'udw', 'MISCREG_PIL', None, 61), + 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 62), + 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63), + 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64), + 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65), + 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66), + 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67), + 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 68), - 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 49), - 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 50), - 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 51), - 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 52), - 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 53), - 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 54), - 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 55), + 'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 69), + 'Htstate': ('ControlReg', 'udw', 'MISCREG_HTSTATE', None, 70), + 'Hintp': ('ControlReg', 'udw', 'MISCREG_HINTP', None, 71), + 'Htba': ('ControlReg', 'udw', 'MISCREG_HTBA', None, 72), + 'HstickCmpr': ('ControlReg', 'udw', 'MISCREG_HSTICK_CMPR', None, 73), + 'Hver': ('ControlReg', 'udw', 'MISCREG_HVER', None, 74), - 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 56), - 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 57), + 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 80), # Mem gets a large number so it's always last 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100) diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 217fba0bd..714c9bdab 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -30,6 +30,7 @@ */ #include "arch/sparc/miscregfile.hh" +#include "base/bitfield.hh" #include "base/trace.hh" #include "config/full_system.hh" #include "cpu/base.hh" @@ -78,8 +79,9 @@ MiscReg MiscRegFile::readReg(int miscReg) case MISCREG_TICK: return tick; case MISCREG_PCR: + panic("PCR not implemented\n"); case MISCREG_PIC: - panic("ASR number %d not implemented\n", miscReg - AsrStart); + panic("PIC not implemented\n"); case MISCREG_GSR: return gsr; case MISCREG_SOFTINT: @@ -154,8 +156,8 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) switch (miscReg) { case MISCREG_TICK: case MISCREG_PRIVTICK: - return tc->getCpuPtr()->curCycle() - tickFields.counter | - tickFields.npt << 63; + return tc->getCpuPtr()->curCycle() - (tick & mask(63)) | + (tick & ~(mask(63))) << 63; case MISCREG_FPRS: panic("FPU not implemented\n"); case MISCREG_PCR: @@ -171,7 +173,7 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) SparcSystem *sys; sys = dynamic_cast(tc->getSystemPtr()); assert(sys != NULL); - return curTick/Clock::Int::ns - sys->sysTick | stickFields.npt << 63; + return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63))); #endif case MISCREG_HVER: return NWindows | MaxTL << 8 | MaxGL << 16; @@ -198,8 +200,9 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val) tick = val; break; case MISCREG_PCR: + panic("PCR not implemented\n"); case MISCREG_PIC: - panic("ASR number %d not implemented\n", miscReg - AsrStart); + panic("PIC not implemented\n"); case MISCREG_GSR: gsr = val; break; @@ -303,12 +306,12 @@ inline void MiscRegFile::setImplicitAsis() if(tl == 0) { implicitInstAsi = implicitDataAsi = - pstateFields.cle ? ASI_PRIMARY_LITTLE : ASI_PRIMARY; + (pstate & (1 << 9)) ? ASI_PRIMARY_LITTLE : ASI_PRIMARY; } else if(tl <= MaxPTL) { implicitInstAsi = ASI_NUCLEUS; - implicitDataAsi = pstateFields.cle ? ASI_NUCLEUS_LITTLE : ASI_NUCLEUS; + implicitDataAsi = (pstate & (1 << 9)) ? ASI_NUCLEUS_LITTLE : ASI_NUCLEUS; } else { @@ -328,8 +331,8 @@ void MiscRegFile::setRegWithEffect(int miscReg, #endif switch (miscReg) { case MISCREG_TICK: - tickFields.counter = tc->getCpuPtr()->curCycle() - val & ~Bit64; - tickFields.npt = val & Bit64 ? 1 : 0; + tick = tc->getCpuPtr()->curCycle() - val & ~Bit64; + tick |= val & Bit64; break; case MISCREG_FPRS: //Configure the fpu based on the fprs @@ -369,10 +372,10 @@ void MiscRegFile::setRegWithEffect(int miscReg, if (tickCompare == NULL) tickCompare = new TickCompareEvent(this, tc); setReg(miscReg, val); - if (tick_cmprFields.int_dis && tickCompare->scheduled()) + if ((tick_cmpr & mask(63)) && tickCompare->scheduled()) tickCompare->deschedule(); - time = tick_cmprFields.tick_cmpr - tickFields.counter; - if (!tick_cmprFields.int_dis && time > 0) + time = (tick_cmpr & mask(63)) - (tick & mask(63)); + if (!(tick_cmpr & ~mask(63)) && time > 0) tickCompare->schedule(time * tc->getCpuPtr()->cycles(1)); break; #endif @@ -390,17 +393,17 @@ void MiscRegFile::setRegWithEffect(int miscReg, sys = dynamic_cast(tc->getSystemPtr()); assert(sys != NULL); sys->sysTick = curTick/Clock::Int::ns - val & ~Bit64; - stickFields.npt = val & Bit64 ? 1 : 0; + stick |= val & Bit64; break; case MISCREG_STICK_CMPR: if (sTickCompare == NULL) sTickCompare = new STickCompareEvent(this, tc); sys = dynamic_cast(tc->getSystemPtr()); assert(sys != NULL); - if (stick_cmprFields.int_dis && sTickCompare->scheduled()) + if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) sTickCompare->deschedule(); - time = stick_cmprFields.tick_cmpr - sys->sysTick; - if (!stick_cmprFields.int_dis && time > 0) + time = (stick_cmpr & mask(63)) - sys->sysTick; + if (!(stick_cmpr & ~mask(63)) && time > 0) sTickCompare->schedule(time * Clock::Int::ns); break; case MISCREG_HSTICK_CMPR: @@ -408,10 +411,10 @@ void MiscRegFile::setRegWithEffect(int miscReg, hSTickCompare = new HSTickCompareEvent(this, tc); sys = dynamic_cast(tc->getSystemPtr()); assert(sys != NULL); - if (hstick_cmprFields.int_dis && hSTickCompare->scheduled()) + if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) hSTickCompare->deschedule(); - int64_t time = hstick_cmprFields.tick_cmpr - sys->sysTick; - if (!hstick_cmprFields.int_dis && time > 0) + int64_t time = (hstick_cmpr & mask(63)) - sys->sysTick; + if (!(hstick_cmpr & ~mask(63)) && time > 0) hSTickCompare->schedule(time * Clock::Int::ns); break; #endif diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index 6d624787d..f74943256 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -92,8 +92,7 @@ namespace SparcISA MISCREG_HSTICK_CMPR, /** Floating Point Status Register */ - MISCREG_FSR, - NumMiscRegs + MISCREG_FSR }; // The control registers, broken out into fields @@ -102,93 +101,16 @@ namespace SparcISA private: /* ASR Registers */ - union { - uint64_t y; // Y (used in obsolete multiplication) - struct { - uint64_t value:32; // The actual value stored in y - uint64_t :32; // reserved bits - } yFields; - }; - union { - uint8_t ccr; // Condition Code Register - struct { - union { - uint8_t icc:4; // 32-bit condition codes - struct { - uint8_t c:1; // Carry - uint8_t v:1; // Overflow - uint8_t z:1; // Zero - uint8_t n:1; // Negative - } iccFields; - }; - union { - uint8_t xcc:4; // 64-bit condition codes - struct { - uint8_t c:1; // Carry - uint8_t v:1; // Overflow - uint8_t z:1; // Zero - uint8_t n:1; // Negative - } xccFields; - }; - } ccrFields; - }; + uint64_t y; // Y (used in obsolete multiplication) + uint8_t ccr; // Condition Code Register uint8_t asi; // Address Space Identifier - union { - uint64_t tick; // Hardware clock-tick counter - struct { - int64_t counter:63; // Clock-tick count - uint64_t npt:1; // Non-priveleged trap - } tickFields; - }; - union { - uint8_t fprs; // Floating-Point Register State - struct { - uint8_t dl:1; // Dirty lower - uint8_t du:1; // Dirty upper - uint8_t fef:1; // FPRS enable floating-Point - } fprsFields; - }; - union { - uint64_t gsr; //General Status Register - struct { - uint64_t mask:32; - uint64_t :4; - uint64_t im:1; - uint64_t irnd:2; - uint64_t :17; - uint64_t scale:5; - uint64_t align:3; - } gsrFields; - }; - union { - uint64_t softint; - struct { - uint64_t tm:1; - uint64_t int_level:14; - uint64_t sm:1; - } softintFields; - }; - union { - uint64_t tick_cmpr; // Hardware tick compare registers - struct { - uint64_t tick_cmpr:63; // Clock-tick count - uint64_t int_dis:1; // Non-priveleged trap - } tick_cmprFields; - }; - union { - uint64_t stick; // Hardware clock-tick counter - struct { - int64_t :63; // Not used, storage in SparcSystem - uint64_t npt:1; // Non-priveleged trap - } stickFields; - }; - union { - uint64_t stick_cmpr; // Hardware tick compare registers - struct { - uint64_t tick_cmpr:63; // Clock-tick count - uint64_t int_dis:1; // Non-priveleged trap - } stick_cmprFields; - }; + uint64_t tick; // Hardware clock-tick counter + uint8_t fprs; // Floating-Point Register State + uint64_t gsr; // General Status Register + uint64_t softint; + uint64_t tick_cmpr; // Hardware tick compare registers + uint64_t stick; // Hardware clock-tick counter + uint64_t stick_cmpr; // Hardware tick compare registers /* Privileged Registers */ @@ -196,37 +118,12 @@ namespace SparcISA // previous trap level) uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from // previous trap level) - union { - uint64_t tstate[MaxTL]; // Trap State - struct { - //Values are from previous trap level - uint64_t cwp:5; // Current Window Pointer - uint64_t :3; // Reserved bits - uint64_t pstate:13; // Process State - uint64_t :3; // Reserved bits - uint64_t asi:8; // Address Space Identifier - uint64_t ccr:8; // Condition Code Register - uint64_t gl:8; // Global level - } tstateFields[MaxTL]; - }; + uint64_t tstate[MaxTL]; // Trap State uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured // on the previous level) uint64_t tba; // Trap Base Address - union { - uint16_t pstate; // Process State Register - struct { - uint16_t :1; // reserved - uint16_t ie:1; // Interrupt enable - uint16_t priv:1; // Privelege mode - uint16_t am:1; // Address mask - uint16_t pef:1; // PSTATE enable floating-point - uint16_t :1; // reserved2 - uint16_t mm:2; // Memory Model - uint16_t tle:1; // Trap little-endian - uint16_t cle:1; // Current little-endian - } pstateFields; - }; + uint16_t pstate; // Process State Register uint8_t tl; // Trap Level uint8_t pil; // Process Interrupt Register uint8_t cwp; // Current Window Pointer @@ -234,97 +131,20 @@ namespace SparcISA uint8_t canrestore; // Restorable windows uint8_t cleanwin; // Clean windows uint8_t otherwin; // Other windows - union { - uint8_t wstate; // Window State - struct { - uint8_t normal:3; // Bits TT<4:2> are set to on a normal - // register window trap - uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin" - // register window trap - } wstateFields; - }; + uint8_t wstate; // Window State uint8_t gl; // Global level register - /** Hyperprivileged Registers */ - union { - uint64_t hpstate; // Hyperprivileged State Register - struct { - uint8_t tlz: 1; - uint8_t :1; - uint8_t hpriv:1; - uint8_t :2; - uint8_t red:1; - uint8_t :4; - uint8_t ibe:1; - uint8_t id:1; - } hpstateFields; - }; - - uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register + uint64_t hpstate; // Hyperprivileged State Register + uint64_t htstate[MaxTL];// Hyperprivileged Trap State Register uint64_t hintp; - uint64_t htba; // Hyperprivileged Trap Base Address register - union { - uint64_t hstick_cmpr; // Hardware tick compare registers - struct { - uint64_t tick_cmpr:63; // Clock-tick count - uint64_t int_dis:1; // Non-priveleged trap - } hstick_cmprFields; - }; - - uint64_t strandStatusReg; // Per strand status register + uint64_t htba; // Hyperprivileged Trap Base Address register + uint64_t hstick_cmpr; // Hardware tick compare registers + uint64_t strandStatusReg;// Per strand status register /** Floating point misc registers. */ - union { - uint64_t fsr; // Floating-Point State Register - struct { - union { - uint64_t cexc:5; // Current excpetion - struct { - uint64_t nxc:1; // Inexact - uint64_t dzc:1; // Divide by zero - uint64_t ufc:1; // Underflow - uint64_t ofc:1; // Overflow - uint64_t nvc:1; // Invalid operand - } cexcFields; - }; - union { - uint64_t aexc:5; // Accrued exception - struct { - uint64_t nxc:1; // Inexact - uint64_t dzc:1; // Divide by zero - uint64_t ufc:1; // Underflow - uint64_t ofc:1; // Overflow - uint64_t nvc:1; // Invalid operand - } aexcFields; - }; - uint64_t fcc0:2; // Floating-Point condtion codes - uint64_t :1; // Reserved bits - uint64_t qne:1; // Deferred trap queue not empty - // with no queue, it should read 0 - uint64_t ftt:3; // Floating-Point trap type - uint64_t ver:3; // Version (of the FPU) - uint64_t :2; // Reserved bits - uint64_t ns:1; // Nonstandard floating point - union { - uint64_t tem:5; // Trap Enable Mask - struct { - uint64_t nxm:1; // Inexact - uint64_t dzm:1; // Divide by zero - uint64_t ufm:1; // Underflow - uint64_t ofm:1; // Overflow - uint64_t nvm:1; // Invalid operand - } temFields; - }; - uint64_t :2; // Reserved bits - uint64_t rd:2; // Rounding direction - uint64_t fcc1:2; // Floating-Point condition codes - uint64_t fcc2:2; // Floating-Point condition codes - uint64_t fcc3:2; // Floating-Point condition codes - uint64_t :26; // Reserved bits - } fsrFields; - }; + uint64_t fsr; // Floating-Point State Register ASI implicitInstAsi; ASI implicitDataAsi; @@ -386,8 +206,8 @@ namespace SparcISA protected: - bool isHyperPriv() { return hpstateFields.hpriv; } - bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; } + bool isHyperPriv() { return (hpstate & (1 << 2)); } + bool isPriv() { return (hpstate & (1 << 2)) || (pstate & (1 << 2)); } bool isNonPriv() { return !isPriv(); } inline void setImplicitAsis(); }; -- cgit v1.2.3 From 1d70dda6d72c4b563a19f3b4159a658d14b0eb41 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Nov 2006 04:11:46 -0500 Subject: Change exetrace code for working with my trace tool to use stream io rather than sprintf which was breaking on 64 bit hosts. --HG-- extra : convert_revision : 184d751392dfcc8c80ac1a6c0ebc3061ff0a3f20 --- src/cpu/exetrace.cc | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 881fbbd9b..ef06e0699 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -68,7 +68,6 @@ Trace::InstRecord::dump(ostream &outs) if (flags[PRINT_REG_DELTA]) { #if THE_ISA == SPARC_ISA -#if 0 //Don't print what happens for each micro-op, just print out //once at the last op, and for regular instructions. if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) @@ -84,23 +83,19 @@ Trace::InstRecord::dump(ostream &outs) uint64_t newVal; static const char * prefixes[4] = {"G", "O", "L", "I"}; - char buf[256]; - sprintf(buf, "PC = 0x%016llx", thread->readNextPC()); - outs << buf; - sprintf(buf, " NPC = 0x%016llx", thread->readNextNPC()); - outs << buf; + outs << hex; + outs << "PC = " << thread->readNextPC(); + outs << " NPC = " << thread->readNextNPC(); newVal = thread->readMiscReg(SparcISA::MISCREG_CCR); if(newVal != ccr) { - sprintf(buf, " CCR = 0x%016llx", newVal); - outs << buf; + outs << " CCR = " << newVal; ccr = newVal; } newVal = thread->readMiscReg(SparcISA::MISCREG_Y); if(newVal != y) { - sprintf(buf, " Y = 0x%016llx", newVal); - outs << buf; + outs << " Y = " << newVal; y = newVal; } for(int y = 0; y < 4; y++) @@ -111,8 +106,7 @@ Trace::InstRecord::dump(ostream &outs) newVal = thread->readIntReg(index); if(regs[index] != newVal) { - sprintf(buf, " %s%d = 0x%016llx", prefixes[y], x, newVal); - outs << buf; + outs << " " << prefixes[y] << dec << x << " = " << hex << newVal; regs[index] = newVal; } } @@ -122,14 +116,12 @@ Trace::InstRecord::dump(ostream &outs) newVal = thread->readFloatRegBits(2 * y, 64); if(floats[y] != newVal) { - sprintf(buf, " F%d = 0x%016llx", 2 * y, newVal); - outs << buf; + outs << " F" << dec << (2 * y) << " = " << hex << newVal; floats[y] = newVal; } } - outs << endl; + outs << dec << endl; } -#endif #endif } else if (flags[INTEL_FORMAT]) { -- cgit v1.2.3 From dc6af9fbf7bbbe29e431190867a2fed6fdcce8b5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Nov 2006 04:14:25 -0500 Subject: Set the ASI register to be something explicitly so that simulation is deterministic. --HG-- extra : convert_revision : 38cd06f946fc0cc22288f71f567e77ce8fdfea99 --- src/arch/sparc/process.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index a3b7dde7c..11a799ccb 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -29,6 +29,7 @@ * Ali Saidi */ +#include "arch/sparc/asi.hh" #include "arch/sparc/isa_traits.hh" #include "arch/sparc/process.hh" #include "base/loader/object_file.hh" @@ -105,6 +106,8 @@ SparcLiveProcess::startup() threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0); //Set the trap level to 0 threadContexts[0]->setMiscReg(MISCREG_TL, 0); + //Set the ASI register to something fixed + threadContexts[0]->setMiscReg(MISCREG_ASI, ASI_PRIMARY); } m5_auxv_t buildAuxVect(int64_t type, int64_t val) -- cgit v1.2.3 From 71dc49c785b8623b82bf0d7b9df6085a3cd66dfa Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Nov 2006 04:33:41 -0500 Subject: The reset function of the MiscRegFile really resets it now. This function is called from the class's constructor. --HG-- extra : convert_revision : 4e7a40ffe0a9a71fd1b2b171d9c0dcac50e1a1fe --- src/arch/sparc/miscregfile.cc | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src') diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 714c9bdab..d52e3983f 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -29,6 +29,7 @@ * Ali Saidi */ +#include "arch/sparc/asi.hh" #include "arch/sparc/miscregfile.hh" #include "base/bitfield.hh" #include "base/trace.hh" @@ -63,6 +64,39 @@ string SparcISA::getMiscRegName(RegIndex index) void MiscRegFile::reset() { + y = 0; + ccr = 0; + asi = 0; + tick = 0; + fprs = 0; + gsr = 0; + softint = 0; + tick_cmpr = 0; + stick = 0; + stick_cmpr = 0; + memset(tpc, 0, sizeof(tpc)); + memset(tnpc, 0, sizeof(tnpc)); + memset(tstate, 0, sizeof(tstate)); + memset(tt, 0, sizeof(tt)); + pstate = 0; + tl = 0; + pil = 0; + cwp = 0; + cansave = 0; + canrestore = 0; + cleanwin = 0; + otherwin = 0; + wstate = 0; + gl = 0; + hpstate = 0; + memset(htstate, 0, sizeof(htstate)); + hintp = 0; + htba = 0; + hstick_cmpr = 0; + strandStatusReg = 0; + fsr = 0; + implicitInstAsi = ASI_PRIMARY; + implicitDataAsi = ASI_PRIMARY; } MiscReg MiscRegFile::readReg(int miscReg) -- cgit v1.2.3 From b4dfbf3aab700f4cc9c5638c2275c588a56778c8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Nov 2006 04:54:25 -0500 Subject: Split out alpha integer register file into it's own files. --HG-- extra : convert_revision : 164bdcec2860c5dca3f0f11d189781b88dd717cb --- src/arch/alpha/SConscript | 1 + src/arch/alpha/intregfile.cc | 65 +++++++++++++++++++++++++++++++++++++++ src/arch/alpha/intregfile.hh | 73 ++++++++++++++++++++++++++++++++++++++++++++ src/arch/alpha/isa_traits.hh | 4 --- src/arch/alpha/regfile.hh | 32 +------------------ 5 files changed, 140 insertions(+), 35 deletions(-) create mode 100644 src/arch/alpha/intregfile.cc create mode 100644 src/arch/alpha/intregfile.hh (limited to 'src') diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript index d9c9765a1..b0a725e7a 100644 --- a/src/arch/alpha/SConscript +++ b/src/arch/alpha/SConscript @@ -50,6 +50,7 @@ base_sources = Split(''' faults.cc isa_traits.cc miscregfile.cc + intregfile.cc ''') # Full-system sources diff --git a/src/arch/alpha/intregfile.cc b/src/arch/alpha/intregfile.cc new file mode 100644 index 000000000..0188cb2cd --- /dev/null +++ b/src/arch/alpha/intregfile.cc @@ -0,0 +1,65 @@ +/* + * 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: Steve Reinhardt + * Gabe Black + * Kevin Lim + */ + +#include "arch/alpha/isa_traits.hh" +#include "arch/alpha/intregfile.hh" +#include "sim/serialize.hh" + +namespace AlphaISA +{ +#if FULL_SYSTEM + const int reg_redir[AlphaISA::NumIntRegs] = { + /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, + /* 8 */ 32, 33, 34, 35, 36, 37, 38, 15, + /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, + /* 24 */ 24, 39, 26, 27, 28, 29, 30, 31 }; +#else + const int reg_redir[AlphaISA::NumIntRegs] = { + /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, + /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, + /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, + /* 24 */ 24, 25, 26, 27, 28, 29, 30, 31 }; +#endif + + void + IntRegFile::serialize(std::ostream &os) + { + SERIALIZE_ARRAY(regs, NumIntRegs); + } + + void + IntRegFile::unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_ARRAY(regs, NumIntRegs); + } +} + diff --git a/src/arch/alpha/intregfile.hh b/src/arch/alpha/intregfile.hh new file mode 100644 index 000000000..78f666345 --- /dev/null +++ b/src/arch/alpha/intregfile.hh @@ -0,0 +1,73 @@ +/* + * 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: Steve Reinhardt + * Gabe Black + */ + +#ifndef __ARCH_ALPHA_INTREGFILE_HH__ +#define __ARCH_ALPHA_INTREGFILE_HH__ + +#include "arch/alpha/types.hh" + +#include +#include + +class Checkpoint; + +namespace AlphaISA +{ + // redirected register map, really only used for the full system case. + extern const int reg_redir[NumIntRegs]; + + class IntRegFile + { + protected: + IntReg regs[NumIntRegs]; + + public: + + IntReg readReg(int intReg) + { + return regs[intReg]; + } + + void setReg(int intReg, const IntReg &val) + { + regs[intReg] = val; + } + + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); + + void clear() + { bzero(regs, sizeof(regs)); } + }; +} + +#endif diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh index 3759b022b..35d9ce843 100644 --- a/src/arch/alpha/isa_traits.hh +++ b/src/arch/alpha/isa_traits.hh @@ -114,7 +114,6 @@ namespace AlphaISA NumInterruptLevels = INTLEVEL_EXTERNAL_MAX }; - // EV5 modes enum mode_type { @@ -181,9 +180,6 @@ namespace AlphaISA // Alpha UNOP (ldq_u r31,0(r0)) const ExtMachInst NoopMachInst = 0x2ffe0000; - // redirected register map, really only used for the full system case. - extern const int reg_redir[NumIntRegs]; - }; #endif // __ARCH_ALPHA_ISA_TRAITS_HH__ diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index af28f6c6f..091f0e2e6 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -32,7 +32,7 @@ #define __ARCH_ALPHA_REGFILE_HH__ #include "arch/alpha/isa_traits.hh" -#include "arch/alpha/ipr.hh" +#include "arch/alpha/intregfile.hh" #include "arch/alpha/miscregfile.hh" #include "arch/alpha/types.hh" #include "sim/faults.hh" @@ -62,32 +62,6 @@ namespace AlphaISA return ""; } - class IntRegFile - { - protected: - IntReg regs[NumIntRegs]; - - public: - - IntReg readReg(int intReg) - { - return regs[intReg]; - } - - Fault setReg(int intReg, const IntReg &val) - { - regs[intReg] = val; - return NoFault; - } - - void serialize(std::ostream &os); - - void unserialize(Checkpoint *cp, const std::string §ion); - - void clear() - { bzero(regs, sizeof(regs)); } - }; - class FloatRegFile { public: @@ -249,10 +223,6 @@ namespace AlphaISA void copyRegs(ThreadContext *src, ThreadContext *dest); void copyMiscRegs(ThreadContext *src, ThreadContext *dest); - -#if FULL_SYSTEM - void copyIprs(ThreadContext *src, ThreadContext *dest); -#endif } // namespace AlphaISA #endif -- cgit v1.2.3 From 9731fb3fd72ed2e8f5bf3423a33d45a5c35f636f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Nov 2006 05:29:05 -0500 Subject: Moved the Alpha float regfile into it's own regfile and got rid of constants.hh and isa_traits.cc --HG-- extra : convert_revision : 55afd7d21c276906520da375b3bbb563be420880 --- src/arch/alpha/SConscript | 14 +++--- src/arch/alpha/floatregfile.cc | 49 ++++++++++++++++++++ src/arch/alpha/floatregfile.hh | 63 +++++++++++++++++++++++++ src/arch/alpha/pagetable.cc | 63 +++++++++++++++++++++++++ src/arch/alpha/regfile.cc | 101 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 284 insertions(+), 6 deletions(-) create mode 100644 src/arch/alpha/floatregfile.cc create mode 100644 src/arch/alpha/floatregfile.hh create mode 100644 src/arch/alpha/pagetable.cc create mode 100644 src/arch/alpha/regfile.cc (limited to 'src') diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript index b0a725e7a..3cc5ec270 100644 --- a/src/arch/alpha/SConscript +++ b/src/arch/alpha/SConscript @@ -48,27 +48,29 @@ Import('env') # Base sources used by all configurations. base_sources = Split(''' faults.cc - isa_traits.cc - miscregfile.cc + floatregfile.cc intregfile.cc + miscregfile.cc + regfile.cc ''') # Full-system sources full_system_sources = Split(''' - tlb.cc arguments.cc ev5.cc + freebsd/system.cc idle_event.cc ipr.cc kernel_stats.cc + linux/system.cc osfpal.cc + pagetable.cc stacktrace.cc - vtophys.cc remote_gdb.cc system.cc - freebsd/system.cc - linux/system.cc + tlb.cc tru64/system.cc + vtophys.cc ''') diff --git a/src/arch/alpha/floatregfile.cc b/src/arch/alpha/floatregfile.cc new file mode 100644 index 000000000..512b0df95 --- /dev/null +++ b/src/arch/alpha/floatregfile.cc @@ -0,0 +1,49 @@ +/* + * 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: Steve Reinhardt + * Gabe Black + * Kevin Lim + */ + +#include "arch/alpha/floatregfile.hh" +#include "sim/serialize.hh" + +namespace AlphaISA +{ + void + FloatRegFile::serialize(std::ostream &os) + { + SERIALIZE_ARRAY(q, NumFloatRegs); + } + + void + FloatRegFile::unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_ARRAY(q, NumFloatRegs); + } +} diff --git a/src/arch/alpha/floatregfile.hh b/src/arch/alpha/floatregfile.hh new file mode 100644 index 000000000..6b394da03 --- /dev/null +++ b/src/arch/alpha/floatregfile.hh @@ -0,0 +1,63 @@ +/* + * 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: Steve Reinhardt + * Gabe Black + */ + +#ifndef __ARCH_ALPHA_FLOATREGFILE_HH__ +#define __ARCH_ALPHA_FLOATREGFILE_HH__ + +#include "arch/alpha/isa_traits.hh" +#include "arch/alpha/types.hh" + +#include +#include + +class Checkpoint; + +namespace AlphaISA +{ + class FloatRegFile + { + public: + + union { + uint64_t q[NumFloatRegs]; // integer qword view + double d[NumFloatRegs]; // double-precision floating point view + }; + + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); + + void clear() + { bzero(d, sizeof(d)); } + }; +} + +#endif diff --git a/src/arch/alpha/pagetable.cc b/src/arch/alpha/pagetable.cc new file mode 100644 index 000000000..0c26ccbe3 --- /dev/null +++ b/src/arch/alpha/pagetable.cc @@ -0,0 +1,63 @@ +/* + * Copyright (c) 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: Gabe Black + */ + +#include "arch/alpha/pagetable.hh" +#include "sim/serialize.hh" + +namespace AlphaISA +{ + void + PTE::serialize(std::ostream &os) + { + SERIALIZE_SCALAR(tag); + SERIALIZE_SCALAR(ppn); + SERIALIZE_SCALAR(xre); + SERIALIZE_SCALAR(xwe); + SERIALIZE_SCALAR(asn); + SERIALIZE_SCALAR(asma); + SERIALIZE_SCALAR(fonr); + SERIALIZE_SCALAR(fonw); + SERIALIZE_SCALAR(valid); + } + + void + PTE::unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_SCALAR(tag); + UNSERIALIZE_SCALAR(ppn); + UNSERIALIZE_SCALAR(xre); + UNSERIALIZE_SCALAR(xwe); + UNSERIALIZE_SCALAR(asn); + UNSERIALIZE_SCALAR(asma); + UNSERIALIZE_SCALAR(fonr); + UNSERIALIZE_SCALAR(fonw); + UNSERIALIZE_SCALAR(valid); + } +} diff --git a/src/arch/alpha/regfile.cc b/src/arch/alpha/regfile.cc new file mode 100644 index 000000000..92e1b07df --- /dev/null +++ b/src/arch/alpha/regfile.cc @@ -0,0 +1,101 @@ +/* + * 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: Steve Reinhardt + * Gabe Black + * Kevin Lim + */ + +#include "arch/alpha/regfile.hh" +#include "cpu/thread_context.hh" + +namespace AlphaISA +{ + void + RegFile::serialize(std::ostream &os) + { + intRegFile.serialize(os); + floatRegFile.serialize(os); + miscRegFile.serialize(os); + SERIALIZE_SCALAR(pc); + SERIALIZE_SCALAR(npc); +#if FULL_SYSTEM + SERIALIZE_SCALAR(intrflag); +#endif + } + + void + RegFile::unserialize(Checkpoint *cp, const std::string §ion) + { + intRegFile.unserialize(cp, section); + floatRegFile.unserialize(cp, section); + miscRegFile.unserialize(cp, section); + UNSERIALIZE_SCALAR(pc); + UNSERIALIZE_SCALAR(npc); +#if FULL_SYSTEM + UNSERIALIZE_SCALAR(intrflag); +#endif + } + + void + copyRegs(ThreadContext *src, ThreadContext *dest) + { + // First loop through the integer registers. + for (int i = 0; i < NumIntRegs; ++i) { + dest->setIntReg(i, src->readIntReg(i)); + } + + // Then loop through the floating point registers. + for (int i = 0; i < TheISA::NumFloatRegs; ++i) { + dest->setFloatRegBits(i, src->readFloatRegBits(i)); + } + + // Copy misc. registers + copyMiscRegs(src, dest); + + // Lastly copy PC/NPC + dest->setPC(src->readPC()); + dest->setNextPC(src->readNextPC()); + } + + void + copyMiscRegs(ThreadContext *src, ThreadContext *dest) + { + dest->setMiscReg(AlphaISA::MISCREG_FPCR, + src->readMiscReg(AlphaISA::MISCREG_FPCR)); + dest->setMiscReg(AlphaISA::MISCREG_UNIQ, + src->readMiscReg(AlphaISA::MISCREG_UNIQ)); + dest->setMiscReg(AlphaISA::MISCREG_LOCKFLAG, + src->readMiscReg(AlphaISA::MISCREG_LOCKFLAG)); + dest->setMiscReg(AlphaISA::MISCREG_LOCKADDR, + src->readMiscReg(AlphaISA::MISCREG_LOCKADDR)); + +#if FULL_SYSTEM + copyIprs(src, dest); +#endif + } +} -- cgit v1.2.3 From 9ef51f2dbaba88c10366d708f0ca872bb39064e4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Nov 2006 05:49:16 -0500 Subject: Actually finished moving the register file stuff around. --HG-- extra : convert_revision : 786735ecea8ff480db6b3754ac5daa562938d988 --- src/arch/alpha/floatregfile.hh | 5 +++++ src/arch/alpha/intregfile.hh | 5 +++++ src/arch/alpha/miscregfile.hh | 5 +++++ src/arch/alpha/regfile.hh | 33 +-------------------------------- 4 files changed, 16 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/floatregfile.hh b/src/arch/alpha/floatregfile.hh index 6b394da03..d289f5785 100644 --- a/src/arch/alpha/floatregfile.hh +++ b/src/arch/alpha/floatregfile.hh @@ -42,6 +42,11 @@ class Checkpoint; namespace AlphaISA { + static inline std::string getFloatRegName(RegIndex) + { + return ""; + } + class FloatRegFile { public: diff --git a/src/arch/alpha/intregfile.hh b/src/arch/alpha/intregfile.hh index 78f666345..0d65f69e0 100644 --- a/src/arch/alpha/intregfile.hh +++ b/src/arch/alpha/intregfile.hh @@ -41,6 +41,11 @@ class Checkpoint; namespace AlphaISA { + static inline std::string getIntRegName(RegIndex) + { + return ""; + } + // redirected register map, really only used for the full system case. extern const int reg_redir[NumIntRegs]; diff --git a/src/arch/alpha/miscregfile.hh b/src/arch/alpha/miscregfile.hh index 85cb054bb..31b3e59b3 100644 --- a/src/arch/alpha/miscregfile.hh +++ b/src/arch/alpha/miscregfile.hh @@ -54,6 +54,11 @@ namespace AlphaISA MISCREG_INTR }; + static inline std::string getMiscRegName(RegIndex) + { + return ""; + } + class MiscRegFile { protected: uint64_t fpcr; // floating point condition codes diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index 091f0e2e6..ff5830822 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -32,6 +32,7 @@ #define __ARCH_ALPHA_REGFILE_HH__ #include "arch/alpha/isa_traits.hh" +#include "arch/alpha/floatregfile.hh" #include "arch/alpha/intregfile.hh" #include "arch/alpha/miscregfile.hh" #include "arch/alpha/types.hh" @@ -47,38 +48,6 @@ class ThreadContext; namespace AlphaISA { - static inline std::string getIntRegName(RegIndex) - { - return ""; - } - - static inline std::string getFloatRegName(RegIndex) - { - return ""; - } - - static inline std::string getMiscRegName(RegIndex) - { - return ""; - } - - class FloatRegFile - { - public: - - union { - uint64_t q[NumFloatRegs]; // integer qword view - double d[NumFloatRegs]; // double-precision floating point view - }; - - void serialize(std::ostream &os); - - void unserialize(Checkpoint *cp, const std::string §ion); - - void clear() - { bzero(d, sizeof(d)); } - }; - class RegFile { protected: -- cgit v1.2.3