diff options
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/checker/thread_context.hh | 2 | ||||
-rw-r--r-- | src/cpu/memtest/memtest.cc | 61 | ||||
-rw-r--r-- | src/cpu/memtest/memtest.hh | 10 | ||||
-rw-r--r-- | src/cpu/o3/commit_impl.hh | 12 | ||||
-rw-r--r-- | src/cpu/o3/cpu.cc | 71 | ||||
-rw-r--r-- | src/cpu/o3/cpu.hh | 19 | ||||
-rw-r--r-- | src/cpu/o3/fetch_impl.hh | 5 | ||||
-rw-r--r-- | src/cpu/o3/iew_impl.hh | 6 | ||||
-rw-r--r-- | src/cpu/o3/lsq_unit.hh | 40 | ||||
-rw-r--r-- | src/cpu/o3/lsq_unit_impl.hh | 24 | ||||
-rwxr-xr-x | src/cpu/o3/thread_context_impl.hh | 6 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 32 | ||||
-rw-r--r-- | src/cpu/simple/timing.hh | 1 |
13 files changed, 212 insertions, 77 deletions
diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh index 8c0186dae..b2806d40b 100644 --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@ -133,7 +133,7 @@ class CheckerThreadContext : public ThreadContext void takeOverFrom(ThreadContext *oldContext) { actualTC->takeOverFrom(oldContext); - checkerTC->takeOverFrom(oldContext); + checkerTC->copyState(oldContext); } void regStats(const std::string &name) { actualTC->regStats(name); } diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc index 609a07a8e..024cd7e41 100644 --- a/src/cpu/memtest/memtest.cc +++ b/src/cpu/memtest/memtest.cc @@ -71,7 +71,11 @@ MemTest::CpuPort::recvAtomic(Packet *pkt) void MemTest::CpuPort::recvFunctional(Packet *pkt) { - memtest->completeRequest(pkt); + //Do nothing if we see one come through + if (curTick != 0)//Supress warning durring initialization + warn("Functional Writes not implemented in MemTester\n"); + //Need to find any response values that intersect and update + return; } void @@ -89,6 +93,20 @@ MemTest::CpuPort::recvRetry() memtest->doRetry(); } +void +MemTest::sendPkt(Packet *pkt) { + if (atomic) { + cachePort.sendAtomic(pkt); + pkt->makeAtomicResponse(); + completeRequest(pkt); + } + else if (!cachePort.sendTiming(pkt)) { + accessRetry = true; + retryPkt = pkt; + } + +} + MemTest::MemTest(const string &name, // MemInterface *_cache_interface, // PhysicalMemory *main_mem, @@ -101,7 +119,8 @@ MemTest::MemTest(const string &name, unsigned _percentSourceUnaligned, unsigned _percentDestUnaligned, Addr _traceAddr, - Counter _max_loads) + Counter _max_loads, + bool _atomic) : MemObject(name), tickEvent(this), cachePort("test", this), @@ -117,7 +136,8 @@ MemTest::MemTest(const string &name, nextProgressMessage(_progressInterval), percentSourceUnaligned(_percentSourceUnaligned), percentDestUnaligned(percentDestUnaligned), - maxLoads(_max_loads) + maxLoads(_max_loads), + atomic(_atomic) { vector<string> cmd; cmd.push_back("/bin/ls"); @@ -325,7 +345,7 @@ MemTest::tick() } else { paddr = ((base) ? baseAddr1 : baseAddr2) + offset; } - // bool probe = (random() % 2 == 1) && !req->isUncacheable(); + //bool probe = (random() % 2 == 1) && !req->isUncacheable(); bool probe = false; paddr &= ~((1 << access_size) - 1); @@ -340,7 +360,11 @@ MemTest::tick() //For now we only allow one outstanding request per addreess per tester //This means we assume CPU does write forwarding to reads that alias something //in the cpu store buffer. - if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) return; + if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) { + delete result; + delete req; + return; + } else outstandingAddrs.insert(paddr); // ***** NOTE FOR RON: I'm not sure how to access checkMem. - Kevin @@ -364,13 +388,10 @@ MemTest::tick() if (probe) { cachePort.sendFunctional(pkt); -// completeRequest(pkt, result); + completeRequest(pkt); } else { // req->completionEvent = new MemCompleteEvent(req, result, this); - if (!cachePort.sendTiming(pkt)) { - accessRetry = true; - retryPkt = pkt; - } + sendPkt(pkt); } } else { // write @@ -378,7 +399,12 @@ MemTest::tick() //For now we only allow one outstanding request per addreess per tester //This means we assume CPU does write forwarding to reads that alias something //in the cpu store buffer. - if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) return; + if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) { + delete [] result; + delete req; + return; + } + else outstandingAddrs.insert(paddr); /* @@ -405,13 +431,10 @@ MemTest::tick() if (probe) { cachePort.sendFunctional(pkt); -// completeRequest(req, NULL); + completeRequest(pkt); } else { // req->completionEvent = new MemCompleteEvent(req, NULL, this); - if (!cachePort.sendTiming(pkt)) { - accessRetry = true; - retryPkt = pkt; - } + sendPkt(pkt); } } /* else { @@ -483,6 +506,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest) Param<unsigned> percent_dest_unaligned; Param<Addr> trace_addr; Param<Counter> max_loads; + Param<bool> atomic; END_DECLARE_SIM_OBJECT_PARAMS(MemTest) @@ -502,7 +526,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(MemTest) INIT_PARAM(percent_dest_unaligned, "percent of copy dest address that are unaligned"), INIT_PARAM(trace_addr, "address to trace"), - INIT_PARAM(max_loads, "terminate when we have reached this load count") + INIT_PARAM(max_loads, "terminate when we have reached this load count"), + INIT_PARAM(atomic, "Is the tester testing atomic mode (or timing)") END_INIT_SIM_OBJECT_PARAMS(MemTest) @@ -513,7 +538,7 @@ CREATE_SIM_OBJECT(MemTest) /*check_mem,*/ memory_size, percent_reads, /*percent_copies,*/ percent_uncacheable, progress_interval, percent_source_unaligned, percent_dest_unaligned, - trace_addr, max_loads); + trace_addr, max_loads, atomic); } REGISTER_SIM_OBJECT("MemTest", MemTest) diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh index 278012eba..5de41f0d8 100644 --- a/src/cpu/memtest/memtest.hh +++ b/src/cpu/memtest/memtest.hh @@ -61,7 +61,8 @@ class MemTest : public MemObject unsigned _percentSourceUnaligned, unsigned _percentDestUnaligned, Addr _traceAddr, - Counter _max_loads); + Counter _max_loads, + bool _atomic); virtual void init(); @@ -113,7 +114,7 @@ class MemTest : public MemObject virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) - { resp.clear(); snoop.clear(); } + { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); } }; CpuPort cachePort; @@ -175,6 +176,9 @@ class MemTest : public MemObject uint64_t numReads; uint64_t maxLoads; + + bool atomic; + Stats::Scalar<> numReadsStat; Stats::Scalar<> numWritesStat; Stats::Scalar<> numCopiesStat; @@ -182,6 +186,8 @@ class MemTest : public MemObject // called by MemCompleteEvent::process() void completeRequest(Packet *pkt); + void sendPkt(Packet *pkt); + void doRetry(); friend class MemCompleteEvent; diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index c80e4d8c1..ecf6ed632 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -342,12 +342,6 @@ DefaultCommit<Impl>::drain() { drainPending = true; - // If it's already drained, return true. - if (rob->isEmpty() && !iewStage->hasStoresToWB()) { - cpu->signalDrained(); - return true; - } - return false; } @@ -1218,16 +1212,16 @@ DefaultCommit<Impl>::skidInsert() for (int inst_num = 0; inst_num < fromRename->size; ++inst_num) { DynInstPtr inst = fromRename->insts[inst_num]; - int tid = inst->threadNumber; if (!inst->isSquashed()) { DPRINTF(Commit, "Inserting PC %#x [sn:%i] [tid:%i] into ", - "skidBuffer.\n", inst->readPC(), inst->seqNum, tid); + "skidBuffer.\n", inst->readPC(), inst->seqNum, + inst->threadNumber); skidBuffer.push(inst); } else { DPRINTF(Commit, "Instruction PC %#x [sn:%i] [tid:%i] was " "squashed, skipping.\n", - inst->readPC(), inst->seqNum, tid); + inst->readPC(), inst->seqNum, inst->threadNumber); } } } diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 7386dfadd..4c9a8e91f 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -88,7 +88,7 @@ FullO3CPU<Impl>::TickEvent::description() template <class Impl> FullO3CPU<Impl>::ActivateThreadEvent::ActivateThreadEvent() - : Event(&mainEventQueue, CPU_Tick_Pri) + : Event(&mainEventQueue, CPU_Switch_Pri) { } @@ -135,7 +135,8 @@ void FullO3CPU<Impl>::DeallocateContextEvent::process() { cpu->deactivateThread(tid); - cpu->removeThread(tid); + if (remove) + cpu->removeThread(tid); } template <class Impl> @@ -191,7 +192,11 @@ FullO3CPU<Impl>::FullO3CPU(Params *params) deferRegistration(params->deferRegistration), numThreads(number_of_threads) { - _status = Idle; + if (!deferRegistration) { + _status = Running; + } else { + _status = Idle; + } checker = NULL; @@ -304,6 +309,9 @@ FullO3CPU<Impl>::FullO3CPU(Params *params) tid, bindRegs); + + activateThreadEvent[tid].init(tid, this); + deallocateContextEvent[tid].init(tid, this); } rename.setRenameMap(renameMap); @@ -447,13 +455,16 @@ FullO3CPU<Impl>::tick() if (!tickEvent.scheduled()) { if (_status == SwitchedOut || getState() == SimObject::Drained) { + DPRINTF(O3CPU, "Switched out!\n"); // increment stat lastRunningCycle = curTick; - } else if (!activityRec.active()) { + } else if (!activityRec.active() || _status == Idle) { + DPRINTF(O3CPU, "Idle!\n"); lastRunningCycle = curTick; timesIdled++; } else { tickEvent.schedule(curTick + cycles(1)); + DPRINTF(O3CPU, "Scheduling next tick!\n"); } } @@ -512,6 +523,8 @@ FullO3CPU<Impl>::activateThread(unsigned tid) list<unsigned>::iterator isActive = find( activeThreads.begin(), activeThreads.end(), tid); + DPRINTF(O3CPU, "[tid:%i]: Calling activate thread.\n", tid); + if (isActive == activeThreads.end()) { DPRINTF(O3CPU, "[tid:%i]: Adding to active threads list\n", tid); @@ -528,6 +541,8 @@ FullO3CPU<Impl>::deactivateThread(unsigned tid) list<unsigned>::iterator thread_it = find(activeThreads.begin(), activeThreads.end(), tid); + DPRINTF(O3CPU, "[tid:%i]: Calling deactivate thread.\n", tid); + if (thread_it != activeThreads.end()) { DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n", tid); @@ -548,7 +563,7 @@ FullO3CPU<Impl>::activateContext(int tid, int delay) activateThread(tid); } - if(lastActivatedCycle < curTick) { + if (lastActivatedCycle < curTick) { scheduleTickEvent(delay); // Be sure to signal that there's some activity so the CPU doesn't @@ -563,17 +578,20 @@ FullO3CPU<Impl>::activateContext(int tid, int delay) } template <class Impl> -void -FullO3CPU<Impl>::deallocateContext(int tid, int delay) +bool +FullO3CPU<Impl>::deallocateContext(int tid, bool remove, int delay) { // Schedule removal of thread data from CPU if (delay){ DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to deallocate " "on cycle %d\n", tid, curTick + cycles(delay)); - scheduleDeallocateContextEvent(tid, delay); + scheduleDeallocateContextEvent(tid, remove, delay); + return false; } else { deactivateThread(tid); - removeThread(tid); + if (remove) + removeThread(tid); + return true; } } @@ -582,8 +600,9 @@ void FullO3CPU<Impl>::suspendContext(int tid) { DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid); - deactivateThread(tid); - if (activeThreads.size() == 0) + bool deallocated = deallocateContext(tid, false, 1); + // If this was the last thread then unschedule the tick event. + if ((activeThreads.size() == 1 && !deallocated) || activeThreads.size() == 0) unscheduleTickEvent(); _status = Idle; } @@ -594,7 +613,7 @@ FullO3CPU<Impl>::haltContext(int tid) { //For now, this is the same as deallocate DPRINTF(O3CPU,"[tid:%i]: Halt Context called. Deallocating", tid); - deallocateContext(tid, 1); + deallocateContext(tid, true, 1); } template <class Impl> @@ -682,10 +701,17 @@ FullO3CPU<Impl>::removeThread(unsigned tid) assert(iew.ldstQueue.getCount(tid) == 0); // Reset ROB/IQ/LSQ Entries + + // Commented out for now. This should be possible to do by + // telling all the pipeline stages to drain first, and then + // checking until the drain completes. Once the pipeline is + // drained, call resetEntries(). - 10-09-06 ktlim +/* if (activeThreads.size() >= 1) { commit.rob->resetEntries(); iew.resetEntries(); } +*/ } @@ -824,7 +850,9 @@ template <class Impl> void FullO3CPU<Impl>::resume() { +#if FULL_SYSTEM assert(system->getMemoryMode() == System::Timing); +#endif fetch.resume(); decode.resume(); rename.resume(); @@ -935,6 +963,25 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU) } if (!tickEvent.scheduled()) tickEvent.schedule(curTick); + + Port *peer; + Port *icachePort = fetch.getIcachePort(); + if (icachePort->getPeer() == NULL) { + peer = oldCPU->getPort("icache_port")->getPeer(); + icachePort->setPeer(peer); + } else { + peer = icachePort->getPeer(); + } + peer->setPeer(icachePort); + + Port *dcachePort = iew.getDcachePort(); + if (dcachePort->getPeer() == NULL) { + peer = oldCPU->getPort("dcache_port")->getPeer(); + dcachePort->setPeer(peer); + } else { + peer = dcachePort->getPeer(); + } + peer->setPeer(dcachePort); } template <class Impl> diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index dcdcd1fe6..fe510519c 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -202,9 +202,12 @@ class FullO3CPU : public BaseO3CPU class DeallocateContextEvent : public Event { private: - /** Number of Thread to Activate */ + /** Number of Thread to deactivate */ int tid; + /** Should the thread be removed from the CPU? */ + bool remove; + /** Pointer to the CPU. */ FullO3CPU<Impl> *cpu; @@ -218,12 +221,15 @@ class FullO3CPU : public BaseO3CPU /** Processes the event, calling activateThread() on the CPU. */ void process(); + /** Sets whether the thread should also be removed from the CPU. */ + void setRemove(bool _remove) { remove = _remove; } + /** Returns the description of the event. */ const char *description(); }; /** Schedule cpu to deallocate thread context.*/ - void scheduleDeallocateContextEvent(int tid, int delay) + void scheduleDeallocateContextEvent(int tid, bool remove, int delay) { // Schedule thread to activate, regardless of its current state. if (deallocateContextEvent[tid].squashed()) @@ -296,9 +302,9 @@ class FullO3CPU : public BaseO3CPU void suspendContext(int tid); /** Remove Thread from Active Threads List && - * Remove Thread Context from CPU. + * Possibly Remove Thread Context from CPU. */ - void deallocateContext(int tid, int delay = 1); + bool deallocateContext(int tid, bool remove, int delay = 1); /** Remove Thread from Active Threads List && * Remove Thread Context from CPU. @@ -626,11 +632,6 @@ class FullO3CPU : public BaseO3CPU /** Pointers to all of the threads in the CPU. */ std::vector<Thread *> thread; - /** Pointer to the icache interface. */ - MemInterface *icacheInterface; - /** Pointer to the dcache interface. */ - MemInterface *dcacheInterface; - /** Whether or not the CPU should defer its registration. */ bool deferRegistration; diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index b3c3caaad..32210f1cd 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -623,6 +623,11 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid // Now do the timing access to see whether or not the instruction // exists within the cache. if (!icachePort->sendTiming(data_pkt)) { + if (data_pkt->result == Packet::BadAddress) { + fault = TheISA::genMachineCheckFault(); + delete mem_req; + memReq[tid] = NULL; + } assert(retryPkt == NULL); assert(retryTid == -1); DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid); diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index b2baae296..ba5260fe2 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -600,6 +600,11 @@ template<class Impl> void DefaultIEW<Impl>::instToCommit(DynInstPtr &inst) { + // This function should not be called after writebackInsts in a + // single cycle. That will cause problems with an instruction + // being added to the queue to commit without being processed by + // writebackInsts prior to being sent to commit. + // First check the time slot that this instruction will write // to. If there are free write ports at the time, then go ahead // and write the instruction to that time. If there are not, @@ -1286,6 +1291,7 @@ DefaultIEW<Impl>::executeInsts() } else if (fault != NoFault) { // If the instruction faulted, then we need to send it along to commit // without the instruction completing. + DPRINTF(IEW, "Store has fault! [sn:%lli]\n", inst->seqNum); // Send this instruction to commit, also make sure iew stage // realizes there is activity. diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh index 58945f04e..11a02e7c7 100644 --- a/src/cpu/o3/lsq_unit.hh +++ b/src/cpu/o3/lsq_unit.hh @@ -626,18 +626,30 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx) ++usedPorts; - PacketPtr data_pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast); - data_pkt->dataStatic(load_inst->memData); - - LSQSenderState *state = new LSQSenderState; - state->isLoad = true; - state->idx = load_idx; - state->inst = load_inst; - data_pkt->senderState = state; - // if we the cache is not blocked, do cache access if (!lsq->cacheBlocked()) { + PacketPtr data_pkt = + new Packet(req, Packet::ReadReq, Packet::Broadcast); + data_pkt->dataStatic(load_inst->memData); + + LSQSenderState *state = new LSQSenderState; + state->isLoad = true; + state->idx = load_idx; + state->inst = load_inst; + data_pkt->senderState = state; + if (!dcachePort->sendTiming(data_pkt)) { + Packet::Result result = data_pkt->result; + + // Delete state and data packet because a load retry + // initiates a pipeline restart; it does not retry. + delete state; + delete data_pkt; + + if (result == Packet::BadAddress) { + return TheISA::genMachineCheckFault(); + } + // If the access didn't succeed, tell the LSQ by setting // the retry thread id. lsq->setRetryTid(lsqID); @@ -664,16 +676,6 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx) return NoFault; } - if (data_pkt->result != Packet::Success) { - DPRINTF(LSQUnit, "LSQUnit: D-cache miss!\n"); - DPRINTF(Activity, "Activity: ld accessing mem miss [sn:%lli]\n", - load_inst->seqNum); - } else { - DPRINTF(LSQUnit, "LSQUnit: D-cache hit!\n"); - DPRINTF(Activity, "Activity: ld accessing mem hit [sn:%lli]\n", - load_inst->seqNum); - } - return NoFault; } diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index 63ffcece1..3f9db912f 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -608,9 +608,9 @@ LSQUnit<Impl>::writebackStores() DPRINTF(LSQUnit, "D-Cache: Writing back store idx:%i PC:%#x " "to Addr:%#x, data:%#x [sn:%lli]\n", - storeWBIdx, storeQueue[storeWBIdx].inst->readPC(), + storeWBIdx, inst->readPC(), req->getPaddr(), *(inst->memData), - storeQueue[storeWBIdx].inst->seqNum); + inst->seqNum); // @todo: Remove this SC hack once the memory system handles it. if (req->isLocked()) { @@ -619,10 +619,19 @@ LSQUnit<Impl>::writebackStores() } else { if (cpu->lockFlag) { req->setScResult(1); + DPRINTF(LSQUnit, "Store conditional [sn:%lli] succeeded.", + inst->seqNum); } else { req->setScResult(0); // Hack: Instantly complete this store. - completeDataAccess(data_pkt); +// completeDataAccess(data_pkt); + DPRINTF(LSQUnit, "Store conditional [sn:%lli] failed. " + "Instantly completing it.\n", + inst->seqNum); + WritebackEvent *wb = new WritebackEvent(inst, data_pkt, this); + wb->schedule(curTick + 1); + delete state; + completeStore(storeWBIdx); incrStIdx(storeWBIdx); continue; } @@ -633,7 +642,13 @@ LSQUnit<Impl>::writebackStores() } if (!dcachePort->sendTiming(data_pkt)) { + if (data_pkt->result == Packet::BadAddress) { + panic("LSQ sent out a bad address for a completed store!"); + } // Need to handle becoming blocked on a store. + DPRINTF(IEW, "D-Cache became blcoked when writing [sn:%lli], will" + "retry later\n", + inst->seqNum); isStoreBlocked = true; ++lsqCacheBlocked; assert(retryPkt == NULL); @@ -880,6 +895,9 @@ LSQUnit<Impl>::recvRetry() assert(retryPkt != NULL); if (dcachePort->sendTiming(retryPkt)) { + if (retryPkt->result == Packet::BadAddress) { + panic("LSQ sent out a bad address for a completed store!"); + } storePostSend(retryPkt); retryPkt = NULL; isStoreBlocked = false; diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index 25e1db21c..2bc194d53 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -165,14 +165,14 @@ template <class Impl> void O3ThreadContext<Impl>::deallocate(int delay) { - DPRINTF(O3CPU, "Calling deallocate on Thread Context %d\n", - getThreadNum()); + DPRINTF(O3CPU, "Calling deallocate on Thread Context %d delay %d\n", + getThreadNum(), delay); if (thread->status() == ThreadContext::Unallocated) return; thread->setStatus(ThreadContext::Unallocated); - cpu->deallocateContext(thread->readTid(), delay); + cpu->deallocateContext(thread->readTid(), true, delay); } template <class Impl> diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 88aa882e3..ad5c0e5d6 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -103,6 +103,7 @@ TimingSimpleCPU::TimingSimpleCPU(Params *p) ifetch_pkt = dcache_pkt = NULL; drainEvent = NULL; fetchEvent = NULL; + previousTick = 0; changeState(SimObject::Running); } @@ -162,6 +163,7 @@ TimingSimpleCPU::resume() } changeState(SimObject::Running); + previousTick = curTick; } void @@ -169,6 +171,7 @@ TimingSimpleCPU::switchOut() { assert(status() == Running || status() == Idle); _status = SwitchedOut; + numCycles += curTick - previousTick; // If we've been scheduled to resume but are then told to switch out, // we'll need to cancel it. @@ -195,6 +198,23 @@ TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU) if (_status != Running) { _status = Idle; } + + Port *peer; + if (icachePort.getPeer() == NULL) { + peer = oldCPU->getPort("icache_port")->getPeer(); + icachePort.setPeer(peer); + } else { + peer = icachePort.getPeer(); + } + peer->setPeer(&icachePort); + + if (dcachePort.getPeer() == NULL) { + peer = oldCPU->getPort("dcache_port")->getPeer(); + dcachePort.setPeer(peer); + } else { + peer = dcachePort.getPeer(); + } + peer->setPeer(&dcachePort); } @@ -429,6 +449,9 @@ TimingSimpleCPU::fetch() // fetch fault: advance directly to next instruction (fault handler) advanceInst(fault); } + + numCycles += curTick - previousTick; + previousTick = curTick; } @@ -459,6 +482,9 @@ TimingSimpleCPU::completeIfetch(Packet *pkt) delete pkt->req; delete pkt; + numCycles += curTick - previousTick; + previousTick = curTick; + if (getState() == SimObject::Draining) { completeDrain(); return; @@ -538,6 +564,9 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt) assert(_status == DcacheWaitResponse); _status = Running; + numCycles += curTick - previousTick; + previousTick = curTick; + Fault fault = curStaticInst->completeAcc(pkt, this, traceData); if (pkt->isRead() && pkt->req->isLocked()) { @@ -547,6 +576,8 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt) delete pkt->req; delete pkt; + postExecute(); + if (getState() == SimObject::Draining) { advancePC(fault); completeDrain(); @@ -554,7 +585,6 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt) return; } - postExecute(); advanceInst(fault); } diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh index 18e13aeb2..988ddeded 100644 --- a/src/cpu/simple/timing.hh +++ b/src/cpu/simple/timing.hh @@ -167,6 +167,7 @@ class TimingSimpleCPU : public BaseSimpleCPU Packet *dcache_pkt; int cpu_id; + Tick previousTick; public: |