2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * Authors: Erik Hallnor
32 * Definition of the MSHRQueue.
35 #include "mem/cache/miss/mshr_queue.hh"
36 #include "sim/eventq.hh"
40 MSHRQueue::MSHRQueue(int num_mshrs
, int reserve
)
41 : numMSHRs(num_mshrs
+ reserve
- 1), numReserve(reserve
)
46 registers
= new MSHR
[numMSHRs
];
47 for (int i
= 0; i
< numMSHRs
; ++i
) {
48 freeList
.push_back(®isters
[i
]);
52 MSHRQueue::~MSHRQueue()
58 MSHRQueue::findMatch(Addr addr
) const
60 MSHR::ConstIterator i
= allocatedList
.begin();
61 MSHR::ConstIterator end
= allocatedList
.end();
62 for (; i
!= end
; ++i
) {
64 if (mshr
->addr
== addr
) {
72 MSHRQueue::findMatches(Addr addr
, vector
<MSHR
*>& matches
) const
74 // Need an empty vector
75 assert(matches
.empty());
77 MSHR::ConstIterator i
= allocatedList
.begin();
78 MSHR::ConstIterator end
= allocatedList
.end();
79 for (; i
!= end
; ++i
) {
81 if (mshr
->addr
== addr
) {
83 matches
.push_back(mshr
);
91 MSHRQueue::findPending(Packet
* &pkt
) const
93 MSHR::ConstIterator i
= pendingList
.begin();
94 MSHR::ConstIterator end
= pendingList
.end();
95 for (; i
!= end
; ++i
) {
97 if (mshr
->addr
< pkt
->getAddr()) {
98 if (mshr
->addr
+ mshr
->pkt
->getSize() > pkt
->getAddr()) {
102 if (pkt
->getAddr() + pkt
->getSize() > mshr
->addr
) {
107 //need to check destination address for copies.
108 //TEMP NOT DOING COPIES
110 if (mshr
->pkt
->cmd
== Copy
) {
111 Addr dest
= mshr
->pkt
->dest
;
112 if (dest
< pkt
->addr
) {
113 if (dest
+ mshr
->pkt
->size
> pkt
->addr
) {
117 if (pkt
->addr
+ pkt
->size
> dest
) {
128 MSHRQueue::allocate(Packet
* &pkt
, int size
)
130 Addr aligned_addr
= pkt
->getAddr() & ~((Addr
)size
- 1);
131 assert(!freeList
.empty());
132 MSHR
*mshr
= freeList
.front();
133 assert(mshr
->getNumTargets() == 0);
134 freeList
.pop_front();
136 if (!pkt
->needsResponse()) {
137 mshr
->allocateAsBuffer(pkt
);
140 mshr
->allocate(pkt
->cmd
, aligned_addr
, size
, pkt
);
141 allocatedTargets
+= 1;
143 mshr
->allocIter
= allocatedList
.insert(allocatedList
.end(), mshr
);
144 mshr
->readyIter
= pendingList
.insert(pendingList
.end(), mshr
);
151 MSHRQueue::allocateFetch(Addr addr
, int size
, Packet
* &target
)
153 MSHR
*mshr
= freeList
.front();
154 assert(mshr
->getNumTargets() == 0);
155 freeList
.pop_front();
156 mshr
->allocate(Packet::ReadReq
, addr
, size
, target
);
157 mshr
->allocIter
= allocatedList
.insert(allocatedList
.end(), mshr
);
158 mshr
->readyIter
= pendingList
.insert(pendingList
.end(), mshr
);
165 MSHRQueue::allocateTargetList(Addr addr
, int size
)
167 MSHR
*mshr
= freeList
.front();
168 assert(mshr
->getNumTargets() == 0);
169 freeList
.pop_front();
171 mshr
->allocate(Packet::ReadReq
, addr
, size
, dummy
);
172 mshr
->allocIter
= allocatedList
.insert(allocatedList
.end(), mshr
);
173 mshr
->inService
= true;
181 MSHRQueue::deallocate(MSHR
* mshr
)
187 MSHRQueue::deallocateOne(MSHR
* mshr
)
189 MSHR::Iterator retval
= allocatedList
.erase(mshr
->allocIter
);
190 freeList
.push_front(mshr
);
192 allocatedTargets
-= mshr
->getNumTargets();
193 if (mshr
->inService
) {
196 pendingList
.erase(mshr
->readyIter
);
203 MSHRQueue::moveToFront(MSHR
*mshr
)
205 if (!mshr
->inService
) {
206 assert(mshr
== *(mshr
->readyIter
));
207 pendingList
.erase(mshr
->readyIter
);
208 mshr
->readyIter
= pendingList
.insert(pendingList
.begin(), mshr
);
213 MSHRQueue::markInService(MSHR
* mshr
)
215 //assert(mshr == pendingList.front());
216 if (!(mshr
->pkt
->needsResponse() || mshr
->pkt
->cmd
== Packet::UpgradeReq
)) {
217 assert(mshr
->getNumTargets() == 0);
218 if ((mshr
->pkt
->flags
& SATISFIED
) && (mshr
->pkt
->cmd
== Packet::Writeback
)) {
219 //Writeback hit, so delete it
220 //otherwise the consumer will delete it
221 delete mshr
->pkt
->req
;
226 mshr
->inService
= true;
227 pendingList
.erase(mshr
->readyIter
);
228 //mshr->readyIter = NULL;
230 //pendingList.pop_front();
234 MSHRQueue::markPending(MSHR
* mshr
, Packet::Command cmd
)
236 //assert(mshr->readyIter == NULL);
237 mshr
->pkt
->cmd
= cmd
;
238 mshr
->pkt
->flags
&= ~SATISFIED
;
239 mshr
->inService
= false;
242 * @ todo might want to add rerequests to front of pending list for
245 mshr
->readyIter
= pendingList
.insert(pendingList
.end(), mshr
);
249 MSHRQueue::squash(int threadNum
)
251 MSHR::Iterator i
= allocatedList
.begin();
252 MSHR::Iterator end
= allocatedList
.end();
255 if (mshr
->threadNum
== threadNum
) {
256 while (mshr
->hasTargets()) {
257 Packet
* target
= mshr
->getTarget();
260 assert(0/*target->req->getThreadNum()*/ == threadNum
);
263 assert(!mshr
->hasTargets());
264 assert(mshr
->ntargets
==0);
265 if (!mshr
->inService
) {
266 i
= deallocateOne(mshr
);
268 //mshr->pkt->flags &= ~CACHE_LINE_FILL;