diff options
Diffstat (limited to 'src/cpu/o3')
-rw-r--r-- | src/cpu/o3/O3CPU.py | 3 | ||||
-rw-r--r-- | src/cpu/o3/cpu.cc | 65 | ||||
-rw-r--r-- | src/cpu/o3/cpu.hh | 87 | ||||
-rw-r--r-- | src/cpu/o3/fetch.hh | 56 | ||||
-rw-r--r-- | src/cpu/o3/fetch_impl.hh | 87 | ||||
-rw-r--r-- | src/cpu/o3/iew.hh | 3 | ||||
-rw-r--r-- | src/cpu/o3/lsq.hh | 76 | ||||
-rw-r--r-- | src/cpu/o3/lsq_impl.hh | 129 |
8 files changed, 243 insertions, 263 deletions
diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py index 2a5b6782f..9dfcc8b9e 100644 --- a/src/cpu/o3/O3CPU.py +++ b/src/cpu/o3/O3CPU.py @@ -53,9 +53,6 @@ class DerivO3CPU(BaseCPU): checker.dtb = Parent.dtb cachePorts = Param.Unsigned(200, "Cache Ports") - icache_port = Port("Instruction Port") - dcache_port = Port("Data Port") - _cached_ports = BaseCPU._cached_ports + ['icache_port', 'dcache_port'] decodeToFetchDelay = Param.Unsigned(1, "Decode to fetch delay") renameToFetchDelay = Param.Unsigned(1 ,"Rename to fetch delay") diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index ee0c3a88a..7e0b4cee7 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2011 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2004-2006 The Regents of The University of Michigan * Copyright (c) 2011 Regents of the University of California * All rights reserved. @@ -79,6 +91,42 @@ BaseO3CPU::regStats() BaseCPU::regStats(); } +template<class Impl> +bool +FullO3CPU<Impl>::IcachePort::recvTiming(PacketPtr pkt) +{ + DPRINTF(O3CPU, "Fetch unit received timing\n"); + if (pkt->isResponse()) { + // We shouldn't ever get a block in ownership state + assert(!(pkt->memInhibitAsserted() && !pkt->sharedAsserted())); + + fetch->processCacheCompletion(pkt); + } + //else Snooped a coherence request, just return + return true; +} + +template<class Impl> +void +FullO3CPU<Impl>::IcachePort::recvRetry() +{ + fetch->recvRetry(); +} + +template <class Impl> +bool +FullO3CPU<Impl>::DcachePort::recvTiming(PacketPtr pkt) +{ + return lsq->recvTiming(pkt); +} + +template <class Impl> +void +FullO3CPU<Impl>::DcachePort::recvRetry() +{ + lsq->recvRetry(); +} + template <class Impl> FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c) : Event(CPU_Tick_Pri), cpu(c) @@ -194,6 +242,9 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params) TheISA::NumMiscRegs * numThreads, TheISA::ZeroReg), + icachePort(&fetch, this), + dcachePort(&iew.ldstQueue, this), + timeBuffer(params->backComSize, params->forwardComSize), fetchQueue(params->backComSize, params->forwardComSize), decodeQueue(params->backComSize, params->forwardComSize), @@ -218,6 +269,7 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params) if (params->checker) { BaseCPU *temp_checker = params->checker; checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker); + checker->setIcachePort(&icachePort); #if FULL_SYSTEM checker->setSystem(params->system); #endif @@ -528,9 +580,9 @@ Port * FullO3CPU<Impl>::getPort(const std::string &if_name, int idx) { if (if_name == "dcache_port") - return iew.getDcachePort(); + return &dcachePort; else if (if_name == "icache_port") - return fetch.getIcachePort(); + return &icachePort; else panic("No Such Port\n"); } @@ -606,6 +658,13 @@ FullO3CPU<Impl>::init() for (ThreadID tid = 0; tid < numThreads; ++tid) thread[tid]->inSyscall = true; + // this CPU could still be unconnected if we are restoring from a + // checkpoint and this CPU is to be switched in, thus we can only + // do this here if the instruction port is actually connected, if + // not we have to do it as part of takeOverFrom + if (icachePort.isConnected()) + fetch.setIcache(); + #if FULL_SYSTEM for (ThreadID tid = 0; tid < numThreads; tid++) { ThreadContext *src_tc = threadContexts[tid]; @@ -1170,7 +1229,7 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU) activityRec.reset(); - BaseCPU::takeOverFrom(oldCPU, fetch.getIcachePort(), iew.getDcachePort()); + BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort); fetch.takeOverFrom(); decode.takeOverFrom(); diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 652e6d99a..1dd49a4f3 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2011 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2004-2005 The Regents of The University of Michigan * Copyright (c) 2011 Regents of the University of California * All rights reserved. @@ -118,6 +130,70 @@ class FullO3CPU : public BaseO3CPU Status _threadStatus[Impl::MaxThreads]; private: + + /** + * IcachePort class for instruction fetch. + */ + class IcachePort : public CpuPort + { + protected: + /** Pointer to fetch. */ + DefaultFetch<Impl> *fetch; + + public: + /** Default constructor. */ + IcachePort(DefaultFetch<Impl> *_fetch, FullO3CPU<Impl>* _cpu) + : CpuPort(_fetch->name() + "-iport", _cpu), fetch(_fetch) + { } + + protected: + + /** Timing version of receive. Handles setting fetch to the + * proper status to start fetching. */ + virtual bool recvTiming(PacketPtr pkt); + + /** Handles doing a retry of a failed fetch. */ + virtual void recvRetry(); + }; + + /** + * DcachePort class for the load/store queue. + */ + class DcachePort : public CpuPort + { + protected: + + /** Pointer to LSQ. */ + LSQ<Impl> *lsq; + + public: + /** Default constructor. */ + DcachePort(LSQ<Impl> *_lsq, FullO3CPU<Impl>* _cpu) + : CpuPort(_lsq->name() + "-dport", _cpu), lsq(_lsq) + { } + + protected: + + /** Timing version of receive. Handles writing back and + * completing the load or store that has returned from + * memory. */ + virtual bool recvTiming(PacketPtr pkt); + + /** Handles doing a retry of the previous send. */ + virtual void recvRetry(); + + /** + * As this CPU requires snooping to maintain the load store queue + * change the behaviour from the base CPU port. + * + * @param resp list of ranges this port responds to + * @param snoop indicating if the port snoops or not + */ + virtual void getDeviceAddressRanges(AddrRangeList& resp, + bool& snoop) + { resp.clear(); snoop = true; } + }; + class TickEvent : public Event { private: @@ -566,6 +642,12 @@ class FullO3CPU : public BaseO3CPU TheISA::ISA isa[Impl::MaxThreads]; + /** Instruction port. Note that it has to appear after the fetch stage. */ + IcachePort icachePort; + + /** Data port. Note that it has to appear after the iew stages */ + DcachePort dcachePort; + public: /** Enum to give each stage a specific index, so when calling * activateStage() or deactivateStage(), they can specify which stage @@ -704,8 +786,11 @@ class FullO3CPU : public BaseO3CPU data, store_idx); } + /** Used by the fetch unit to get a hold of the instruction port. */ + Port* getIcachePort() { return &icachePort; } + /** Get the dcache port (used to find block size for translations). */ - Port *getDcachePort() { return this->iew.ldstQueue.getDcachePort(); } + Port* getDcachePort() { return &dcachePort; } Addr lockAddr; diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index d09d7f680..f5d275593 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 ARM Limited + * Copyright (c) 2010-2011 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -85,48 +85,6 @@ class DefaultFetch typedef TheISA::MachInst MachInst; typedef TheISA::ExtMachInst ExtMachInst; - /** IcachePort class for DefaultFetch. Handles doing the - * communication with the cache/memory. - */ - class IcachePort : public Port - { - protected: - /** Pointer to fetch. */ - DefaultFetch<Impl> *fetch; - - public: - /** Default constructor. */ - IcachePort(DefaultFetch<Impl> *_fetch) - : Port(_fetch->name() + "-iport", _fetch->cpu), fetch(_fetch) - { } - - bool snoopRangeSent; - - virtual void setPeer(Port *port); - - protected: - /** Atomic version of receive. Panics. */ - virtual Tick recvAtomic(PacketPtr pkt); - - /** Functional version of receive. Panics. */ - virtual void recvFunctional(PacketPtr pkt); - - /** Receives status change. Other than range changing, panics. */ - virtual void recvStatusChange(Status status); - - /** Returns the address ranges of this device. */ - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) - { resp.clear(); snoop = true; } - - /** Timing version of receive. Handles setting fetch to the - * proper status to start fetching. */ - virtual bool recvTiming(PacketPtr pkt); - - /** Handles doing a retry of a failed fetch. */ - virtual void recvRetry(); - }; - class FetchTranslation : public BaseTLB::Translation { protected: @@ -248,9 +206,6 @@ class DefaultFetch /** Registers statistics. */ void regStats(); - /** Returns the icache port. */ - Port *getIcachePort() { return icachePort; } - /** Sets the main backwards communication time buffer pointer. */ void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer); @@ -266,6 +221,9 @@ class DefaultFetch /** Tells the fetch stage that the Icache is set. */ void setIcache(); + /** Handles retrying the fetch access. */ + void recvRetry(); + /** Processes cache completion event. */ void processCacheCompletion(PacketPtr pkt); @@ -389,9 +347,6 @@ class DefaultFetch StaticInstPtr curMacroop, TheISA::PCState thisPC, TheISA::PCState nextPC, bool trace); - /** Handles retrying the fetch access. */ - void recvRetry(); - /** Returns the appropriate thread to fetch, given the fetch policy. */ ThreadID getFetchingThread(FetchPriority &fetch_priority); @@ -440,9 +395,6 @@ class DefaultFetch /** Wire used to write any information heading to decode. */ typename TimeBuffer<FetchStruct>::wire toDecode; - /** Icache interface. */ - IcachePort *icachePort; - /** BPredUnit. */ BPredUnit branchPred; diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index ccab47d2f..d145fb099 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 ARM Limited + * Copyright (c) 2010-2011 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -71,68 +71,6 @@ using namespace std; template<class Impl> -void -DefaultFetch<Impl>::IcachePort::setPeer(Port *port) -{ - Port::setPeer(port); - - fetch->setIcache(); -} - -template<class Impl> -Tick -DefaultFetch<Impl>::IcachePort::recvAtomic(PacketPtr pkt) -{ - panic("DefaultFetch doesn't expect recvAtomic callback!"); - return curTick(); -} - -template<class Impl> -void -DefaultFetch<Impl>::IcachePort::recvFunctional(PacketPtr pkt) -{ - DPRINTF(Fetch, "DefaultFetch doesn't update its state from a " - "functional call.\n"); -} - -template<class Impl> -void -DefaultFetch<Impl>::IcachePort::recvStatusChange(Status status) -{ - if (status == RangeChange) { - if (!snoopRangeSent) { - snoopRangeSent = true; - sendStatusChange(Port::RangeChange); - } - return; - } - - panic("DefaultFetch doesn't expect recvStatusChange callback!"); -} - -template<class Impl> -bool -DefaultFetch<Impl>::IcachePort::recvTiming(PacketPtr pkt) -{ - DPRINTF(Fetch, "Received timing\n"); - if (pkt->isResponse()) { - // We shouldn't ever get a block in ownership state - assert(!(pkt->memInhibitAsserted() && !pkt->sharedAsserted())); - - fetch->processCacheCompletion(pkt); - } - //else Snooped a coherence request, just return - return true; -} - -template<class Impl> -void -DefaultFetch<Impl>::IcachePort::recvRetry() -{ - fetch->recvRetry(); -} - -template<class Impl> DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params) : cpu(_cpu), branchPred(params), @@ -191,17 +129,6 @@ DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params) // Get the size of an instruction. instSize = sizeof(TheISA::MachInst); - - // Name is finally available, so create the port. - icachePort = new IcachePort(this); - - icachePort->snoopRangeSent = false; - -#if USE_CHECKER - if (cpu->checker) { - cpu->checker->setIcachePort(icachePort); - } -#endif } template <class Impl> @@ -404,8 +331,10 @@ template<class Impl> void DefaultFetch<Impl>::setIcache() { + assert(cpu->getIcachePort()->isConnected()); + // Size of cache block. - cacheBlkSize = icachePort->peerBlockSize(); + cacheBlkSize = cpu->getIcachePort()->peerBlockSize(); // Create mask to get rid of offset bits. cacheBlkMask = (cacheBlkSize - 1); @@ -496,6 +425,10 @@ template <class Impl> void DefaultFetch<Impl>::takeOverFrom() { + // the instruction port is now connected so we can get the block + // size + setIcache(); + // Reset all state for (ThreadID i = 0; i < Impl::MaxThreads; ++i) { stalls[i].decode = 0; @@ -686,7 +619,7 @@ DefaultFetch<Impl>::finishTranslation(Fault fault, RequestPtr mem_req) fetchedCacheLines++; // Access the cache. - if (!icachePort->sendTiming(data_pkt)) { + if (!cpu->getIcachePort()->sendTiming(data_pkt)) { assert(retryPkt == NULL); assert(retryTid == InvalidThreadID); DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid); @@ -1405,7 +1338,7 @@ DefaultFetch<Impl>::recvRetry() assert(retryTid != InvalidThreadID); assert(fetchStatus[retryTid] == IcacheWaitRetry); - if (icachePort->sendTiming(retryPkt)) { + if (cpu->getIcachePort()->sendTiming(retryPkt)) { fetchStatus[retryTid] = IcacheWaitResponse; retryPkt = NULL; retryTid = InvalidThreadID; diff --git a/src/cpu/o3/iew.hh b/src/cpu/o3/iew.hh index 113d0756e..c58361cd6 100644 --- a/src/cpu/o3/iew.hh +++ b/src/cpu/o3/iew.hh @@ -139,9 +139,6 @@ class DefaultIEW /** Initializes stage; sends back the number of free IQ and LSQ entries. */ void initStage(); - /** Returns the dcache port. */ - Port *getDcachePort() { return ldstQueue.getDcachePort(); } - /** Sets main time buffer used for backwards communication. */ void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh index d01a6b0a4..731c67ae6 100644 --- a/src/cpu/o3/lsq.hh +++ b/src/cpu/o3/lsq.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2011 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2004-2006 The Regents of The University of Michigan * All rights reserved. * @@ -66,13 +78,6 @@ class LSQ { /** Registers statistics of each LSQ unit. */ void regStats(); - /** Returns dcache port. - * @todo: Dcache port needs to be moved up to this level for SMT - * to work. For now it just returns the port from one of the - * threads. - */ - Port *getDcachePort() { return &dcachePort; } - /** Sets the pointer to the list of active threads. */ void setActiveThreads(std::list<ThreadID> *at_ptr); /** Switches out the LSQ. */ @@ -282,56 +287,25 @@ class LSQ { Fault write(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh, uint8_t *data, int store_idx); + /** + * Retry the previous send that failed. + */ + void recvRetry(); + + /** + * Handles writing back and completing the load or store that has + * returned from memory. + * + * @param pkt Response packet from the memory sub-system + */ + bool recvTiming(PacketPtr pkt); + /** The CPU pointer. */ O3CPU *cpu; /** The IEW stage pointer. */ IEW *iewStage; - /** DcachePort class for this LSQ. Handles doing the - * communication with the cache/memory. - */ - class DcachePort : public Port - { - protected: - /** Pointer to LSQ. */ - LSQ *lsq; - - public: - /** Default constructor. */ - DcachePort(LSQ *_lsq) - : Port(_lsq->name() + "-dport", _lsq->cpu), lsq(_lsq) - { } - - bool snoopRangeSent; - - protected: - /** Atomic version of receive. Panics. */ - virtual Tick recvAtomic(PacketPtr pkt); - - /** Functional version of receive. Panics. */ - virtual void recvFunctional(PacketPtr pkt); - - /** Receives status change. Other than range changing, panics. */ - virtual void recvStatusChange(Status status); - - /** Returns the address ranges of this device. */ - virtual void getDeviceAddressRanges(AddrRangeList &resp, - bool &snoop) - { resp.clear(); snoop = true; } - - /** Timing version of receive. Handles writing back and - * completing the load or store that has returned from - * memory. */ - virtual bool recvTiming(PacketPtr pkt); - - /** Handles doing a retry of the previous send. */ - virtual void recvRetry(); - }; - - /** D-cache port. */ - DcachePort dcachePort; - protected: /** The LSQ policy for SMT mode. */ LSQPolicy lsqPolicy; diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh index 61dced14f..f1642be9c 100644 --- a/src/cpu/o3/lsq_impl.hh +++ b/src/cpu/o3/lsq_impl.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2011 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2005-2006 The Regents of The University of Michigan * All rights reserved. * @@ -41,84 +53,13 @@ using namespace std; template <class Impl> -Tick -LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt) -{ - panic("O3CPU model does not work with atomic mode!"); - return curTick(); -} - -template <class Impl> -void -LSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt) -{ - DPRINTF(LSQ, "LSQ doesn't update things on a recvFunctional.\n"); -} - -template <class Impl> -void -LSQ<Impl>::DcachePort::recvStatusChange(Status status) -{ - if (status == RangeChange) { - if (!snoopRangeSent) { - snoopRangeSent = true; - sendStatusChange(Port::RangeChange); - } - return; - } - panic("O3CPU doesn't expect recvStatusChange callback!"); -} - -template <class Impl> -bool -LSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt) -{ - if (pkt->isError()) - DPRINTF(LSQ, "Got error packet back for address: %#X\n", pkt->getAddr()); - if (pkt->isResponse()) { - lsq->thread[pkt->req->threadId()].completeDataAccess(pkt); - } else { - DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(), - pkt->cmdString()); - - // must be a snoop - if (pkt->isInvalidate()) { - DPRINTF(LSQ, "received invalidation for addr:%#x\n", pkt->getAddr()); - for (ThreadID tid = 0; tid < lsq->numThreads; tid++) { - lsq->thread[tid].checkSnoop(pkt); - } - } - // to provide stronger consistency model - } - return true; -} - -template <class Impl> -void -LSQ<Impl>::DcachePort::recvRetry() -{ - if (lsq->retryTid == -1) - { - //Squashed, so drop it - return; - } - int curr_retry_tid = lsq->retryTid; - // Speculatively clear the retry Tid. This will get set again if - // the LSQUnit was unable to complete its access. - lsq->retryTid = -1; - lsq->thread[curr_retry_tid].recvRetry(); -} - -template <class Impl> LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) - : cpu(cpu_ptr), iewStage(iew_ptr), dcachePort(this), + : cpu(cpu_ptr), iewStage(iew_ptr), LQEntries(params->LQEntries), SQEntries(params->SQEntries), numThreads(params->numThreads), retryTid(-1) { - dcachePort.snoopRangeSent = false; - //**********************************************/ //************ Handle SMT Parameters ***********/ //**********************************************/ @@ -170,7 +111,7 @@ LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) for (ThreadID tid = 0; tid < numThreads; tid++) { thread[tid].init(cpu, iew_ptr, params, this, maxLQEntries, maxSQEntries, tid); - thread[tid].setDcachePort(&dcachePort); + thread[tid].setDcachePort(cpu_ptr->getDcachePort()); } } @@ -360,6 +301,48 @@ LSQ<Impl>::violation() return false; } +template <class Impl> +void +LSQ<Impl>::recvRetry() +{ + if (retryTid == InvalidThreadID) + { + //Squashed, so drop it + return; + } + int curr_retry_tid = retryTid; + // Speculatively clear the retry Tid. This will get set again if + // the LSQUnit was unable to complete its access. + retryTid = -1; + thread[curr_retry_tid].recvRetry(); +} + +template <class Impl> +bool +LSQ<Impl>::recvTiming(PacketPtr pkt) +{ + if (pkt->isError()) + DPRINTF(LSQ, "Got error packet back for address: %#X\n", + pkt->getAddr()); + if (pkt->isResponse()) { + thread[pkt->req->threadId()].completeDataAccess(pkt); + } else { + DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(), + pkt->cmdString()); + + // must be a snoop + if (pkt->isInvalidate()) { + DPRINTF(LSQ, "received invalidation for addr:%#x\n", + pkt->getAddr()); + for (ThreadID tid = 0; tid < numThreads; tid++) { + thread[tid].checkSnoop(pkt); + } + } + // to provide stronger consistency model + } + return true; +} + template<class Impl> int LSQ<Impl>::getCount() |