2 * Copyright (c) 2012 ARM Limited
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
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
14 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 * Authors: Erik Hallnor
45 * Definition of MSHRQueue class functions.
48 #include "mem/cache/mshr_queue.hh"
52 MSHRQueue::MSHRQueue(const std::string
&_label
,
53 int num_entries
, int reserve
, int _index
)
55 numEntries(num_entries
+ reserve
- 1), numReserve(reserve
),
56 drainManager(NULL
), index(_index
)
60 registers
= new MSHR
[numEntries
];
61 for (int i
= 0; i
< numEntries
; ++i
) {
62 registers
[i
].queue
= this;
63 freeList
.push_back(®isters
[i
]);
67 MSHRQueue::~MSHRQueue()
73 MSHRQueue::findMatch(Addr addr
) const
75 MSHR::ConstIterator i
= allocatedList
.begin();
76 MSHR::ConstIterator end
= allocatedList
.end();
77 for (; i
!= end
; ++i
) {
79 if (mshr
->addr
== addr
) {
87 MSHRQueue::findMatches(Addr addr
, vector
<MSHR
*>& matches
) const
89 // Need an empty vector
90 assert(matches
.empty());
92 MSHR::ConstIterator i
= allocatedList
.begin();
93 MSHR::ConstIterator end
= allocatedList
.end();
94 for (; i
!= end
; ++i
) {
96 if (mshr
->addr
== addr
) {
98 matches
.push_back(mshr
);
106 MSHRQueue::checkFunctional(PacketPtr pkt
, Addr blk_addr
)
108 pkt
->pushLabel(label
);
109 MSHR::ConstIterator i
= allocatedList
.begin();
110 MSHR::ConstIterator end
= allocatedList
.end();
111 for (; i
!= end
; ++i
) {
113 if (mshr
->addr
== blk_addr
&& mshr
->checkFunctional(pkt
)) {
124 MSHRQueue::findPending(Addr addr
, int size
) const
126 MSHR::ConstIterator i
= readyList
.begin();
127 MSHR::ConstIterator end
= readyList
.end();
128 for (; i
!= end
; ++i
) {
130 if (mshr
->addr
< addr
) {
131 if (mshr
->addr
+ mshr
->size
> addr
) {
135 if (addr
+ size
> mshr
->addr
) {
145 MSHRQueue::addToReadyList(MSHR
*mshr
)
147 if (readyList
.empty() || readyList
.back()->readyTime
<= mshr
->readyTime
) {
148 return readyList
.insert(readyList
.end(), mshr
);
151 MSHR::Iterator i
= readyList
.begin();
152 MSHR::Iterator end
= readyList
.end();
153 for (; i
!= end
; ++i
) {
154 if ((*i
)->readyTime
> mshr
->readyTime
) {
155 return readyList
.insert(i
, mshr
);
159 return end
; // keep stupid compilers happy
164 MSHRQueue::allocate(Addr addr
, int size
, PacketPtr
&pkt
,
165 Tick when
, Counter order
)
167 assert(!freeList
.empty());
168 MSHR
*mshr
= freeList
.front();
169 assert(mshr
->getNumTargets() == 0);
170 freeList
.pop_front();
172 mshr
->allocate(addr
, size
, pkt
, when
, order
);
173 mshr
->allocIter
= allocatedList
.insert(allocatedList
.end(), mshr
);
174 mshr
->readyIter
= addToReadyList(mshr
);
182 MSHRQueue::deallocate(MSHR
*mshr
)
188 MSHRQueue::deallocateOne(MSHR
*mshr
)
190 MSHR::Iterator retval
= allocatedList
.erase(mshr
->allocIter
);
191 freeList
.push_front(mshr
);
193 if (mshr
->inService
) {
196 readyList
.erase(mshr
->readyIter
);
199 if (drainManager
&& allocated
== 0) {
200 // Notify the drain manager that we have completed draining if
201 // there are no other outstanding requests in this MSHR queue.
202 drainManager
->signalDrainDone();
204 setDrainState(Drainable::Drained
);
210 MSHRQueue::moveToFront(MSHR
*mshr
)
212 if (!mshr
->inService
) {
213 assert(mshr
== *(mshr
->readyIter
));
214 readyList
.erase(mshr
->readyIter
);
215 mshr
->readyIter
= readyList
.insert(readyList
.begin(), mshr
);
220 MSHRQueue::markInService(MSHR
*mshr
, PacketPtr pkt
)
222 if (mshr
->markInService(pkt
)) {
225 readyList
.erase(mshr
->readyIter
);
226 inServiceEntries
+= 1;
231 MSHRQueue::markPending(MSHR
*mshr
)
233 assert(mshr
->inService
);
234 mshr
->inService
= false;
237 * @ todo might want to add rerequests to front of pending list for
240 mshr
->readyIter
= addToReadyList(mshr
);
244 MSHRQueue::squash(int threadNum
)
246 MSHR::Iterator i
= allocatedList
.begin();
247 MSHR::Iterator end
= allocatedList
.end();
250 if (mshr
->threadNum
== threadNum
) {
251 while (mshr
->hasTargets()) {
253 assert(0/*target->req->threadId()*/ == threadNum
);
255 assert(!mshr
->hasTargets());
256 assert(mshr
->ntargets
==0);
257 if (!mshr
->inService
) {
258 i
= deallocateOne(mshr
);
260 //mshr->pkt->flags &= ~CACHE_LINE_FILL;
270 MSHRQueue::drain(DrainManager
*dm
)
272 if (allocated
== 0) {
273 setDrainState(Drainable::Drained
);
277 setDrainState(Drainable::Draining
);