1/*
2 * Copyright (c) 2010-2011 ARM Limited
2 * Copyright (c) 2010-2012 ARM Limited
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated

--- 42 unchanged lines hidden (view full) ---

53#include "arch/vtophys.hh"
54#include "base/types.hh"
55#include "config/the_isa.hh"
56#include "cpu/base.hh"
57//#include "cpu/checker/cpu.hh"
58#include "cpu/o3/fetch.hh"
59#include "cpu/exetrace.hh"
60#include "debug/Activity.hh"
61#include "debug/Drain.hh"
62#include "debug/Fetch.hh"
63#include "mem/packet.hh"
64#include "params/DerivO3CPU.hh"
65#include "sim/byteswap.hh"
66#include "sim/core.hh"
67#include "sim/eventq.hh"
68#include "sim/full_system.hh"
69#include "sim/system.hh"
70
71using namespace std;
72
73template<class Impl>
74DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
75 : cpu(_cpu),
76 branchPred(params),
76 numInst(0),
77 decodeToFetchDelay(params->decodeToFetchDelay),
78 renameToFetchDelay(params->renameToFetchDelay),
79 iewToFetchDelay(params->iewToFetchDelay),
80 commitToFetchDelay(params->commitToFetchDelay),
81 fetchWidth(params->fetchWidth),
82 cacheBlocked(false),
82 retryPkt(NULL),
83 retryTid(InvalidThreadID),
84 numThreads(params->numThreads),
85 numFetchingThreads(params->smtNumFetchingThreads),
87 interruptPending(false),
88 drainPending(false),
89 switchedOut(false),
86 finishTranslationEvent(this)
87{
88 if (numThreads > Impl::MaxThreads)
89 fatal("numThreads (%d) is larger than compiled limit (%d),\n"
90 "\tincrease MaxThreads in src/cpu/o3/impl.hh\n",
91 numThreads, static_cast<int>(Impl::MaxThreads));
92 if (fetchWidth > Impl::MaxWidth)
93 fatal("fetchWidth (%d) is larger than compiled limit (%d),\n"
94 "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
95 fetchWidth, static_cast<int>(Impl::MaxWidth));
96
101 // Set fetch stage's status to inactive.
102 _status = Inactive;
103
97 std::string policy = params->smtFetchPolicy;
98
99 // Convert string to lowercase
100 std::transform(policy.begin(), policy.end(), policy.begin(),
101 (int(*)(int)) tolower);
102
103 // Figure out fetch policy
104 if (policy == "singlethread") {

--- 187 unchanged lines hidden (view full) ---

292 // Create wire to write information to proper place in fetch queue.
293 toDecode = fetchQueue->getWire(0);
294}
295
296template<class Impl>
297void
298DefaultFetch<Impl>::startupStage()
299{
300 assert(priorityList.empty());
301 resetStage();
302
303 // Fetch needs to start fetching instructions at the very beginning,
304 // so it must start up in active state.
305 switchToActive();
306}
307
308template<class Impl>
309void
310DefaultFetch<Impl>::resetStage()
311{
312 numInst = 0;
313 interruptPending = false;
314 cacheBlocked = false;
315
316 priorityList.clear();
317
318 // Setup PC and nextPC with initial state.
319 for (ThreadID tid = 0; tid < numThreads; tid++) {
320 fetchStatus[tid] = Running;
321 pc[tid] = cpu->pcState(tid);
322 fetchOffset[tid] = 0;
323 macroop[tid] = NULL;
312 delayedCommit[tid] = false;
313 }
324
315 for (ThreadID tid = 0; tid < numThreads; tid++) {
316
317 fetchStatus[tid] = Running;
318
319 priorityList.push_back(tid);
320
325 delayedCommit[tid] = false;
326 memReq[tid] = NULL;
327
328 stalls[tid].decode = false;
329 stalls[tid].rename = false;
330 stalls[tid].iew = false;
331 stalls[tid].commit = false;
332 stalls[tid].drain = false;
333
334 priorityList.push_back(tid);
335 }
336
329 // Schedule fetch to get the correct PC from the CPU
330 // scheduleFetchStartupEvent(1);
337 wroteToTimeBuffer = false;
338 _status = Inactive;
339
332 // Fetch needs to start fetching instructions at the very beginning,
333 // so it must start up in active state.
334 switchToActive();
340 // this CPU could still be unconnected if we are restoring from a
341 // checkpoint and this CPU is to be switched in, thus we can only
342 // do this here if the instruction port is actually connected, if
343 // not we have to do it as part of takeOverFrom.
344 if (cpu->getInstPort().isConnected())
345 setIcache();
346}
347
348template<class Impl>
349void
350DefaultFetch<Impl>::setIcache()
351{
352 assert(cpu->getInstPort().isConnected());
353

--- 14 unchanged lines hidden (view full) ---

368
369template<class Impl>
370void
371DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
372{
373 ThreadID tid = pkt->req->threadId();
374
375 DPRINTF(Fetch, "[tid:%u] Waking up from cache miss.\n", tid);
376 assert(!cpu->switchedOut());
377
378 // Only change the status if it's still waiting on the icache access
379 // to return.
380 if (fetchStatus[tid] != IcacheWaitResponse ||
369 pkt->req != memReq[tid] ||
370 isSwitchedOut()) {
381 pkt->req != memReq[tid]) {
382 ++fetchIcacheSquashes;
383 delete pkt->req;
384 delete pkt;
385 return;
386 }
387
388 memcpy(cacheData[tid], pkt->getPtr<uint8_t>(), cacheBlkSize);
389 cacheDataValid[tid] = true;
390
380 if (!drainPending) {
381 // Wake up the CPU (if it went to sleep and was waiting on
382 // this completion event).
383 cpu->wakeCPU();
391 // Wake up the CPU (if it went to sleep and was waiting on
392 // this completion event).
393 cpu->wakeCPU();
394
385 DPRINTF(Activity, "[tid:%u] Activating fetch due to cache completion\n",
386 tid);
395 DPRINTF(Activity, "[tid:%u] Activating fetch due to cache completion\n",
396 tid);
397
388 switchToActive();
389 }
398 switchToActive();
399
400 // Only switch to IcacheAccessComplete if we're not stalled as well.
401 if (checkStall(tid)) {
402 fetchStatus[tid] = Blocked;
403 } else {
404 fetchStatus[tid] = IcacheAccessComplete;
405 }
406
407 // Reset the mem req to NULL.
408 delete pkt->req;
409 delete pkt;
410 memReq[tid] = NULL;
411}
412
413template <class Impl>
405bool
406DefaultFetch::drain()
414void
415DefaultFetch<Impl>::drainResume()
416{
408 // Fetch is ready to drain at any time.
409 cpu->signalDrained();
410 drainPending = true;
411 return true;
417 for (ThreadID i = 0; i < Impl::MaxThreads; ++i)
418 stalls[i].drain = false;
419}
420
421template <class Impl>
422void
416DefaultFetch<Impl>::resume()
423DefaultFetch<Impl>::drainSanityCheck() const
424{
418 drainPending = false;
425 assert(isDrained());
426 assert(retryPkt == NULL);
427 assert(retryTid == InvalidThreadID);
428 assert(cacheBlocked == false);
429 assert(interruptPending == false);
430
431 for (ThreadID i = 0; i < numThreads; ++i) {
432 assert(!memReq[i]);
433 assert(!stalls[i].decode);
434 assert(!stalls[i].rename);
435 assert(!stalls[i].iew);
436 assert(!stalls[i].commit);
437 assert(fetchStatus[i] == Idle || stalls[i].drain);
438 }
439
440 branchPred.drainSanityCheck();
441}
442
443template <class Impl>
422void
423DefaultFetch<Impl>::switchOut()
444bool
445DefaultFetch<Impl>::isDrained() const
446{
425 switchedOut = true;
426 // Branch predictor needs to have its state cleared.
427 branchPred.switchOut();
447 /* Make sure that threads are either idle of that the commit stage
448 * has signaled that draining has completed by setting the drain
449 * stall flag. This effectively forces the pipeline to be disabled
450 * until the whole system is drained (simulation may continue to
451 * drain other components).
452 */
453 for (ThreadID i = 0; i < numThreads; ++i) {
454 if (!(fetchStatus[i] == Idle ||
455 (fetchStatus[i] == Blocked && stalls[i].drain)))
456 return false;
457 }
458
459 /* The pipeline might start up again in the middle of the drain
460 * cycle if the finish translation event is scheduled, so make
461 * sure that's not the case.
462 */
463 return !finishTranslationEvent.scheduled();
464}
465
466template <class Impl>
467void
468DefaultFetch<Impl>::takeOverFrom()
469{
434 // the instruction port is now connected so we can get the block
435 // size
436 setIcache();
470 assert(cpu->getInstPort().isConnected());
471 resetStage();
472
438 // Reset all state
439 for (ThreadID i = 0; i < Impl::MaxThreads; ++i) {
440 stalls[i].decode = 0;
441 stalls[i].rename = 0;
442 stalls[i].iew = 0;
443 stalls[i].commit = 0;
444 pc[i] = cpu->pcState(i);
445 fetchStatus[i] = Running;
446 }
447 numInst = 0;
448 wroteToTimeBuffer = false;
449 _status = Inactive;
450 switchedOut = false;
451 interruptPending = false;
473 branchPred.takeOverFrom();
474}
475
476template <class Impl>
477void
478DefaultFetch<Impl>::drainStall(ThreadID tid)
479{
480 assert(cpu->isDraining());
481 assert(!stalls[tid].drain);
482 DPRINTF(Drain, "%i: Thread drained.\n", tid);
483 stalls[tid].drain = true;
484}
485
486template <class Impl>
487void
488DefaultFetch<Impl>::wakeFromQuiesce()
489{
490 DPRINTF(Fetch, "Waking up from quiesce\n");
491 // Hopefully this is safe
492 // @todo: Allow other threads to wake from quiesce.
493 fetchStatus[0] = Running;
494}
495

