1/*
2 * Copyright (c) 2012-2014 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 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Thomas Grass
38 *          Andreas Hansson
39 *          Marco Elver
40 */
41
42#ifndef __MEM_MEM_CHECKER_MONITOR_HH__
43#define __MEM_MEM_CHECKER_MONITOR_HH__
44
45#include "base/statistics.hh"
46#include "mem/mem_checker.hh"
47#include "params/MemCheckerMonitor.hh"
48#include "sim/sim_object.hh"
49#include "sim/system.hh"
50
51/**
52 * Implements a MemChecker monitor, to be inserted between two ports.
53 */
54class MemCheckerMonitor : public SimObject
55{
56  public:
57
58    /** Parameters of memchecker monitor */
59    typedef MemCheckerMonitorParams Params;
60    const Params* params() const
61    { return reinterpret_cast<const Params*>(_params); }
62
63    /**
64     * Constructor based on the Python params
65     *
66     * @param params Python parameters
67     */
68    MemCheckerMonitor(Params* params);
69
70    /** Destructor */
71    ~MemCheckerMonitor();
72
73    Port &getPort(const std::string &if_name,
74                  PortID idx=InvalidPortID) override;
75
76    void init() override;
77
78  private:
79
80    struct MemCheckerMonitorSenderState : public Packet::SenderState
81    {
82        MemCheckerMonitorSenderState(MemChecker::Serial _serial)
83            : serial(_serial)
84        {}
85
86        MemChecker::Serial serial;
87    };
88
89    /**
90     * This is the master port of the communication monitor. All recv
91     * functions call a function in MemCheckerMonitor, where the
92     * send function of the slave port is called. Besides this, these
93     * functions can also perform actions for capturing statistics.
94     */
95    class MonitorMasterPort : public MasterPort
96    {
97
98      public:
99
100        MonitorMasterPort(const std::string& _name, MemCheckerMonitor& _mon)
101            : MasterPort(_name, &_mon), mon(_mon)
102        { }
103
104      protected:
105
106        void recvFunctionalSnoop(PacketPtr pkt)
107        {
108            mon.recvFunctionalSnoop(pkt);
109        }
110
111        Tick recvAtomicSnoop(PacketPtr pkt)
112        {
113            return mon.recvAtomicSnoop(pkt);
114        }
115
116        bool recvTimingResp(PacketPtr pkt)
117        {
118            return mon.recvTimingResp(pkt);
119        }
120
121        void recvTimingSnoopReq(PacketPtr pkt)
122        {
123            mon.recvTimingSnoopReq(pkt);
124        }
125
126        void recvRangeChange()
127        {
128            mon.recvRangeChange();
129        }
130
131        bool isSnooping() const
132        {
133            return mon.isSnooping();
134        }
135
136        void recvReqRetry()
137        {
138            mon.recvReqRetry();
139        }
140
141      private:
142
143        MemCheckerMonitor& mon;
144
145    };
146
147    /** Instance of master port, facing the memory side */
148    MonitorMasterPort masterPort;
149
150    /**
151     * This is the slave port of the communication monitor. All recv
152     * functions call a function in MemCheckerMonitor, where the
153     * send function of the master port is called. Besides this, these
154     * functions can also perform actions for capturing statistics.
155     */
156    class MonitorSlavePort : public SlavePort
157    {
158
159      public:
160
161        MonitorSlavePort(const std::string& _name, MemCheckerMonitor& _mon)
162            : SlavePort(_name, &_mon), mon(_mon)
163        { }
164
165      protected:
166
167        void recvFunctional(PacketPtr pkt)
168        {
169            mon.recvFunctional(pkt);
170        }
171
172        Tick recvAtomic(PacketPtr pkt)
173        {
174            return mon.recvAtomic(pkt);
175        }
176
177        bool recvTimingReq(PacketPtr pkt)
178        {
179            return mon.recvTimingReq(pkt);
180        }
181
182        bool recvTimingSnoopResp(PacketPtr pkt)
183        {
184            return mon.recvTimingSnoopResp(pkt);
185        }
186
187        AddrRangeList getAddrRanges() const
188        {
189            return mon.getAddrRanges();
190        }
191
192        void recvRespRetry()
193        {
194            mon.recvRespRetry();
195        }
196
197      private:
198
199        MemCheckerMonitor& mon;
200
201    };
202
203    /** Instance of slave port, i.e. on the CPU side */
204    MonitorSlavePort slavePort;
205
206    void recvFunctional(PacketPtr pkt);
207
208    void recvFunctionalSnoop(PacketPtr pkt);
209
210    Tick recvAtomic(PacketPtr pkt);
211
212    Tick recvAtomicSnoop(PacketPtr pkt);
213
214    bool recvTimingReq(PacketPtr pkt);
215
216    bool recvTimingResp(PacketPtr pkt);
217
218    void recvTimingSnoopReq(PacketPtr pkt);
219
220    bool recvTimingSnoopResp(PacketPtr pkt);
221
222    AddrRangeList getAddrRanges() const;
223
224    bool isSnooping() const;
225
226    void recvReqRetry();
227
228    void recvRespRetry();
229
230    void recvRangeChange();
231
232    bool warnOnly;
233
234    MemChecker *memchecker;
235};
236
237#endif //__MEM_MEM_CHECKER_MONITOR_HH__
238