e9aa89bf8409970c495a98d8c3ef33c3be92b20c
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(PacketPtr
&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
) {
111 MSHRQueue::allocate(PacketPtr
&pkt
, int size
)
113 Addr aligned_addr
= pkt
->getAddr() & ~((Addr
)size
- 1);
114 assert(!freeList
.empty());
115 MSHR
*mshr
= freeList
.front();
116 assert(mshr
->getNumTargets() == 0);
117 freeList
.pop_front();
119 if (!pkt
->needsResponse()) {
120 mshr
->allocateAsBuffer(pkt
);
122 mshr
->allocate(pkt
->cmd
, aligned_addr
, size
, pkt
);
123 allocatedTargets
+= 1;
125 mshr
->allocIter
= allocatedList
.insert(allocatedList
.end(), mshr
);
126 mshr
->readyIter
= pendingList
.insert(pendingList
.end(), mshr
);
133 MSHRQueue::allocateFetch(Addr addr
, int size
, PacketPtr
&target
)
135 MSHR
*mshr
= freeList
.front();
136 assert(mshr
->getNumTargets() == 0);
137 freeList
.pop_front();
138 mshr
->allocate(MemCmd::ReadReq
, addr
, size
, target
);
139 mshr
->allocIter
= allocatedList
.insert(allocatedList
.end(), mshr
);
140 mshr
->readyIter
= pendingList
.insert(pendingList
.end(), mshr
);
147 MSHRQueue::allocateTargetList(Addr addr
, int size
)
149 MSHR
*mshr
= freeList
.front();
150 assert(mshr
->getNumTargets() == 0);
151 freeList
.pop_front();
153 mshr
->allocate(MemCmd::ReadReq
, addr
, size
, dummy
);
154 mshr
->allocIter
= allocatedList
.insert(allocatedList
.end(), mshr
);
155 mshr
->inService
= true;
163 MSHRQueue::deallocate(MSHR
* mshr
)
169 MSHRQueue::deallocateOne(MSHR
* mshr
)
171 MSHR::Iterator retval
= allocatedList
.erase(mshr
->allocIter
);
172 freeList
.push_front(mshr
);
174 allocatedTargets
-= mshr
->getNumTargets();
175 if (mshr
->inService
) {
178 pendingList
.erase(mshr
->readyIter
);
185 MSHRQueue::moveToFront(MSHR
*mshr
)
187 if (!mshr
->inService
) {
188 assert(mshr
== *(mshr
->readyIter
));
189 pendingList
.erase(mshr
->readyIter
);
190 mshr
->readyIter
= pendingList
.insert(pendingList
.begin(), mshr
);
195 MSHRQueue::markInService(MSHR
* mshr
)
197 //assert(mshr == pendingList.front());
198 if (!mshr
->pkt
->needsResponse() && !(mshr
->pkt
->cmd
== MemCmd::UpgradeReq
)) {
199 assert(mshr
->getNumTargets() == 0);
203 mshr
->inService
= true;
204 pendingList
.erase(mshr
->readyIter
);
205 //mshr->readyIter = NULL;
207 //pendingList.pop_front();
211 MSHRQueue::markPending(MSHR
* mshr
, MemCmd cmd
)
213 //assert(mshr->readyIter == NULL);
214 mshr
->pkt
->cmd
= cmd
;
215 mshr
->pkt
->flags
&= ~SATISFIED
;
216 mshr
->inService
= false;
219 * @ todo might want to add rerequests to front of pending list for
222 mshr
->readyIter
= pendingList
.insert(pendingList
.end(), mshr
);
226 MSHRQueue::squash(int threadNum
)
228 MSHR::Iterator i
= allocatedList
.begin();
229 MSHR::Iterator end
= allocatedList
.end();
232 if (mshr
->threadNum
== threadNum
) {
233 while (mshr
->hasTargets()) {
234 PacketPtr target
= mshr
->getTarget();
237 assert(0/*target->req->getThreadNum()*/ == threadNum
);
240 assert(!mshr
->hasTargets());
241 assert(mshr
->ntargets
==0);
242 if (!mshr
->inService
) {
243 i
= deallocateOne(mshr
);
245 //mshr->pkt->flags &= ~CACHE_LINE_FILL;