base.cc revision 9418:9923a5ab8c13
1/*
2 * Copyright (c) 2012 ARM Limited
3 * All rights reserved.
4 *
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.
13 *
14 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
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.
27 *
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.
39 *
40 * Authors: Erik Hallnor
41 */
42
43/**
44 * @file
45 * Definition of BaseCache functions.
46 */
47
48#include "cpu/base.hh"
49#include "cpu/smt.hh"
50#include "debug/Cache.hh"
51#include "debug/Drain.hh"
52#include "mem/cache/base.hh"
53#include "mem/cache/mshr.hh"
54#include "sim/full_system.hh"
55
56using namespace std;
57
58BaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name,
59                                          BaseCache *_cache,
60                                          const std::string &_label)
61    : QueuedSlavePort(_name, _cache, queue), queue(*_cache, *this, _label),
62      blocked(false), mustSendRetry(false), sendRetryEvent(this)
63{
64}
65
66BaseCache::BaseCache(const Params *p)
67    : MemObject(p),
68      mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs),
69      writeBuffer("write buffer", p->write_buffers, p->mshrs+1000,
70                  MSHRQueue_WriteBuffer),
71      blkSize(p->block_size),
72      hitLatency(p->hit_latency),
73      responseLatency(p->response_latency),
74      numTarget(p->tgts_per_mshr),
75      forwardSnoops(p->forward_snoops),
76      isTopLevel(p->is_top_level),
77      blocked(0),
78      noTargetMSHR(NULL),
79      missCount(p->max_miss_count),
80      drainManager(NULL),
81      addrRanges(p->addr_ranges.begin(), p->addr_ranges.end()),
82      system(p->system)
83{
84}
85
86void
87BaseCache::CacheSlavePort::setBlocked()
88{
89    assert(!blocked);
90    DPRINTF(CachePort, "Cache port %s blocking new requests\n", name());
91    blocked = true;
92}
93
94void
95BaseCache::CacheSlavePort::clearBlocked()
96{
97    assert(blocked);
98    DPRINTF(CachePort, "Cache port %s accepting new requests\n", name());
99    blocked = false;
100    if (mustSendRetry) {
101        DPRINTF(CachePort, "Cache port %s sending retry\n", name());
102        mustSendRetry = false;
103        // @TODO: need to find a better time (next bus cycle?)
104        owner.schedule(sendRetryEvent, curTick() + 1);
105    }
106}
107
108
109void
110BaseCache::init()
111{
112    if (!cpuSidePort->isConnected() || !memSidePort->isConnected())
113        fatal("Cache ports on %s are not connected\n", name());
114    cpuSidePort->sendRangeChange();
115}
116
117BaseMasterPort &
118BaseCache::getMasterPort(const std::string &if_name, PortID idx)
119{
120    if (if_name == "mem_side") {
121        return *memSidePort;
122    }  else {
123        return MemObject::getMasterPort(if_name, idx);
124    }
125}
126
127BaseSlavePort &
128BaseCache::getSlavePort(const std::string &if_name, PortID idx)
129{
130    if (if_name == "cpu_side") {
131        return *cpuSidePort;
132    } else {
133        return MemObject::getSlavePort(if_name, idx);
134    }
135}
136
137void
138BaseCache::regStats()
139{
140    using namespace Stats;
141
142    // Hit statistics
143    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
144        MemCmd cmd(access_idx);
145        const string &cstr = cmd.toString();
146
147        hits[access_idx]
148            .init(system->maxMasters())
149            .name(name() + "." + cstr + "_hits")
150            .desc("number of " + cstr + " hits")
151            .flags(total | nozero | nonan)
152            ;
153        for (int i = 0; i < system->maxMasters(); i++) {
154            hits[access_idx].subname(i, system->getMasterName(i));
155        }
156    }
157
158// These macros make it easier to sum the right subset of commands and
159// to change the subset of commands that are considered "demand" vs
160// "non-demand"
161#define SUM_DEMAND(s) \
162    (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
163
164// should writebacks be included here?  prior code was inconsistent...
165#define SUM_NON_DEMAND(s) \
166    (s[MemCmd::SoftPFReq] + s[MemCmd::HardPFReq])
167
168    demandHits
169        .name(name() + ".demand_hits")
170        .desc("number of demand (read+write) hits")
171        .flags(total | nozero | nonan)
172        ;
173    demandHits = SUM_DEMAND(hits);
174    for (int i = 0; i < system->maxMasters(); i++) {
175        demandHits.subname(i, system->getMasterName(i));
176    }
177
178    overallHits
179        .name(name() + ".overall_hits")
180        .desc("number of overall hits")
181        .flags(total | nozero | nonan)
182        ;
183    overallHits = demandHits + SUM_NON_DEMAND(hits);
184    for (int i = 0; i < system->maxMasters(); i++) {
185        overallHits.subname(i, system->getMasterName(i));
186    }
187
188    // Miss statistics
189    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
190        MemCmd cmd(access_idx);
191        const string &cstr = cmd.toString();
192
193        misses[access_idx]
194            .init(system->maxMasters())
195            .name(name() + "." + cstr + "_misses")
196            .desc("number of " + cstr + " misses")
197            .flags(total | nozero | nonan)
198            ;
199        for (int i = 0; i < system->maxMasters(); i++) {
200            misses[access_idx].subname(i, system->getMasterName(i));
201        }
202    }
203
204    demandMisses
205        .name(name() + ".demand_misses")
206        .desc("number of demand (read+write) misses")
207        .flags(total | nozero | nonan)
208        ;
209    demandMisses = SUM_DEMAND(misses);
210    for (int i = 0; i < system->maxMasters(); i++) {
211        demandMisses.subname(i, system->getMasterName(i));
212    }
213
214    overallMisses
215        .name(name() + ".overall_misses")
216        .desc("number of overall misses")
217        .flags(total | nozero | nonan)
218        ;
219    overallMisses = demandMisses + SUM_NON_DEMAND(misses);
220    for (int i = 0; i < system->maxMasters(); i++) {
221        overallMisses.subname(i, system->getMasterName(i));
222    }
223
224    // Miss latency statistics
225    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
226        MemCmd cmd(access_idx);
227        const string &cstr = cmd.toString();
228
229        missLatency[access_idx]
230            .init(system->maxMasters())
231            .name(name() + "." + cstr + "_miss_latency")
232            .desc("number of " + cstr + " miss cycles")
233            .flags(total | nozero | nonan)
234            ;
235        for (int i = 0; i < system->maxMasters(); i++) {
236            missLatency[access_idx].subname(i, system->getMasterName(i));
237        }
238    }
239
240    demandMissLatency
241        .name(name() + ".demand_miss_latency")
242        .desc("number of demand (read+write) miss cycles")
243        .flags(total | nozero | nonan)
244        ;
245    demandMissLatency = SUM_DEMAND(missLatency);
246    for (int i = 0; i < system->maxMasters(); i++) {
247        demandMissLatency.subname(i, system->getMasterName(i));
248    }
249
250    overallMissLatency
251        .name(name() + ".overall_miss_latency")
252        .desc("number of overall miss cycles")
253        .flags(total | nozero | nonan)
254        ;
255    overallMissLatency = demandMissLatency + SUM_NON_DEMAND(missLatency);
256    for (int i = 0; i < system->maxMasters(); i++) {
257        overallMissLatency.subname(i, system->getMasterName(i));
258    }
259
260    // access formulas
261    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
262        MemCmd cmd(access_idx);
263        const string &cstr = cmd.toString();
264
265        accesses[access_idx]
266            .name(name() + "." + cstr + "_accesses")
267            .desc("number of " + cstr + " accesses(hits+misses)")
268            .flags(total | nozero | nonan)
269            ;
270        accesses[access_idx] = hits[access_idx] + misses[access_idx];
271
272        for (int i = 0; i < system->maxMasters(); i++) {
273            accesses[access_idx].subname(i, system->getMasterName(i));
274        }
275    }
276
277    demandAccesses
278        .name(name() + ".demand_accesses")
279        .desc("number of demand (read+write) accesses")
280        .flags(total | nozero | nonan)
281        ;
282    demandAccesses = demandHits + demandMisses;
283    for (int i = 0; i < system->maxMasters(); i++) {
284        demandAccesses.subname(i, system->getMasterName(i));
285    }
286
287    overallAccesses
288        .name(name() + ".overall_accesses")
289        .desc("number of overall (read+write) accesses")
290        .flags(total | nozero | nonan)
291        ;
292    overallAccesses = overallHits + overallMisses;
293    for (int i = 0; i < system->maxMasters(); i++) {
294        overallAccesses.subname(i, system->getMasterName(i));
295    }
296
297    // miss rate formulas
298    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
299        MemCmd cmd(access_idx);
300        const string &cstr = cmd.toString();
301
302        missRate[access_idx]
303            .name(name() + "." + cstr + "_miss_rate")
304            .desc("miss rate for " + cstr + " accesses")
305            .flags(total | nozero | nonan)
306            ;
307        missRate[access_idx] = misses[access_idx] / accesses[access_idx];
308
309        for (int i = 0; i < system->maxMasters(); i++) {
310            missRate[access_idx].subname(i, system->getMasterName(i));
311        }
312    }
313
314    demandMissRate
315        .name(name() + ".demand_miss_rate")
316        .desc("miss rate for demand accesses")
317        .flags(total | nozero | nonan)
318        ;
319    demandMissRate = demandMisses / demandAccesses;
320    for (int i = 0; i < system->maxMasters(); i++) {
321        demandMissRate.subname(i, system->getMasterName(i));
322    }
323
324    overallMissRate
325        .name(name() + ".overall_miss_rate")
326        .desc("miss rate for overall accesses")
327        .flags(total | nozero | nonan)
328        ;
329    overallMissRate = overallMisses / overallAccesses;
330    for (int i = 0; i < system->maxMasters(); i++) {
331        overallMissRate.subname(i, system->getMasterName(i));
332    }
333
334    // miss latency formulas
335    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
336        MemCmd cmd(access_idx);
337        const string &cstr = cmd.toString();
338
339        avgMissLatency[access_idx]
340            .name(name() + "." + cstr + "_avg_miss_latency")
341            .desc("average " + cstr + " miss latency")
342            .flags(total | nozero | nonan)
343            ;
344        avgMissLatency[access_idx] =
345            missLatency[access_idx] / misses[access_idx];
346
347        for (int i = 0; i < system->maxMasters(); i++) {
348            avgMissLatency[access_idx].subname(i, system->getMasterName(i));
349        }
350    }
351
352    demandAvgMissLatency
353        .name(name() + ".demand_avg_miss_latency")
354        .desc("average overall miss latency")
355        .flags(total | nozero | nonan)
356        ;
357    demandAvgMissLatency = demandMissLatency / demandMisses;
358    for (int i = 0; i < system->maxMasters(); i++) {
359        demandAvgMissLatency.subname(i, system->getMasterName(i));
360    }
361
362    overallAvgMissLatency
363        .name(name() + ".overall_avg_miss_latency")
364        .desc("average overall miss latency")
365        .flags(total | nozero | nonan)
366        ;
367    overallAvgMissLatency = overallMissLatency / overallMisses;
368    for (int i = 0; i < system->maxMasters(); i++) {
369        overallAvgMissLatency.subname(i, system->getMasterName(i));
370    }
371
372    blocked_cycles.init(NUM_BLOCKED_CAUSES);
373    blocked_cycles
374        .name(name() + ".blocked_cycles")
375        .desc("number of cycles access was blocked")
376        .subname(Blocked_NoMSHRs, "no_mshrs")
377        .subname(Blocked_NoTargets, "no_targets")
378        ;
379
380
381    blocked_causes.init(NUM_BLOCKED_CAUSES);
382    blocked_causes
383        .name(name() + ".blocked")
384        .desc("number of cycles access was blocked")
385        .subname(Blocked_NoMSHRs, "no_mshrs")
386        .subname(Blocked_NoTargets, "no_targets")
387        ;
388
389    avg_blocked
390        .name(name() + ".avg_blocked_cycles")
391        .desc("average number of cycles each access was blocked")
392        .subname(Blocked_NoMSHRs, "no_mshrs")
393        .subname(Blocked_NoTargets, "no_targets")
394        ;
395
396    avg_blocked = blocked_cycles / blocked_causes;
397
398    fastWrites
399        .name(name() + ".fast_writes")
400        .desc("number of fast writes performed")
401        ;
402
403    cacheCopies
404        .name(name() + ".cache_copies")
405        .desc("number of cache copies performed")
406        ;
407
408    writebacks
409        .init(system->maxMasters())
410        .name(name() + ".writebacks")
411        .desc("number of writebacks")
412        .flags(total | nozero | nonan)
413        ;
414    for (int i = 0; i < system->maxMasters(); i++) {
415        writebacks.subname(i, system->getMasterName(i));
416    }
417
418    // MSHR statistics
419    // MSHR hit statistics
420    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
421        MemCmd cmd(access_idx);
422        const string &cstr = cmd.toString();
423
424        mshr_hits[access_idx]
425            .init(system->maxMasters())
426            .name(name() + "." + cstr + "_mshr_hits")
427            .desc("number of " + cstr + " MSHR hits")
428            .flags(total | nozero | nonan)
429            ;
430        for (int i = 0; i < system->maxMasters(); i++) {
431            mshr_hits[access_idx].subname(i, system->getMasterName(i));
432        }
433    }
434
435    demandMshrHits
436        .name(name() + ".demand_mshr_hits")
437        .desc("number of demand (read+write) MSHR hits")
438        .flags(total | nozero | nonan)
439        ;
440    demandMshrHits = SUM_DEMAND(mshr_hits);
441    for (int i = 0; i < system->maxMasters(); i++) {
442        demandMshrHits.subname(i, system->getMasterName(i));
443    }
444
445    overallMshrHits
446        .name(name() + ".overall_mshr_hits")
447        .desc("number of overall MSHR hits")
448        .flags(total | nozero | nonan)
449        ;
450    overallMshrHits = demandMshrHits + SUM_NON_DEMAND(mshr_hits);
451    for (int i = 0; i < system->maxMasters(); i++) {
452        overallMshrHits.subname(i, system->getMasterName(i));
453    }
454
455    // MSHR miss statistics
456    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
457        MemCmd cmd(access_idx);
458        const string &cstr = cmd.toString();
459
460        mshr_misses[access_idx]
461            .init(system->maxMasters())
462            .name(name() + "." + cstr + "_mshr_misses")
463            .desc("number of " + cstr + " MSHR misses")
464            .flags(total | nozero | nonan)
465            ;
466        for (int i = 0; i < system->maxMasters(); i++) {
467            mshr_misses[access_idx].subname(i, system->getMasterName(i));
468        }
469    }
470
471    demandMshrMisses
472        .name(name() + ".demand_mshr_misses")
473        .desc("number of demand (read+write) MSHR misses")
474        .flags(total | nozero | nonan)
475        ;
476    demandMshrMisses = SUM_DEMAND(mshr_misses);
477    for (int i = 0; i < system->maxMasters(); i++) {
478        demandMshrMisses.subname(i, system->getMasterName(i));
479    }
480
481    overallMshrMisses
482        .name(name() + ".overall_mshr_misses")
483        .desc("number of overall MSHR misses")
484        .flags(total | nozero | nonan)
485        ;
486    overallMshrMisses = demandMshrMisses + SUM_NON_DEMAND(mshr_misses);
487    for (int i = 0; i < system->maxMasters(); i++) {
488        overallMshrMisses.subname(i, system->getMasterName(i));
489    }
490
491    // MSHR miss latency statistics
492    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
493        MemCmd cmd(access_idx);
494        const string &cstr = cmd.toString();
495
496        mshr_miss_latency[access_idx]
497            .init(system->maxMasters())
498            .name(name() + "." + cstr + "_mshr_miss_latency")
499            .desc("number of " + cstr + " MSHR miss cycles")
500            .flags(total | nozero | nonan)
501            ;
502        for (int i = 0; i < system->maxMasters(); i++) {
503            mshr_miss_latency[access_idx].subname(i, system->getMasterName(i));
504        }
505    }
506
507    demandMshrMissLatency
508        .name(name() + ".demand_mshr_miss_latency")
509        .desc("number of demand (read+write) MSHR miss cycles")
510        .flags(total | nozero | nonan)
511        ;
512    demandMshrMissLatency = SUM_DEMAND(mshr_miss_latency);
513    for (int i = 0; i < system->maxMasters(); i++) {
514        demandMshrMissLatency.subname(i, system->getMasterName(i));
515    }
516
517    overallMshrMissLatency
518        .name(name() + ".overall_mshr_miss_latency")
519        .desc("number of overall MSHR miss cycles")
520        .flags(total | nozero | nonan)
521        ;
522    overallMshrMissLatency =
523        demandMshrMissLatency + SUM_NON_DEMAND(mshr_miss_latency);
524    for (int i = 0; i < system->maxMasters(); i++) {
525        overallMshrMissLatency.subname(i, system->getMasterName(i));
526    }
527
528    // MSHR uncacheable statistics
529    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
530        MemCmd cmd(access_idx);
531        const string &cstr = cmd.toString();
532
533        mshr_uncacheable[access_idx]
534            .init(system->maxMasters())
535            .name(name() + "." + cstr + "_mshr_uncacheable")
536            .desc("number of " + cstr + " MSHR uncacheable")
537            .flags(total | nozero | nonan)
538            ;
539        for (int i = 0; i < system->maxMasters(); i++) {
540            mshr_uncacheable[access_idx].subname(i, system->getMasterName(i));
541        }
542    }
543
544    overallMshrUncacheable
545        .name(name() + ".overall_mshr_uncacheable_misses")
546        .desc("number of overall MSHR uncacheable misses")
547        .flags(total | nozero | nonan)
548        ;
549    overallMshrUncacheable =
550        SUM_DEMAND(mshr_uncacheable) + SUM_NON_DEMAND(mshr_uncacheable);
551    for (int i = 0; i < system->maxMasters(); i++) {
552        overallMshrUncacheable.subname(i, system->getMasterName(i));
553    }
554
555    // MSHR miss latency statistics
556    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
557        MemCmd cmd(access_idx);
558        const string &cstr = cmd.toString();
559
560        mshr_uncacheable_lat[access_idx]
561            .init(system->maxMasters())
562            .name(name() + "." + cstr + "_mshr_uncacheable_latency")
563            .desc("number of " + cstr + " MSHR uncacheable cycles")
564            .flags(total | nozero | nonan)
565            ;
566        for (int i = 0; i < system->maxMasters(); i++) {
567            mshr_uncacheable_lat[access_idx].subname(i, system->getMasterName(i));
568        }
569    }
570
571    overallMshrUncacheableLatency
572        .name(name() + ".overall_mshr_uncacheable_latency")
573        .desc("number of overall MSHR uncacheable cycles")
574        .flags(total | nozero | nonan)
575        ;
576    overallMshrUncacheableLatency =
577        SUM_DEMAND(mshr_uncacheable_lat) +
578        SUM_NON_DEMAND(mshr_uncacheable_lat);
579    for (int i = 0; i < system->maxMasters(); i++) {
580        overallMshrUncacheableLatency.subname(i, system->getMasterName(i));
581    }
582
583#if 0
584    // MSHR access formulas
585    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
586        MemCmd cmd(access_idx);
587        const string &cstr = cmd.toString();
588
589        mshrAccesses[access_idx]
590            .name(name() + "." + cstr + "_mshr_accesses")
591            .desc("number of " + cstr + " mshr accesses(hits+misses)")
592            .flags(total | nozero | nonan)
593            ;
594        mshrAccesses[access_idx] =
595            mshr_hits[access_idx] + mshr_misses[access_idx]
596            + mshr_uncacheable[access_idx];
597    }
598
599    demandMshrAccesses
600        .name(name() + ".demand_mshr_accesses")
601        .desc("number of demand (read+write) mshr accesses")
602        .flags(total | nozero | nonan)
603        ;
604    demandMshrAccesses = demandMshrHits + demandMshrMisses;
605
606    overallMshrAccesses
607        .name(name() + ".overall_mshr_accesses")
608        .desc("number of overall (read+write) mshr accesses")
609        .flags(total | nozero | nonan)
610        ;
611    overallMshrAccesses = overallMshrHits + overallMshrMisses
612        + overallMshrUncacheable;
613#endif
614
615    // MSHR miss rate formulas
616    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
617        MemCmd cmd(access_idx);
618        const string &cstr = cmd.toString();
619
620        mshrMissRate[access_idx]
621            .name(name() + "." + cstr + "_mshr_miss_rate")
622            .desc("mshr miss rate for " + cstr + " accesses")
623            .flags(total | nozero | nonan)
624            ;
625        mshrMissRate[access_idx] =
626            mshr_misses[access_idx] / accesses[access_idx];
627
628        for (int i = 0; i < system->maxMasters(); i++) {
629            mshrMissRate[access_idx].subname(i, system->getMasterName(i));
630        }
631    }
632
633    demandMshrMissRate
634        .name(name() + ".demand_mshr_miss_rate")
635        .desc("mshr miss rate for demand accesses")
636        .flags(total | nozero | nonan)
637        ;
638    demandMshrMissRate = demandMshrMisses / demandAccesses;
639    for (int i = 0; i < system->maxMasters(); i++) {
640        demandMshrMissRate.subname(i, system->getMasterName(i));
641    }
642
643    overallMshrMissRate
644        .name(name() + ".overall_mshr_miss_rate")
645        .desc("mshr miss rate for overall accesses")
646        .flags(total | nozero | nonan)
647        ;
648    overallMshrMissRate = overallMshrMisses / overallAccesses;
649    for (int i = 0; i < system->maxMasters(); i++) {
650        overallMshrMissRate.subname(i, system->getMasterName(i));
651    }
652
653    // mshrMiss latency formulas
654    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
655        MemCmd cmd(access_idx);
656        const string &cstr = cmd.toString();
657
658        avgMshrMissLatency[access_idx]
659            .name(name() + "." + cstr + "_avg_mshr_miss_latency")
660            .desc("average " + cstr + " mshr miss latency")
661            .flags(total | nozero | nonan)
662            ;
663        avgMshrMissLatency[access_idx] =
664            mshr_miss_latency[access_idx] / mshr_misses[access_idx];
665
666        for (int i = 0; i < system->maxMasters(); i++) {
667            avgMshrMissLatency[access_idx].subname(i, system->getMasterName(i));
668        }
669    }
670
671    demandAvgMshrMissLatency
672        .name(name() + ".demand_avg_mshr_miss_latency")
673        .desc("average overall mshr miss latency")
674        .flags(total | nozero | nonan)
675        ;
676    demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
677    for (int i = 0; i < system->maxMasters(); i++) {
678        demandAvgMshrMissLatency.subname(i, system->getMasterName(i));
679    }
680
681    overallAvgMshrMissLatency
682        .name(name() + ".overall_avg_mshr_miss_latency")
683        .desc("average overall mshr miss latency")
684        .flags(total | nozero | nonan)
685        ;
686    overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
687    for (int i = 0; i < system->maxMasters(); i++) {
688        overallAvgMshrMissLatency.subname(i, system->getMasterName(i));
689    }
690
691    // mshrUncacheable latency formulas
692    for (int access_idx = 0; access_idx < MemCmd::NUM_MEM_CMDS; ++access_idx) {
693        MemCmd cmd(access_idx);
694        const string &cstr = cmd.toString();
695
696        avgMshrUncacheableLatency[access_idx]
697            .name(name() + "." + cstr + "_avg_mshr_uncacheable_latency")
698            .desc("average " + cstr + " mshr uncacheable latency")
699            .flags(total | nozero | nonan)
700            ;
701        avgMshrUncacheableLatency[access_idx] =
702            mshr_uncacheable_lat[access_idx] / mshr_uncacheable[access_idx];
703
704        for (int i = 0; i < system->maxMasters(); i++) {
705            avgMshrUncacheableLatency[access_idx].subname(i, system->getMasterName(i));
706        }
707    }
708
709    overallAvgMshrUncacheableLatency
710        .name(name() + ".overall_avg_mshr_uncacheable_latency")
711        .desc("average overall mshr uncacheable latency")
712        .flags(total | nozero | nonan)
713        ;
714    overallAvgMshrUncacheableLatency = overallMshrUncacheableLatency / overallMshrUncacheable;
715    for (int i = 0; i < system->maxMasters(); i++) {
716        overallAvgMshrUncacheableLatency.subname(i, system->getMasterName(i));
717    }
718
719    mshr_cap_events
720        .init(system->maxMasters())
721        .name(name() + ".mshr_cap_events")
722        .desc("number of times MSHR cap was activated")
723        .flags(total | nozero | nonan)
724        ;
725    for (int i = 0; i < system->maxMasters(); i++) {
726        mshr_cap_events.subname(i, system->getMasterName(i));
727    }
728
729    //software prefetching stats
730    soft_prefetch_mshr_full
731        .init(system->maxMasters())
732        .name(name() + ".soft_prefetch_mshr_full")
733        .desc("number of mshr full events for SW prefetching instrutions")
734        .flags(total | nozero | nonan)
735        ;
736    for (int i = 0; i < system->maxMasters(); i++) {
737        soft_prefetch_mshr_full.subname(i, system->getMasterName(i));
738    }
739
740    mshr_no_allocate_misses
741        .name(name() +".no_allocate_misses")
742        .desc("Number of misses that were no-allocate")
743        ;
744
745}
746
747unsigned int
748BaseCache::drain(DrainManager *dm)
749{
750    int count = memSidePort->drain(dm) + cpuSidePort->drain(dm) +
751        mshrQueue.drain(dm) + writeBuffer.drain(dm);
752
753    // Set status
754    if (count != 0) {
755        drainManager = dm;
756
757        setDrainState(Drainable::Draining);
758        DPRINTF(Drain, "Cache not drained\n");
759        return count;
760    }
761
762    setDrainState(Drainable::Drained);
763    return 0;
764}
765