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
, int asid
) 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
, int asid
, 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 MSHR
*mshr
= freeList
.front();
132 assert(mshr
->getNumTargets() == 0);
133 freeList
.pop_front();
135 if (!pkt
->needsResponse()) {
136 mshr
->allocateAsBuffer(pkt
);
139 mshr
->allocate(pkt
->cmd
, aligned_addr
, pkt
->req
->getAsid(), size
, pkt
);
140 allocatedTargets
+= 1;
142 mshr
->allocIter
= allocatedList
.insert(allocatedList
.end(), mshr
);
143 mshr
->readyIter
= pendingList
.insert(pendingList
.end(), mshr
);
150 MSHRQueue::allocateFetch(Addr addr
, int asid
, int size
, Packet
* &target
)
152 MSHR
*mshr
= freeList
.front();
153 assert(mshr
->getNumTargets() == 0);
154 freeList
.pop_front();
155 mshr
->allocate(Packet::ReadReq
, addr
, asid
, size
, target
);
156 mshr
->allocIter
= allocatedList
.insert(allocatedList
.end(), mshr
);
157 mshr
->readyIter
= pendingList
.insert(pendingList
.end(), mshr
);
164 MSHRQueue::allocateTargetList(Addr addr
, int asid
, int size
)
166 MSHR
*mshr
= freeList
.front();
167 assert(mshr
->getNumTargets() == 0);
168 freeList
.pop_front();
170 mshr
->allocate(Packet::ReadReq
, addr
, asid
, size
, dummy
);
171 mshr
->allocIter
= allocatedList
.insert(allocatedList
.end(), mshr
);
172 mshr
->inService
= true;
180 MSHRQueue::deallocate(MSHR
* mshr
)
186 MSHRQueue::deallocateOne(MSHR
* mshr
)
188 MSHR::Iterator retval
= allocatedList
.erase(mshr
->allocIter
);
189 freeList
.push_front(mshr
);
191 allocatedTargets
-= mshr
->getNumTargets();
192 if (mshr
->inService
) {
195 pendingList
.erase(mshr
->readyIter
);
202 MSHRQueue::moveToFront(MSHR
*mshr
)
204 if (!mshr
->inService
) {
205 assert(mshr
== *(mshr
->readyIter
));
206 pendingList
.erase(mshr
->readyIter
);
207 mshr
->readyIter
= pendingList
.insert(pendingList
.begin(), mshr
);
212 MSHRQueue::markInService(MSHR
* mshr
)
214 //assert(mshr == pendingList.front());
215 if (!mshr
->pkt
->needsResponse()) {
216 assert(mshr
->getNumTargets() == 0);
220 mshr
->inService
= true;
221 pendingList
.erase(mshr
->readyIter
);
222 mshr
->readyIter
= NULL
;
224 //pendingList.pop_front();
228 MSHRQueue::markPending(MSHR
* mshr
, Packet::Command cmd
)
230 assert(mshr
->readyIter
== NULL
);
231 mshr
->pkt
->cmd
= cmd
;
232 mshr
->pkt
->flags
&= ~SATISFIED
;
233 mshr
->inService
= false;
236 * @ todo might want to add rerequests to front of pending list for
239 mshr
->readyIter
= pendingList
.insert(pendingList
.end(), mshr
);
243 MSHRQueue::squash(int threadNum
)
245 MSHR::Iterator i
= allocatedList
.begin();
246 MSHR::Iterator end
= allocatedList
.end();
249 if (mshr
->threadNum
== threadNum
) {
250 while (mshr
->hasTargets()) {
251 Packet
* target
= mshr
->getTarget();
254 assert(target
->req
->getThreadNum() == threadNum
);
257 assert(!mshr
->hasTargets());
258 assert(mshr
->ntargets
==0);
259 if (!mshr
->inService
) {
260 i
= deallocateOne(mshr
);
262 //mshr->pkt->flags &= ~CACHE_LINE_FILL;