mem_checker_monitor.cc (13377:2e04ce7d3fd4) mem_checker_monitor.cc (13449:2f7efa89c58b)
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#include "mem/mem_checker_monitor.hh"
43
44#include <memory>
45
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#include "mem/mem_checker_monitor.hh"
43
44#include <memory>
45
46#include "base/logging.hh"
46#include "base/output.hh"
47#include "base/trace.hh"
48#include "debug/MemCheckerMonitor.hh"
49
50MemCheckerMonitor::MemCheckerMonitor(Params* params)
51 : MemObject(params),
52 masterPort(name() + "-master", *this),
53 slavePort(name() + "-slave", *this),
54 warnOnly(params->warn_only),
55 memchecker(params->memchecker)
56{}
57
58MemCheckerMonitor::~MemCheckerMonitor()
59{}
60
61MemCheckerMonitor*
62MemCheckerMonitorParams::create()
63{
64 return new MemCheckerMonitor(this);
65}
66
67void
68MemCheckerMonitor::init()
69{
70 // make sure both sides of the monitor are connected
71 if (!slavePort.isConnected() || !masterPort.isConnected())
72 fatal("Communication monitor is not connected on both sides.\n");
73}
74
75BaseMasterPort&
76MemCheckerMonitor::getMasterPort(const std::string& if_name, PortID idx)
77{
78 if (if_name == "master" || if_name == "mem_side") {
79 return masterPort;
80 } else {
81 return MemObject::getMasterPort(if_name, idx);
82 }
83}
84
85BaseSlavePort&
86MemCheckerMonitor::getSlavePort(const std::string& if_name, PortID idx)
87{
88 if (if_name == "slave" || if_name == "cpu_side") {
89 return slavePort;
90 } else {
91 return MemObject::getSlavePort(if_name, idx);
92 }
93}
94
95void
96MemCheckerMonitor::recvFunctional(PacketPtr pkt)
97{
98 Addr addr = pkt->getAddr();
99 unsigned size = pkt->getSize();
100
101 // Conservatively reset this address-range. Alternatively we could try to
102 // update the values seen by the memchecker, however, there may be other
103 // reads/writes to these location from other devices we do not see.
104 memchecker->reset(addr, size);
105
106 masterPort.sendFunctional(pkt);
107
108 DPRINTF(MemCheckerMonitor,
109 "Forwarded functional access: addr = %#llx, size = %d\n",
110 addr, size);
111}
112
113void
114MemCheckerMonitor::recvFunctionalSnoop(PacketPtr pkt)
115{
116 Addr addr = pkt->getAddr();
117 unsigned size = pkt->getSize();
118
119 // See above.
120 memchecker->reset(addr, size);
121
122 slavePort.sendFunctionalSnoop(pkt);
123
124 DPRINTF(MemCheckerMonitor,
125 "Received functional snoop: addr = %#llx, size = %d\n",
126 addr, size);
127}
128
129Tick
130MemCheckerMonitor::recvAtomic(PacketPtr pkt)
131{
47#include "base/output.hh"
48#include "base/trace.hh"
49#include "debug/MemCheckerMonitor.hh"
50
51MemCheckerMonitor::MemCheckerMonitor(Params* params)
52 : MemObject(params),
53 masterPort(name() + "-master", *this),
54 slavePort(name() + "-slave", *this),
55 warnOnly(params->warn_only),
56 memchecker(params->memchecker)
57{}
58
59MemCheckerMonitor::~MemCheckerMonitor()
60{}
61
62MemCheckerMonitor*
63MemCheckerMonitorParams::create()
64{
65 return new MemCheckerMonitor(this);
66}
67
68void
69MemCheckerMonitor::init()
70{
71 // make sure both sides of the monitor are connected
72 if (!slavePort.isConnected() || !masterPort.isConnected())
73 fatal("Communication monitor is not connected on both sides.\n");
74}
75
76BaseMasterPort&
77MemCheckerMonitor::getMasterPort(const std::string& if_name, PortID idx)
78{
79 if (if_name == "master" || if_name == "mem_side") {
80 return masterPort;
81 } else {
82 return MemObject::getMasterPort(if_name, idx);
83 }
84}
85
86BaseSlavePort&
87MemCheckerMonitor::getSlavePort(const std::string& if_name, PortID idx)
88{
89 if (if_name == "slave" || if_name == "cpu_side") {
90 return slavePort;
91 } else {
92 return MemObject::getSlavePort(if_name, idx);
93 }
94}
95
96void
97MemCheckerMonitor::recvFunctional(PacketPtr pkt)
98{
99 Addr addr = pkt->getAddr();
100 unsigned size = pkt->getSize();
101
102 // Conservatively reset this address-range. Alternatively we could try to
103 // update the values seen by the memchecker, however, there may be other
104 // reads/writes to these location from other devices we do not see.
105 memchecker->reset(addr, size);
106
107 masterPort.sendFunctional(pkt);
108
109 DPRINTF(MemCheckerMonitor,
110 "Forwarded functional access: addr = %#llx, size = %d\n",
111 addr, size);
112}
113
114void
115MemCheckerMonitor::recvFunctionalSnoop(PacketPtr pkt)
116{
117 Addr addr = pkt->getAddr();
118 unsigned size = pkt->getSize();
119
120 // See above.
121 memchecker->reset(addr, size);
122
123 slavePort.sendFunctionalSnoop(pkt);
124
125 DPRINTF(MemCheckerMonitor,
126 "Received functional snoop: addr = %#llx, size = %d\n",
127 addr, size);
128}
129
130Tick
131MemCheckerMonitor::recvAtomic(PacketPtr pkt)
132{
132 assert(false && "Atomic not supported");
133 return masterPort.sendAtomic(pkt);
133 panic("Atomic not supported");
134}
135
136Tick
137MemCheckerMonitor::recvAtomicSnoop(PacketPtr pkt)
138{
134}
135
136Tick
137MemCheckerMonitor::recvAtomicSnoop(PacketPtr pkt)
138{
139 assert(false && "Atomic not supported");
140 return slavePort.sendAtomicSnoop(pkt);
139 panic("Atomic not supported");
141}
142
143bool
144MemCheckerMonitor::recvTimingReq(PacketPtr pkt)
145{
146 // should always see a request
147 assert(pkt->isRequest());
148
149 // Store relevant fields of packet, because packet may be modified
150 // or even deleted when sendTiming() is called.
151 //
152 // For reads we are only interested in real reads, and not prefetches, as
153 // it is not guaranteed that the prefetch returns any useful data.
154 bool is_read = pkt->isRead() && !pkt->req->isPrefetch();
155 bool is_write = pkt->isWrite();
156 unsigned size = pkt->getSize();
157 Addr addr = pkt->getAddr();
158 bool expects_response = pkt->needsResponse() && !pkt->cacheResponding();
159 std::unique_ptr<uint8_t[]> pkt_data;
160 MemCheckerMonitorSenderState* state = NULL;
161
162 if (expects_response && is_write) {
163 // On receipt of a request, only need to allocate pkt_data if this is a
164 // write. For reads, we have no data yet, so it doesn't make sense to
165 // allocate.
166 pkt_data.reset(new uint8_t[size]);
167 pkt->writeData(pkt_data.get());
168 }
169
170 // If a cache miss is served by a cache, a monitor near the memory
171 // would see a request which needs a response, but this response
172 // would not come back from the memory. Therefore
173 // we additionally have to check the inhibit flag.
174 if (expects_response && (is_read || is_write)) {
175 state = new MemCheckerMonitorSenderState(0);
176 pkt->pushSenderState(state);
177 }
178
179 // Attempt to send the packet
180 bool successful = masterPort.sendTimingReq(pkt);
181
182 // If not successful, restore the sender state
183 if (!successful && expects_response && (is_read || is_write)) {
184 delete pkt->popSenderState();
185 }
186
187 if (successful && expects_response) {
188 if (is_read) {
189 MemChecker::Serial serial = memchecker->startRead(curTick(),
190 addr,
191 size);
192
193 // At the time where we push the sender-state, we do not yet know
194 // the serial the MemChecker class will assign to this request. We
195 // cannot call startRead at the time we push the sender-state, as
196 // the masterPort may not be successful in executing sendTimingReq,
197 // and in case of a failure, we must not modify the state of the
198 // MemChecker.
199 //
200 // Once we know that sendTimingReq was successful, we can set the
201 // serial of the newly constructed sender-state. This is legal, as
202 // we know that nobody else will touch nor is responsible for
203 // deletion of our sender-state.
204 state->serial = serial;
205
206 DPRINTF(MemCheckerMonitor,
207 "Forwarded read request: serial = %d, addr = %#llx, "
208 "size = %d\n",
209 serial, addr, size);
210 } else if (is_write) {
211 MemChecker::Serial serial = memchecker->startWrite(curTick(),
212 addr,
213 size,
214 pkt_data.get());
215
216 state->serial = serial;
217
218 DPRINTF(MemCheckerMonitor,
219 "Forwarded write request: serial = %d, addr = %#llx, "
220 "size = %d\n",
221 serial, addr, size);
222 } else {
223 DPRINTF(MemCheckerMonitor,
224 "Forwarded non read/write request: addr = %#llx\n", addr);
225 }
226 } else if (successful) {
227 DPRINTF(MemCheckerMonitor,
228 "Forwarded request marked for cache response: addr = %#llx\n",
229 addr);
230 }
231
232 return successful;
233}
234
235bool
236MemCheckerMonitor::recvTimingResp(PacketPtr pkt)
237{
238 // should always see responses
239 assert(pkt->isResponse());
240
241 // Store relevant fields of packet, because packet may be modified
242 // or even deleted when sendTiming() is called.
243 bool is_read = pkt->isRead() && !pkt->req->isPrefetch();
244 bool is_write = pkt->isWrite();
245 bool is_failed_LLSC = pkt->isLLSC() && pkt->req->getExtraData() == 0;
246 unsigned size = pkt->getSize();
247 Addr addr = pkt->getAddr();
248 std::unique_ptr<uint8_t[]> pkt_data;
249 MemCheckerMonitorSenderState* received_state = NULL;
250
251 if (is_read) {
252 // On receipt of a response, only need to allocate pkt_data if this is
253 // a read. For writes, we have already given the MemChecker the data on
254 // the request, so it doesn't make sense to allocate on write.
255 pkt_data.reset(new uint8_t[size]);
256 pkt->writeData(pkt_data.get());
257 }
258
259 if (is_read || is_write) {
260 received_state =
261 dynamic_cast<MemCheckerMonitorSenderState*>(pkt->senderState);
262
263 // Restore initial sender state
264 panic_if(received_state == NULL,
265 "Monitor got a response without monitor sender state\n");
266
267 // Restore the state
268 pkt->senderState = received_state->predecessor;
269 }
270
271 // Attempt to send the packet
272 bool successful = slavePort.sendTimingResp(pkt);
273
274 // If packet successfully send, complete transaction in MemChecker
275 // instance, and delete sender state, otherwise restore state.
276 if (successful) {
277 if (is_read) {
278 DPRINTF(MemCheckerMonitor,
279 "Received read response: serial = %d, addr = %#llx, "
280 "size = %d\n",
281 received_state->serial, addr, size);
282
283 bool result = memchecker->completeRead(received_state->serial,
284 curTick(),
285 addr,
286 size,
287 pkt_data.get());
288
289 if (!result) {
290 warn("%s: read of %#llx @ cycle %d failed:\n%s\n",
291 name(),
292 addr, curTick(),
293 memchecker->getErrorMessage().c_str());
294
295 panic_if(!warnOnly, "MemChecker violation!");
296 }
297
298 delete received_state;
299 } else if (is_write) {
300 DPRINTF(MemCheckerMonitor,
301 "Received write response: serial = %d, addr = %#llx, "
302 "size = %d\n",
303 received_state->serial, addr, size);
304
305 if (is_failed_LLSC) {
306 // The write was not successful, let MemChecker know.
307 memchecker->abortWrite(received_state->serial,
308 addr,
309 size);
310 } else {
311 memchecker->completeWrite(received_state->serial,
312 curTick(),
313 addr,
314 size);
315 }
316
317 delete received_state;
318 } else {
319 DPRINTF(MemCheckerMonitor,
320 "Received non read/write response: addr = %#llx\n", addr);
321 }
322 } else if (is_read || is_write) {
323 // Don't delete anything and let the packet look like we
324 // did not touch it
325 pkt->senderState = received_state;
326 }
327
328 return successful;
329}
330
331void
332MemCheckerMonitor::recvTimingSnoopReq(PacketPtr pkt)
333{
334 slavePort.sendTimingSnoopReq(pkt);
335}
336
337bool
338MemCheckerMonitor::recvTimingSnoopResp(PacketPtr pkt)
339{
340 return masterPort.sendTimingSnoopResp(pkt);
341}
342
343bool
344MemCheckerMonitor::isSnooping() const
345{
346 // check if the connected master port is snooping
347 return slavePort.isSnooping();
348}
349
350AddrRangeList
351MemCheckerMonitor::getAddrRanges() const
352{
353 // get the address ranges of the connected slave port
354 return masterPort.getAddrRanges();
355}
356
357void
358MemCheckerMonitor::recvReqRetry()
359{
360 slavePort.sendRetryReq();
361}
362
363void
364MemCheckerMonitor::recvRespRetry()
365{
366 masterPort.sendRetryResp();
367}
368
369void
370MemCheckerMonitor::recvRangeChange()
371{
372 slavePort.sendRangeChange();
373}
140}
141
142bool
143MemCheckerMonitor::recvTimingReq(PacketPtr pkt)
144{
145 // should always see a request
146 assert(pkt->isRequest());
147
148 // Store relevant fields of packet, because packet may be modified
149 // or even deleted when sendTiming() is called.
150 //
151 // For reads we are only interested in real reads, and not prefetches, as
152 // it is not guaranteed that the prefetch returns any useful data.
153 bool is_read = pkt->isRead() && !pkt->req->isPrefetch();
154 bool is_write = pkt->isWrite();
155 unsigned size = pkt->getSize();
156 Addr addr = pkt->getAddr();
157 bool expects_response = pkt->needsResponse() && !pkt->cacheResponding();
158 std::unique_ptr<uint8_t[]> pkt_data;
159 MemCheckerMonitorSenderState* state = NULL;
160
161 if (expects_response && is_write) {
162 // On receipt of a request, only need to allocate pkt_data if this is a
163 // write. For reads, we have no data yet, so it doesn't make sense to
164 // allocate.
165 pkt_data.reset(new uint8_t[size]);
166 pkt->writeData(pkt_data.get());
167 }
168
169 // If a cache miss is served by a cache, a monitor near the memory
170 // would see a request which needs a response, but this response
171 // would not come back from the memory. Therefore
172 // we additionally have to check the inhibit flag.
173 if (expects_response && (is_read || is_write)) {
174 state = new MemCheckerMonitorSenderState(0);
175 pkt->pushSenderState(state);
176 }
177
178 // Attempt to send the packet
179 bool successful = masterPort.sendTimingReq(pkt);
180
181 // If not successful, restore the sender state
182 if (!successful && expects_response && (is_read || is_write)) {
183 delete pkt->popSenderState();
184 }
185
186 if (successful && expects_response) {
187 if (is_read) {
188 MemChecker::Serial serial = memchecker->startRead(curTick(),
189 addr,
190 size);
191
192 // At the time where we push the sender-state, we do not yet know
193 // the serial the MemChecker class will assign to this request. We
194 // cannot call startRead at the time we push the sender-state, as
195 // the masterPort may not be successful in executing sendTimingReq,
196 // and in case of a failure, we must not modify the state of the
197 // MemChecker.
198 //
199 // Once we know that sendTimingReq was successful, we can set the
200 // serial of the newly constructed sender-state. This is legal, as
201 // we know that nobody else will touch nor is responsible for
202 // deletion of our sender-state.
203 state->serial = serial;
204
205 DPRINTF(MemCheckerMonitor,
206 "Forwarded read request: serial = %d, addr = %#llx, "
207 "size = %d\n",
208 serial, addr, size);
209 } else if (is_write) {
210 MemChecker::Serial serial = memchecker->startWrite(curTick(),
211 addr,
212 size,
213 pkt_data.get());
214
215 state->serial = serial;
216
217 DPRINTF(MemCheckerMonitor,
218 "Forwarded write request: serial = %d, addr = %#llx, "
219 "size = %d\n",
220 serial, addr, size);
221 } else {
222 DPRINTF(MemCheckerMonitor,
223 "Forwarded non read/write request: addr = %#llx\n", addr);
224 }
225 } else if (successful) {
226 DPRINTF(MemCheckerMonitor,
227 "Forwarded request marked for cache response: addr = %#llx\n",
228 addr);
229 }
230
231 return successful;
232}
233
234bool
235MemCheckerMonitor::recvTimingResp(PacketPtr pkt)
236{
237 // should always see responses
238 assert(pkt->isResponse());
239
240 // Store relevant fields of packet, because packet may be modified
241 // or even deleted when sendTiming() is called.
242 bool is_read = pkt->isRead() && !pkt->req->isPrefetch();
243 bool is_write = pkt->isWrite();
244 bool is_failed_LLSC = pkt->isLLSC() && pkt->req->getExtraData() == 0;
245 unsigned size = pkt->getSize();
246 Addr addr = pkt->getAddr();
247 std::unique_ptr<uint8_t[]> pkt_data;
248 MemCheckerMonitorSenderState* received_state = NULL;
249
250 if (is_read) {
251 // On receipt of a response, only need to allocate pkt_data if this is
252 // a read. For writes, we have already given the MemChecker the data on
253 // the request, so it doesn't make sense to allocate on write.
254 pkt_data.reset(new uint8_t[size]);
255 pkt->writeData(pkt_data.get());
256 }
257
258 if (is_read || is_write) {
259 received_state =
260 dynamic_cast<MemCheckerMonitorSenderState*>(pkt->senderState);
261
262 // Restore initial sender state
263 panic_if(received_state == NULL,
264 "Monitor got a response without monitor sender state\n");
265
266 // Restore the state
267 pkt->senderState = received_state->predecessor;
268 }
269
270 // Attempt to send the packet
271 bool successful = slavePort.sendTimingResp(pkt);
272
273 // If packet successfully send, complete transaction in MemChecker
274 // instance, and delete sender state, otherwise restore state.
275 if (successful) {
276 if (is_read) {
277 DPRINTF(MemCheckerMonitor,
278 "Received read response: serial = %d, addr = %#llx, "
279 "size = %d\n",
280 received_state->serial, addr, size);
281
282 bool result = memchecker->completeRead(received_state->serial,
283 curTick(),
284 addr,
285 size,
286 pkt_data.get());
287
288 if (!result) {
289 warn("%s: read of %#llx @ cycle %d failed:\n%s\n",
290 name(),
291 addr, curTick(),
292 memchecker->getErrorMessage().c_str());
293
294 panic_if(!warnOnly, "MemChecker violation!");
295 }
296
297 delete received_state;
298 } else if (is_write) {
299 DPRINTF(MemCheckerMonitor,
300 "Received write response: serial = %d, addr = %#llx, "
301 "size = %d\n",
302 received_state->serial, addr, size);
303
304 if (is_failed_LLSC) {
305 // The write was not successful, let MemChecker know.
306 memchecker->abortWrite(received_state->serial,
307 addr,
308 size);
309 } else {
310 memchecker->completeWrite(received_state->serial,
311 curTick(),
312 addr,
313 size);
314 }
315
316 delete received_state;
317 } else {
318 DPRINTF(MemCheckerMonitor,
319 "Received non read/write response: addr = %#llx\n", addr);
320 }
321 } else if (is_read || is_write) {
322 // Don't delete anything and let the packet look like we
323 // did not touch it
324 pkt->senderState = received_state;
325 }
326
327 return successful;
328}
329
330void
331MemCheckerMonitor::recvTimingSnoopReq(PacketPtr pkt)
332{
333 slavePort.sendTimingSnoopReq(pkt);
334}
335
336bool
337MemCheckerMonitor::recvTimingSnoopResp(PacketPtr pkt)
338{
339 return masterPort.sendTimingSnoopResp(pkt);
340}
341
342bool
343MemCheckerMonitor::isSnooping() const
344{
345 // check if the connected master port is snooping
346 return slavePort.isSnooping();
347}
348
349AddrRangeList
350MemCheckerMonitor::getAddrRanges() const
351{
352 // get the address ranges of the connected slave port
353 return masterPort.getAddrRanges();
354}
355
356void
357MemCheckerMonitor::recvReqRetry()
358{
359 slavePort.sendRetryReq();
360}
361
362void
363MemCheckerMonitor::recvRespRetry()
364{
365 masterPort.sendRetryResp();
366}
367
368void
369MemCheckerMonitor::recvRangeChange()
370{
371 slavePort.sendRangeChange();
372}