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