From 9ca5427c0367d9aa391f491b8a1a4309f3b24385 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 22 Jun 2006 18:05:12 -0400 Subject: Split Checker up properly into templated and non-templated definitions. --HG-- extra : convert_revision : 3ead18e42f4a536f2f868da07cb81a8940a7fa2f --- src/cpu/checker/cpu_impl.hh | 362 -------------------------------------------- 1 file changed, 362 deletions(-) (limited to 'src/cpu/checker/cpu_impl.hh') diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh index 5091c7c1a..137e1c46d 100644 --- a/src/cpu/checker/cpu_impl.hh +++ b/src/cpu/checker/cpu_impl.hh @@ -32,7 +32,6 @@ #include #include "base/refcnt.hh" -#include "cpu/base.hh" #include "cpu/base_dyn_inst.hh" #include "cpu/checker/cpu.hh" #include "cpu/simple_thread.hh" @@ -44,374 +43,13 @@ #include "sim/stats.hh" #if FULL_SYSTEM -#include "sim/system.hh" #include "arch/vtophys.hh" -#include "kern/kernel_stats.hh" #endif // FULL_SYSTEM using namespace std; //The CheckerCPU does alpha only using namespace AlphaISA; -void -CheckerCPU::init() -{ -} - -CheckerCPU::CheckerCPU(Params *p) - : BaseCPU(p), thread(NULL), tc(NULL) -{ - memReq = NULL; - - numInst = 0; - startNumInst = 0; - numLoad = 0; - startNumLoad = 0; - youngestSN = 0; - - changedPC = willChangePC = changedNextPC = false; - - exitOnError = p->exitOnError; - warnOnlyOnLoadError = p->warnOnlyOnLoadError; -#if FULL_SYSTEM - itb = p->itb; - dtb = p->dtb; - systemPtr = NULL; -#else - process = p->process; -#endif - - result.integer = 0; -} - -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) -{ -#if FULL_SYSTEM - systemPtr = system; - - thread = new SimpleThread(this, 0, systemPtr, itb, dtb, false); - - thread->setStatus(ThreadContext::Suspended); - tc = thread->getTC(); - threadContexts.push_back(tc); - delete thread->kernelStats; - thread->kernelStats = NULL; -#endif -} - -void -CheckerCPU::setIcachePort(Port *icache_port) -{ - icachePort = icache_port; -} - -void -CheckerCPU::setDcachePort(Port *dcache_port) -{ - dcachePort = dcache_port; -} - -void -CheckerCPU::serialize(ostream &os) -{ -/* - BaseCPU::serialize(os); - SERIALIZE_SCALAR(inst); - nameOut(os, csprintf("%s.xc", name())); - thread->serialize(os); - cacheCompletionEvent.serialize(os); -*/ -} - -void -CheckerCPU::unserialize(Checkpoint *cp, const string §ion) -{ -/* - BaseCPU::unserialize(cp, section); - UNSERIALIZE_SCALAR(inst); - thread->unserialize(cp, csprintf("%s.xc", section)); -*/ -} - -Fault -CheckerCPU::copySrcTranslate(Addr src) -{ - panic("Unimplemented!"); -} - -Fault -CheckerCPU::copy(Addr dest) -{ - panic("Unimplemented!"); -} - -template -Fault -CheckerCPU::read(Addr addr, T &data, unsigned flags) -{ - // need to fill in CPU & thread IDs here - memReq = new Request(); - - memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC()); - - // translate to physical address - translateDataReadReq(memReq); - - Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast); - - pkt->dataStatic(&data); - - if (!(memReq->getFlags() & UNCACHEABLE)) { - // Access memory to see if we have the same data - dcachePort->sendFunctional(pkt); - } else { - // Assume the data is correct if it's an uncached access - memcpy(&data, &unverifiedResult.integer, sizeof(T)); - } - - delete pkt; - - return NoFault; -} - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -template -Fault -CheckerCPU::read(Addr addr, uint64_t &data, unsigned flags); - -template -Fault -CheckerCPU::read(Addr addr, uint32_t &data, unsigned flags); - -template -Fault -CheckerCPU::read(Addr addr, uint16_t &data, unsigned flags); - -template -Fault -CheckerCPU::read(Addr addr, uint8_t &data, unsigned flags); - -#endif //DOXYGEN_SHOULD_SKIP_THIS - -template<> -Fault -CheckerCPU::read(Addr addr, double &data, unsigned flags) -{ - return read(addr, *(uint64_t*)&data, flags); -} - -template<> -Fault -CheckerCPU::read(Addr addr, float &data, unsigned flags) -{ - return read(addr, *(uint32_t*)&data, flags); -} - -template<> -Fault -CheckerCPU::read(Addr addr, int32_t &data, unsigned flags) -{ - return read(addr, (uint32_t&)data, flags); -} - -template -Fault -CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) -{ - // need to fill in CPU & thread IDs here - memReq = new Request(); - - memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC()); - - // translate to physical address - thread->translateDataWriteReq(memReq); - - // Can compare the write data and result only if it's cacheable, - // not a store conditional, or is a store conditional that - // succeeded. - // @todo: Verify that actual memory matches up with these values. - // Right now it only verifies that the instruction data is the - // same as what was in the request that got sent to memory; there - // is no verification that it is the same as what is in memory. - // This is because the LSQ would have to be snooped in the CPU to - // verify this data. - if (unverifiedReq && - !(unverifiedReq->getFlags() & UNCACHEABLE) && - (!(unverifiedReq->getFlags() & LOCKED) || - ((unverifiedReq->getFlags() & LOCKED) && - unverifiedReq->getScResult() == 1))) { - T inst_data; -/* - // This code would work if the LSQ allowed for snooping. - Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast); - pkt.dataStatic(&inst_data); - - dcachePort->sendFunctional(pkt); - - delete pkt; -*/ - memcpy(&inst_data, unverifiedMemData, sizeof(T)); - - if (data != inst_data) { - warn("%lli: Store value does not match value in memory! " - "Instruction: %#x, memory: %#x", - curTick, inst_data, data); - handleError(); - } - } - - // Assume the result was the same as the one passed in. This checker - // doesn't check if the SC should succeed or fail, it just checks the - // value. - if (res && unverifiedReq->scResultValid()) - *res = unverifiedReq->getScResult(); - - return NoFault; -} - - -#ifndef DOXYGEN_SHOULD_SKIP_THIS -template -Fault -CheckerCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res); - -template -Fault -CheckerCPU::write(uint32_t data, Addr addr, unsigned flags, uint64_t *res); - -template -Fault -CheckerCPU::write(uint16_t data, Addr addr, unsigned flags, uint64_t *res); - -template -Fault -CheckerCPU::write(uint8_t data, Addr addr, unsigned flags, uint64_t *res); - -#endif //DOXYGEN_SHOULD_SKIP_THIS - -template<> -Fault -CheckerCPU::write(double data, Addr addr, unsigned flags, uint64_t *res) -{ - return write(*(uint64_t*)&data, addr, flags, res); -} - -template<> -Fault -CheckerCPU::write(float data, Addr addr, unsigned flags, uint64_t *res) -{ - return write(*(uint32_t*)&data, addr, flags, res); -} - -template<> -Fault -CheckerCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res) -{ - return write((uint32_t)data, addr, flags, res); -} - - -#if FULL_SYSTEM -Addr -CheckerCPU::dbg_vtophys(Addr addr) -{ - return vtophys(tc, addr); -} -#endif // FULL_SYSTEM - -bool -CheckerCPU::translateInstReq(Request *req) -{ -#if FULL_SYSTEM - return (thread->translateInstReq(req) == NoFault); -#else - thread->translateInstReq(req); - return true; -#endif -} - -void -CheckerCPU::translateDataReadReq(Request *req) -{ - thread->translateDataReadReq(req); - - if (req->getVaddr() != unverifiedReq->getVaddr()) { - warn("%lli: Request virtual addresses do not match! Inst: %#x, " - "checker: %#x", - curTick, unverifiedReq->getVaddr(), req->getVaddr()); - handleError(); - } - req->setPaddr(unverifiedReq->getPaddr()); - - if (checkFlags(req)) { - warn("%lli: Request flags do not match! Inst: %#x, checker: %#x", - curTick, unverifiedReq->getFlags(), req->getFlags()); - handleError(); - } -} - -void -CheckerCPU::translateDataWriteReq(Request *req) -{ - thread->translateDataWriteReq(req); - - if (req->getVaddr() != unverifiedReq->getVaddr()) { - warn("%lli: Request virtual addresses do not match! Inst: %#x, " - "checker: %#x", - curTick, unverifiedReq->getVaddr(), req->getVaddr()); - handleError(); - } - req->setPaddr(unverifiedReq->getPaddr()); - - if (checkFlags(req)) { - warn("%lli: Request flags do not match! Inst: %#x, checker: %#x", - curTick, unverifiedReq->getFlags(), req->getFlags()); - handleError(); - } -} - -bool -CheckerCPU::checkFlags(Request *req) -{ - // Remove any dynamic flags that don't have to do with the request itself. - unsigned flags = unverifiedReq->getFlags(); - unsigned mask = LOCKED | PHYSICAL | VPTE | ALTMODE | UNCACHEABLE | NO_FAULT; - flags = flags & (mask); - if (flags == req->getFlags()) { - return false; - } else { - return true; - } -} - -void -CheckerCPU::dumpAndExit() -{ - warn("%lli: Checker PC:%#x, next PC:%#x", - curTick, thread->readPC(), thread->readNextPC()); - panic("Checker found an error!"); -} - template void Checker::verify(DynInstPtr &completed_inst) -- cgit v1.2.3