--- 66 unchanged lines hidden (view full) ---

562}
563
564template <class Impl>
565bool
566DefaultFetch<Impl>::fetchCacheLine(Addr vaddr, ThreadID tid, Addr pc)
567{
568 Fault fault = NoFault;
569
570 assert(!cpu->switchedOut());
571
572 // @todo: not sure if these should block translation.
573 //AlphaDep
574 if (cacheBlocked) {
575 DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, cache blocked\n",
576 tid);
577 return false;
545 } else if (isSwitchedOut()) {
546 DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, switched out\n",
547 tid);
548 return false;
578 } else if (checkInterrupt(pc) && !delayedCommit[tid]) {
579 // Hold off fetch from getting new instructions when:
580 // Cache is blocked, or
581 // while an interrupt is pending and we're not in PAL mode, or
582 // fetch is switched out.
583 DPRINTF(Fetch, "[tid:%i] Can't fetch cache line, interrupt pending\n",
584 tid);
585 return false;

--- 24 unchanged lines hidden (view full) ---

610
611template <class Impl>
612void
613DefaultFetch<Impl>::finishTranslation(Fault fault, RequestPtr mem_req)
614{
615 ThreadID tid = mem_req->threadId();
616 Addr block_PC = mem_req->getVaddr();
617
618 assert(!cpu->switchedOut());
619
620 // Wake up CPU if it was idle
621 cpu->wakeCPU();
622
623 if (fetchStatus[tid] != ItlbWait || mem_req != memReq[tid] ||
593 mem_req->getVaddr() != memReq[tid]->getVaddr() || isSwitchedOut()) {
624 mem_req->getVaddr() != memReq[tid]->getVaddr()) {
625 DPRINTF(Fetch, "[tid:%i] Ignoring itlb completed after squash\n",
626 tid);
627 ++fetchTlbSquashes;
628 delete mem_req;
629 return;
630 }
631
632

--- 150 unchanged lines hidden (view full) ---

783bool
784DefaultFetch<Impl>::checkStall(ThreadID tid) const
785{
786 bool ret_val = false;
787
788 if (cpu->contextSwitch) {
789 DPRINTF(Fetch,"[tid:%i]: Stalling for a context switch.\n",tid);
790 ret_val = true;
791 } else if (stalls[tid].drain) {
792 assert(cpu->isDraining());
793 DPRINTF(Fetch,"[tid:%i]: Drain stall detected.\n",tid);
794 ret_val = true;
795 } else if (stalls[tid].decode) {
796 DPRINTF(Fetch,"[tid:%i]: Stall from Decode stage detected.\n",tid);
797 ret_val = true;
798 } else if (stalls[tid].rename) {
799 DPRINTF(Fetch,"[tid:%i]: Stall from Rename stage detected.\n",tid);
800 ret_val = true;
801 } else if (stalls[tid].iew) {
802 DPRINTF(Fetch,"[tid:%i]: Stall from IEW stage detected.\n",tid);

--- 324 unchanged lines hidden (view full) ---

1127void
1128DefaultFetch<Impl>::fetch(bool &status_change)
1129{
1130 //////////////////////////////////////////
1131 // Start actual fetch
1132 //////////////////////////////////////////
1133 ThreadID tid = getFetchingThread(fetchPolicy);
1134
1100 if (tid == InvalidThreadID || drainPending) {
1135 assert(!cpu->switchedOut());
1136
1137 if (tid == InvalidThreadID) {
1138 // Breaks looping condition in tick()
1139 threadFetched = numFetchingThreads;
1140
1141 if (numThreads == 1) { // @todo Per-thread stats
1142 profileStall(0);
1143 }
1144
1145 return;

--- 33 unchanged lines hidden (view full) ---

1179
1180 if (fetchStatus[tid] == IcacheWaitResponse)
1181 ++icacheStallCycles;
1182 else if (fetchStatus[tid] == ItlbWait)
1183 ++fetchTlbCycles;
1184 else
1185 ++fetchMiscStallCycles;
1186 return;
1150 } else if ((checkInterrupt(thisPC.instAddr()) && !delayedCommit[tid])
1151 || isSwitchedOut()) {
1187 } else if ((checkInterrupt(thisPC.instAddr()) && !delayedCommit[tid])) {
1188 // Stall CPU if an interrupt is posted and we're not issuing
1189 // an delayed commit micro-op currently (delayed commit instructions
1190 // are not interruptable by interrupts, only faults)
1191 ++fetchMiscStallCycles;
1192 DPRINTF(Fetch, "[tid:%i]: Fetch is stalled!\n", tid);
1193 return;
1194 }
1195 } else {

--- 401 unchanged lines hidden (view full) ---

1597
1598template<class Impl>
1599void
1600DefaultFetch<Impl>::profileStall(ThreadID tid) {
1601 DPRINTF(Fetch,"There are no more threads available to fetch from.\n");
1602
1603 // @todo Per-thread stats
1604
1569 if (drainPending) {
1605 if (stalls[tid].drain) {
1606 ++fetchPendingDrainCycles;
1607 DPRINTF(Fetch, "Fetch is waiting for a drain!\n");
1608 } else if (activeThreads->empty()) {
1609 ++fetchNoActiveThreadStallCycles;
1610 DPRINTF(Fetch, "Fetch has no active thread!\n");
1611 } else if (fetchStatus[tid] == Blocked) {
1612 ++fetchBlockedCycles;
1613 DPRINTF(Fetch, "[tid:%i]: Fetch is blocked!\n", tid);

--- 31 unchanged lines hidden ---