Fix problems with unCacheable addresses in timing-coherence
[gem5.git] / src / mem / cache / coherence / coherence_protocol.cc
1 /*
2 * Copyright (c) 2002-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
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.
15 *
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.
27 *
28 * Authors: Erik Hallnor
29 * Steve Reinhardt
30 * Ron Dreslinski
31 */
32
33 /**
34 * @file
35 * Definitions of CoherenceProtocol.
36 */
37
38 #include <string>
39
40 #include "base/misc.hh"
41 #include "mem/cache/miss/mshr.hh"
42 #include "mem/cache/cache.hh"
43 #include "mem/cache/coherence/coherence_protocol.hh"
44 #include "sim/builder.hh"
45
46 using namespace std;
47
48
49 CoherenceProtocol::StateTransition::StateTransition()
50 : busCmd(Packet::InvalidCmd), newState(-1), snoopFunc(invalidTransition)
51 {
52 }
53
54
55 void
56 CoherenceProtocol::regStats()
57 {
58 // Even though we count all the possible transitions in the
59 // requestCount and snoopCount arrays, most of these are invalid,
60 // so we just select the interesting ones to print here.
61
62 requestCount[Invalid][Packet::ReadReq]
63 .name(name() + ".read_invalid")
64 .desc("read misses to invalid blocks")
65 ;
66
67 requestCount[Invalid][Packet::WriteReq]
68 .name(name() +".write_invalid")
69 .desc("write misses to invalid blocks")
70 ;
71
72 requestCount[Invalid][Packet::SoftPFReq]
73 .name(name() +".swpf_invalid")
74 .desc("soft prefetch misses to invalid blocks")
75 ;
76
77 requestCount[Invalid][Packet::HardPFReq]
78 .name(name() +".hwpf_invalid")
79 .desc("hard prefetch misses to invalid blocks")
80 ;
81
82 requestCount[Shared][Packet::WriteReq]
83 .name(name() + ".write_shared")
84 .desc("write misses to shared blocks")
85 ;
86
87 requestCount[Owned][Packet::WriteReq]
88 .name(name() + ".write_owned")
89 .desc("write misses to owned blocks")
90 ;
91
92 snoopCount[Shared][Packet::ReadReq]
93 .name(name() + ".snoop_read_shared")
94 .desc("read snoops on shared blocks")
95 ;
96
97 snoopCount[Shared][Packet::ReadExReq]
98 .name(name() + ".snoop_readex_shared")
99 .desc("readEx snoops on shared blocks")
100 ;
101
102 snoopCount[Shared][Packet::UpgradeReq]
103 .name(name() + ".snoop_upgrade_shared")
104 .desc("upgradee snoops on shared blocks")
105 ;
106
107 snoopCount[Modified][Packet::ReadReq]
108 .name(name() + ".snoop_read_modified")
109 .desc("read snoops on modified blocks")
110 ;
111
112 snoopCount[Modified][Packet::ReadExReq]
113 .name(name() + ".snoop_readex_modified")
114 .desc("readEx snoops on modified blocks")
115 ;
116
117 snoopCount[Owned][Packet::ReadReq]
118 .name(name() + ".snoop_read_owned")
119 .desc("read snoops on owned blocks")
120 ;
121
122 snoopCount[Owned][Packet::ReadExReq]
123 .name(name() + ".snoop_readex_owned")
124 .desc("readEx snoops on owned blocks")
125 ;
126
127 snoopCount[Owned][Packet::UpgradeReq]
128 .name(name() + ".snoop_upgrade_owned")
129 .desc("upgrade snoops on owned blocks")
130 ;
131
132 snoopCount[Exclusive][Packet::ReadReq]
133 .name(name() + ".snoop_read_exclusive")
134 .desc("read snoops on exclusive blocks")
135 ;
136
137 snoopCount[Exclusive][Packet::ReadExReq]
138 .name(name() + ".snoop_readex_exclusive")
139 .desc("readEx snoops on exclusive blocks")
140 ;
141
142 snoopCount[Shared][Packet::InvalidateReq]
143 .name(name() + ".snoop_inv_shared")
144 .desc("Invalidate snoops on shared blocks")
145 ;
146
147 snoopCount[Owned][Packet::InvalidateReq]
148 .name(name() + ".snoop_inv_owned")
149 .desc("Invalidate snoops on owned blocks")
150 ;
151
152 snoopCount[Exclusive][Packet::InvalidateReq]
153 .name(name() + ".snoop_inv_exclusive")
154 .desc("Invalidate snoops on exclusive blocks")
155 ;
156
157 snoopCount[Modified][Packet::InvalidateReq]
158 .name(name() + ".snoop_inv_modified")
159 .desc("Invalidate snoops on modified blocks")
160 ;
161
162 snoopCount[Invalid][Packet::InvalidateReq]
163 .name(name() + ".snoop_inv_invalid")
164 .desc("Invalidate snoops on invalid blocks")
165 ;
166
167 snoopCount[Shared][Packet::WriteInvalidateReq]
168 .name(name() + ".snoop_writeinv_shared")
169 .desc("WriteInvalidate snoops on shared blocks")
170 ;
171
172 snoopCount[Owned][Packet::WriteInvalidateReq]
173 .name(name() + ".snoop_writeinv_owned")
174 .desc("WriteInvalidate snoops on owned blocks")
175 ;
176
177 snoopCount[Exclusive][Packet::WriteInvalidateReq]
178 .name(name() + ".snoop_writeinv_exclusive")
179 .desc("WriteInvalidate snoops on exclusive blocks")
180 ;
181
182 snoopCount[Modified][Packet::WriteInvalidateReq]
183 .name(name() + ".snoop_writeinv_modified")
184 .desc("WriteInvalidate snoops on modified blocks")
185 ;
186
187 snoopCount[Invalid][Packet::WriteInvalidateReq]
188 .name(name() + ".snoop_writeinv_invalid")
189 .desc("WriteInvalidate snoops on invalid blocks")
190 ;
191 }
192
193
194 bool
195 CoherenceProtocol::invalidateTrans(BaseCache *cache, Packet * &pkt,
196 CacheBlk *blk, MSHR *mshr,
197 CacheBlk::State & new_state)
198 {
199 // invalidate the block
200 new_state = (blk->status & ~stateMask) | Invalid;
201 return false;
202 }
203
204
205 bool
206 CoherenceProtocol::supplyTrans(BaseCache *cache, Packet * &pkt,
207 CacheBlk *blk,
208 MSHR *mshr,
209 CacheBlk::State & new_state
210 )
211 {
212 return true;
213 }
214
215
216 bool
217 CoherenceProtocol::supplyAndGotoSharedTrans(BaseCache *cache, Packet * &pkt,
218 CacheBlk *blk,
219 MSHR *mshr,
220 CacheBlk::State & new_state)
221 {
222 new_state = (blk->status & ~stateMask) | Shared;
223 pkt->flags |= SHARED_LINE;
224 return supplyTrans(cache, pkt, blk, mshr, new_state);
225 }
226
227
228 bool
229 CoherenceProtocol::supplyAndGotoOwnedTrans(BaseCache *cache, Packet * &pkt,
230 CacheBlk *blk,
231 MSHR *mshr,
232 CacheBlk::State & new_state)
233 {
234 new_state = (blk->status & ~stateMask) | Owned;
235 pkt->flags |= SHARED_LINE;
236 return supplyTrans(cache, pkt, blk, mshr, new_state);
237 }
238
239
240 bool
241 CoherenceProtocol::supplyAndInvalidateTrans(BaseCache *cache, Packet * &pkt,
242 CacheBlk *blk,
243 MSHR *mshr,
244 CacheBlk::State & new_state)
245 {
246 new_state = (blk->status & ~stateMask) | Invalid;
247 return supplyTrans(cache, pkt, blk, mshr, new_state);
248 }
249
250 bool
251 CoherenceProtocol::assertShared(BaseCache *cache, Packet * &pkt,
252 CacheBlk *blk,
253 MSHR *mshr,
254 CacheBlk::State & new_state)
255 {
256 new_state = (blk->status & ~stateMask) | Shared;
257 pkt->flags |= SHARED_LINE;
258 return false;
259 }
260
261 CoherenceProtocol::CoherenceProtocol(const string &name,
262 const string &protocol,
263 const bool doUpgrades)
264 : SimObject(name)
265 {
266 if ((protocol == "mosi" || protocol == "moesi") && !doUpgrades) {
267 cerr << "CoherenceProtocol: ownership protocols require upgrade transactions"
268 << "(write miss on owned block generates ReadExcl, which will clobber dirty block)"
269 << endl;
270 fatal("");
271 }
272
273 Packet::Command writeToSharedCmd = doUpgrades ? Packet::UpgradeReq : Packet::ReadExReq;
274 Packet::Command writeToSharedResp = doUpgrades ? Packet::UpgradeReq : Packet::ReadExResp;
275
276 //@todo add in hardware prefetch to this list
277 if (protocol == "msi") {
278 // incoming requests: specify outgoing bus request
279 transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq);
280 transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq);
281 transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd);
282 //Prefetching causes a read
283 transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq);
284 transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq);
285
286 // on response to given request: specify new state
287 transitionTable[Invalid][Packet::ReadResp].onResponse(Shared);
288 transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified);
289 transitionTable[Shared][writeToSharedResp].onResponse(Modified);
290
291 // bus snoop transition functions
292 transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition);
293 transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition);
294 transitionTable[Shared][Packet::ReadReq].onSnoop(nullTransition);
295 transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans);
296 transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
297 transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoSharedTrans);
298 //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv)
299 transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans);
300 transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans);
301 transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans);
302 transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
303 transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
304 transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
305
306 if (doUpgrades) {
307 transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition);
308 transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans);
309 }
310 }
311
312 else if(protocol == "mesi") {
313 // incoming requests: specify outgoing bus request
314 transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq);
315 transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq);
316 transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd);
317 //Prefetching causes a read
318 transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq);
319 transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq);
320
321 // on response to given request: specify new state
322 transitionTable[Invalid][Packet::ReadResp].onResponse(Exclusive);
323 //It will move into shared if the shared line is asserted in the
324 //getNewState function
325 transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified);
326 transitionTable[Shared][writeToSharedResp].onResponse(Modified);
327
328 // bus snoop transition functions
329 transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition);
330 transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition);
331 transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared);
332 transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans);
333 transitionTable[Exclusive][Packet::ReadReq].onSnoop(assertShared);
334 transitionTable[Exclusive][Packet::ReadExReq].onSnoop(invalidateTrans);
335 transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
336 transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoSharedTrans);
337 //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv)
338 transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans);
339 transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans);
340 transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans);
341 transitionTable[Exclusive][Packet::InvalidateReq].onSnoop(invalidateTrans);
342 transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
343 transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
344 transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
345 transitionTable[Exclusive][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
346
347 if (doUpgrades) {
348 transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition);
349 transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans);
350 }
351 }
352
353 else if(protocol == "mosi") {
354 // incoming requests: specify outgoing bus request
355 transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq);
356 transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq);
357 transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd);
358 transitionTable[Owned][Packet::WriteReq].onRequest(writeToSharedCmd);
359 //Prefetching causes a read
360 transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq);
361 transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq);
362
363 // on response to given request: specify new state
364 transitionTable[Invalid][Packet::ReadResp].onResponse(Shared);
365 transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified);
366 transitionTable[Shared][writeToSharedResp].onResponse(Modified);
367 transitionTable[Owned][writeToSharedResp].onResponse(Modified);
368
369 // bus snoop transition functions
370 transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition);
371 transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition);
372 transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition);
373 transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared);
374 transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans);
375 transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans);
376 transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
377 transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
378 transitionTable[Owned][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
379 transitionTable[Owned][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
380 transitionTable[Owned][Packet::UpgradeReq].onSnoop(invalidateTrans);
381 //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv)
382 transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans);
383 transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans);
384 transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans);
385 transitionTable[Owned][Packet::InvalidateReq].onSnoop(invalidateTrans);
386 transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
387 transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
388 transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
389 transitionTable[Owned][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
390 }
391
392 else if(protocol == "moesi") {
393 // incoming requests: specify outgoing bus request
394 transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq);
395 transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq);
396 transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd);
397 transitionTable[Owned][Packet::WriteReq].onRequest(writeToSharedCmd);
398 //Prefetching causes a read
399 transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq);
400 transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq);
401
402 // on response to given request: specify new state
403 transitionTable[Invalid][Packet::ReadResp].onResponse(Exclusive);
404 //It will move into shared if the shared line is asserted in the
405 //getNewState function
406 transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified);
407 transitionTable[Shared][writeToSharedResp].onResponse(Modified);
408 transitionTable[Owned][writeToSharedResp].onResponse(Modified);
409
410 // bus snoop transition functions
411 transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition);
412 transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition);
413 transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition);
414 transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared);
415 transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans);
416 transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans);
417 transitionTable[Exclusive][Packet::ReadReq].onSnoop(assertShared);
418 transitionTable[Exclusive][Packet::ReadExReq].onSnoop(invalidateTrans);
419 transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
420 transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
421 transitionTable[Owned][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
422 transitionTable[Owned][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
423 transitionTable[Owned][Packet::UpgradeReq].onSnoop(invalidateTrans);
424 //Transitions on seeing a DMA (writeInv(samelevel) or DMAInv)
425 transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans);
426 transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans);
427 transitionTable[Exclusive][Packet::InvalidateReq].onSnoop(invalidateTrans);
428 transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans);
429 transitionTable[Owned][Packet::InvalidateReq].onSnoop(invalidateTrans);
430 transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
431 transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
432 transitionTable[Exclusive][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
433 transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
434 transitionTable[Owned][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
435 }
436
437 else {
438 cerr << "CoherenceProtocol: unrecognized protocol " << protocol
439 << endl;
440 fatal("");
441 }
442 }
443
444
445 Packet::Command
446 CoherenceProtocol::getBusCmd(Packet::Command cmdIn, CacheBlk::State state,
447 MSHR *mshr)
448 {
449 state &= stateMask;
450 int cmd_idx = (int) cmdIn;
451
452 assert(0 <= state && state <= stateMax);
453 assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
454
455 Packet::Command cmdOut = transitionTable[state][cmd_idx].busCmd;
456
457 assert(cmdOut != Packet::InvalidCmd);
458
459 ++requestCount[state][cmd_idx];
460
461 return cmdOut;
462 }
463
464
465 CacheBlk::State
466 CoherenceProtocol::getNewState(Packet * &pkt, CacheBlk::State oldState)
467 {
468 CacheBlk::State state = oldState & stateMask;
469 int cmd_idx = pkt->cmdToIndex();
470
471 assert(0 <= state && state <= stateMax);
472 assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
473
474 CacheBlk::State newState = transitionTable[state][cmd_idx].newState;
475
476 //Check if it's exclusive and the shared line was asserted,
477 //then goto shared instead
478 if (newState == Exclusive && (pkt->flags & SHARED_LINE)) {
479 newState = Shared;
480 }
481
482 assert(newState != -1);
483
484 //Make sure not to loose any other state information
485 newState = (oldState & ~stateMask) | newState;
486 return newState;
487 }
488
489
490 bool
491 CoherenceProtocol::handleBusRequest(BaseCache *cache, Packet * &pkt,
492 CacheBlk *blk,
493 MSHR *mshr,
494 CacheBlk::State & new_state)
495 {
496 if (blk == NULL) {
497 // nothing to do if we don't have a block
498 return false;
499 }
500
501 CacheBlk::State state = blk->status & stateMask;
502 int cmd_idx = pkt->cmdToIndex();
503
504 assert(0 <= state && state <= stateMax);
505 assert(0 <= cmd_idx && cmd_idx < NUM_MEM_CMDS);
506
507 // assert(mshr == NULL); // can't currently handle outstanding requests
508 //Check first if MSHR, and also insure, if there is one, that it is not in service
509 assert(!mshr || mshr->inService == 0);
510 ++snoopCount[state][cmd_idx];
511
512 bool ret = transitionTable[state][cmd_idx].snoopFunc(cache, pkt, blk, mshr,
513 new_state);
514
515
516
517 return ret;
518 }
519
520 bool
521 CoherenceProtocol::nullTransition(BaseCache *cache, Packet * &pkt,
522 CacheBlk *blk, MSHR *mshr,
523 CacheBlk::State & new_state)
524 {
525 // do nothing
526 if (blk)
527 new_state = blk->status;
528 return false;
529 }
530
531
532 bool
533 CoherenceProtocol::invalidTransition(BaseCache *cache, Packet * &pkt,
534 CacheBlk *blk, MSHR *mshr,
535 CacheBlk::State & new_state)
536 {
537 panic("Invalid transition");
538 return false;
539 }
540
541 #ifndef DOXYGEN_SHOULD_SKIP_THIS
542
543 BEGIN_DECLARE_SIM_OBJECT_PARAMS(CoherenceProtocol)
544
545 Param<string> protocol;
546 Param<bool> do_upgrades;
547
548 END_DECLARE_SIM_OBJECT_PARAMS(CoherenceProtocol)
549
550
551 BEGIN_INIT_SIM_OBJECT_PARAMS(CoherenceProtocol)
552
553 INIT_PARAM(protocol, "name of coherence protocol"),
554 INIT_PARAM_DFLT(do_upgrades, "use upgrade transactions?", true)
555
556 END_INIT_SIM_OBJECT_PARAMS(CoherenceProtocol)
557
558
559 CREATE_SIM_OBJECT(CoherenceProtocol)
560 {
561 return new CoherenceProtocol(getInstanceName(), protocol,
562 do_upgrades);
563 }
564
565 REGISTER_SIM_OBJECT("CoherenceProtocol", CoherenceProtocol)
566
567 #endif // DOXYGEN_SHOULD_SKIP_THIS