110612SMarco.Elver@ARM.com/*
210612SMarco.Elver@ARM.com * Copyright (c) 2012-2014 ARM Limited
310612SMarco.Elver@ARM.com * All rights reserved
410612SMarco.Elver@ARM.com *
510612SMarco.Elver@ARM.com * The license below extends only to copyright in the software and shall
610612SMarco.Elver@ARM.com * not be construed as granting a license to any other intellectual
710612SMarco.Elver@ARM.com * property including but not limited to intellectual property relating
810612SMarco.Elver@ARM.com * to a hardware implementation of the functionality of the software
910612SMarco.Elver@ARM.com * licensed hereunder.  You may use the software subject to the license
1010612SMarco.Elver@ARM.com * terms below provided that you ensure that this notice is replicated
1110612SMarco.Elver@ARM.com * unmodified and in its entirety in all distributions of the software,
1210612SMarco.Elver@ARM.com * modified or unmodified, in source code or in binary form.
1310612SMarco.Elver@ARM.com *
1410612SMarco.Elver@ARM.com * Redistribution and use in source and binary forms, with or without
1510612SMarco.Elver@ARM.com * modification, are permitted provided that the following conditions are
1610612SMarco.Elver@ARM.com * met: redistributions of source code must retain the above copyright
1710612SMarco.Elver@ARM.com * notice, this list of conditions and the following disclaimer;
1810612SMarco.Elver@ARM.com * redistributions in binary form must reproduce the above copyright
1910612SMarco.Elver@ARM.com * notice, this list of conditions and the following disclaimer in the
2010612SMarco.Elver@ARM.com * documentation and/or other materials provided with the distribution;
2110612SMarco.Elver@ARM.com * neither the name of the copyright holders nor the names of its
2210612SMarco.Elver@ARM.com * contributors may be used to endorse or promote products derived from
2310612SMarco.Elver@ARM.com * this software without specific prior written permission.
2410612SMarco.Elver@ARM.com *
2510612SMarco.Elver@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610612SMarco.Elver@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710612SMarco.Elver@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810612SMarco.Elver@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910612SMarco.Elver@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010612SMarco.Elver@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110612SMarco.Elver@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210612SMarco.Elver@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310612SMarco.Elver@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410612SMarco.Elver@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510612SMarco.Elver@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610612SMarco.Elver@ARM.com *
3710612SMarco.Elver@ARM.com * Authors: Thomas Grass
3810612SMarco.Elver@ARM.com *          Andreas Hansson
3910612SMarco.Elver@ARM.com *          Marco Elver
4010612SMarco.Elver@ARM.com */
4110612SMarco.Elver@ARM.com
4211793Sbrandon.potter@amd.com#include "mem/mem_checker_monitor.hh"
4311793Sbrandon.potter@amd.com
4410612SMarco.Elver@ARM.com#include <memory>
4510612SMarco.Elver@ARM.com
4613449Sgabeblack@google.com#include "base/logging.hh"
4710612SMarco.Elver@ARM.com#include "base/output.hh"
4810612SMarco.Elver@ARM.com#include "base/trace.hh"
4910612SMarco.Elver@ARM.com#include "debug/MemCheckerMonitor.hh"
5010612SMarco.Elver@ARM.com
5110612SMarco.Elver@ARM.comMemCheckerMonitor::MemCheckerMonitor(Params* params)
5213892Sgabeblack@google.com    : SimObject(params),
5310612SMarco.Elver@ARM.com      masterPort(name() + "-master", *this),
5410612SMarco.Elver@ARM.com      slavePort(name() + "-slave", *this),
5510612SMarco.Elver@ARM.com      warnOnly(params->warn_only),
5610612SMarco.Elver@ARM.com      memchecker(params->memchecker)
5710612SMarco.Elver@ARM.com{}
5810612SMarco.Elver@ARM.com
5910612SMarco.Elver@ARM.comMemCheckerMonitor::~MemCheckerMonitor()
6010612SMarco.Elver@ARM.com{}
6110612SMarco.Elver@ARM.com
6210612SMarco.Elver@ARM.comMemCheckerMonitor*
6310612SMarco.Elver@ARM.comMemCheckerMonitorParams::create()
6410612SMarco.Elver@ARM.com{
6510612SMarco.Elver@ARM.com    return new MemCheckerMonitor(this);
6610612SMarco.Elver@ARM.com}
6710612SMarco.Elver@ARM.com
6810612SMarco.Elver@ARM.comvoid
6910612SMarco.Elver@ARM.comMemCheckerMonitor::init()
7010612SMarco.Elver@ARM.com{
7110612SMarco.Elver@ARM.com    // make sure both sides of the monitor are connected
7210612SMarco.Elver@ARM.com    if (!slavePort.isConnected() || !masterPort.isConnected())
7310612SMarco.Elver@ARM.com        fatal("Communication monitor is not connected on both sides.\n");
7410612SMarco.Elver@ARM.com}
7510612SMarco.Elver@ARM.com
7613784Sgabeblack@google.comPort &
7713784Sgabeblack@google.comMemCheckerMonitor::getPort(const std::string &if_name, PortID idx)
7810612SMarco.Elver@ARM.com{
7910612SMarco.Elver@ARM.com    if (if_name == "master" || if_name == "mem_side") {
8010612SMarco.Elver@ARM.com        return masterPort;
8113784Sgabeblack@google.com    } else if (if_name == "slave" || if_name == "cpu_side") {
8210612SMarco.Elver@ARM.com        return slavePort;
8310612SMarco.Elver@ARM.com    } else {
8413892Sgabeblack@google.com        return SimObject::getPort(if_name, idx);
8510612SMarco.Elver@ARM.com    }
8610612SMarco.Elver@ARM.com}
8710612SMarco.Elver@ARM.com
8810612SMarco.Elver@ARM.comvoid
8910612SMarco.Elver@ARM.comMemCheckerMonitor::recvFunctional(PacketPtr pkt)
9010612SMarco.Elver@ARM.com{
9110612SMarco.Elver@ARM.com    Addr addr = pkt->getAddr();
9210612SMarco.Elver@ARM.com    unsigned size = pkt->getSize();
9310612SMarco.Elver@ARM.com
9410612SMarco.Elver@ARM.com    // Conservatively reset this address-range. Alternatively we could try to
9510612SMarco.Elver@ARM.com    // update the values seen by the memchecker, however, there may be other
9610612SMarco.Elver@ARM.com    // reads/writes to these location from other devices we do not see.
9710612SMarco.Elver@ARM.com    memchecker->reset(addr, size);
9810612SMarco.Elver@ARM.com
9910612SMarco.Elver@ARM.com    masterPort.sendFunctional(pkt);
10010612SMarco.Elver@ARM.com
10110612SMarco.Elver@ARM.com    DPRINTF(MemCheckerMonitor,
10210612SMarco.Elver@ARM.com            "Forwarded functional access: addr = %#llx, size = %d\n",
10310612SMarco.Elver@ARM.com            addr, size);
10410612SMarco.Elver@ARM.com}
10510612SMarco.Elver@ARM.com
10610612SMarco.Elver@ARM.comvoid
10710612SMarco.Elver@ARM.comMemCheckerMonitor::recvFunctionalSnoop(PacketPtr pkt)
10810612SMarco.Elver@ARM.com{
10910612SMarco.Elver@ARM.com    Addr addr = pkt->getAddr();
11010612SMarco.Elver@ARM.com    unsigned size = pkt->getSize();
11110612SMarco.Elver@ARM.com
11210612SMarco.Elver@ARM.com    // See above.
11310612SMarco.Elver@ARM.com    memchecker->reset(addr, size);
11410612SMarco.Elver@ARM.com
11510612SMarco.Elver@ARM.com    slavePort.sendFunctionalSnoop(pkt);
11610612SMarco.Elver@ARM.com
11710612SMarco.Elver@ARM.com    DPRINTF(MemCheckerMonitor,
11810612SMarco.Elver@ARM.com            "Received functional snoop: addr = %#llx, size = %d\n",
11910612SMarco.Elver@ARM.com            addr, size);
12010612SMarco.Elver@ARM.com}
12110612SMarco.Elver@ARM.com
12210612SMarco.Elver@ARM.comTick
12310612SMarco.Elver@ARM.comMemCheckerMonitor::recvAtomic(PacketPtr pkt)
12410612SMarco.Elver@ARM.com{
12513449Sgabeblack@google.com    panic("Atomic not supported");
12610612SMarco.Elver@ARM.com}
12710612SMarco.Elver@ARM.com
12810612SMarco.Elver@ARM.comTick
12910612SMarco.Elver@ARM.comMemCheckerMonitor::recvAtomicSnoop(PacketPtr pkt)
13010612SMarco.Elver@ARM.com{
13113449Sgabeblack@google.com    panic("Atomic not supported");
13210612SMarco.Elver@ARM.com}
13310612SMarco.Elver@ARM.com
13410612SMarco.Elver@ARM.combool
13510612SMarco.Elver@ARM.comMemCheckerMonitor::recvTimingReq(PacketPtr pkt)
13610612SMarco.Elver@ARM.com{
13710612SMarco.Elver@ARM.com    // should always see a request
13810612SMarco.Elver@ARM.com    assert(pkt->isRequest());
13910612SMarco.Elver@ARM.com
14010612SMarco.Elver@ARM.com    // Store relevant fields of packet, because packet may be modified
14110612SMarco.Elver@ARM.com    // or even deleted when sendTiming() is called.
14210612SMarco.Elver@ARM.com    //
14310612SMarco.Elver@ARM.com    // For reads we are only interested in real reads, and not prefetches, as
14410612SMarco.Elver@ARM.com    // it is not guaranteed that the prefetch returns any useful data.
14510612SMarco.Elver@ARM.com    bool is_read = pkt->isRead() && !pkt->req->isPrefetch();
14610612SMarco.Elver@ARM.com    bool is_write = pkt->isWrite();
14710612SMarco.Elver@ARM.com    unsigned size = pkt->getSize();
14810612SMarco.Elver@ARM.com    Addr addr = pkt->getAddr();
14911284Sandreas.hansson@arm.com    bool expects_response = pkt->needsResponse() && !pkt->cacheResponding();
15011489Sandreas.hansson@arm.com    std::unique_ptr<uint8_t[]> pkt_data;
15110612SMarco.Elver@ARM.com    MemCheckerMonitorSenderState* state = NULL;
15210612SMarco.Elver@ARM.com
15310612SMarco.Elver@ARM.com    if (expects_response && is_write) {
15410612SMarco.Elver@ARM.com        // On receipt of a request, only need to allocate pkt_data if this is a
15510612SMarco.Elver@ARM.com        // write. For reads, we have no data yet, so it doesn't make sense to
15610612SMarco.Elver@ARM.com        // allocate.
15710612SMarco.Elver@ARM.com        pkt_data.reset(new uint8_t[size]);
15813377Sodanrc@yahoo.com.br        pkt->writeData(pkt_data.get());
15910612SMarco.Elver@ARM.com    }
16010612SMarco.Elver@ARM.com
16110612SMarco.Elver@ARM.com    // If a cache miss is served by a cache, a monitor near the memory
16210612SMarco.Elver@ARM.com    // would see a request which needs a response, but this response
16311284Sandreas.hansson@arm.com    // would not come back from the memory. Therefore
16410612SMarco.Elver@ARM.com    // we additionally have to check the inhibit flag.
16510612SMarco.Elver@ARM.com    if (expects_response && (is_read || is_write)) {
16610612SMarco.Elver@ARM.com        state = new MemCheckerMonitorSenderState(0);
16710612SMarco.Elver@ARM.com        pkt->pushSenderState(state);
16810612SMarco.Elver@ARM.com    }
16910612SMarco.Elver@ARM.com
17011284Sandreas.hansson@arm.com    // Attempt to send the packet
17110612SMarco.Elver@ARM.com    bool successful = masterPort.sendTimingReq(pkt);
17210612SMarco.Elver@ARM.com
17310612SMarco.Elver@ARM.com    // If not successful, restore the sender state
17410612SMarco.Elver@ARM.com    if (!successful && expects_response && (is_read || is_write)) {
17510612SMarco.Elver@ARM.com        delete pkt->popSenderState();
17610612SMarco.Elver@ARM.com    }
17710612SMarco.Elver@ARM.com
17810612SMarco.Elver@ARM.com    if (successful && expects_response) {
17910612SMarco.Elver@ARM.com        if (is_read) {
18010612SMarco.Elver@ARM.com            MemChecker::Serial serial = memchecker->startRead(curTick(),
18110612SMarco.Elver@ARM.com                                                              addr,
18210612SMarco.Elver@ARM.com                                                              size);
18310612SMarco.Elver@ARM.com
18410612SMarco.Elver@ARM.com            // At the time where we push the sender-state, we do not yet know
18510612SMarco.Elver@ARM.com            // the serial the MemChecker class will assign to this request. We
18610612SMarco.Elver@ARM.com            // cannot call startRead at the time we push the sender-state, as
18710612SMarco.Elver@ARM.com            // the masterPort may not be successful in executing sendTimingReq,
18810612SMarco.Elver@ARM.com            // and in case of a failure, we must not modify the state of the
18910612SMarco.Elver@ARM.com            // MemChecker.
19010612SMarco.Elver@ARM.com            //
19110612SMarco.Elver@ARM.com            // Once we know that sendTimingReq was successful, we can set the
19210612SMarco.Elver@ARM.com            // serial of the newly constructed sender-state. This is legal, as
19310612SMarco.Elver@ARM.com            // we know that nobody else will touch nor is responsible for
19410612SMarco.Elver@ARM.com            // deletion of our sender-state.
19510612SMarco.Elver@ARM.com            state->serial = serial;
19610612SMarco.Elver@ARM.com
19710612SMarco.Elver@ARM.com            DPRINTF(MemCheckerMonitor,
19810612SMarco.Elver@ARM.com                    "Forwarded read request: serial = %d, addr = %#llx, "
19910612SMarco.Elver@ARM.com                    "size = %d\n",
20010612SMarco.Elver@ARM.com                    serial, addr, size);
20110612SMarco.Elver@ARM.com        } else if (is_write) {
20210612SMarco.Elver@ARM.com            MemChecker::Serial serial = memchecker->startWrite(curTick(),
20310612SMarco.Elver@ARM.com                                                               addr,
20410612SMarco.Elver@ARM.com                                                               size,
20510612SMarco.Elver@ARM.com                                                               pkt_data.get());
20610612SMarco.Elver@ARM.com
20710612SMarco.Elver@ARM.com            state->serial = serial;
20810612SMarco.Elver@ARM.com
20910612SMarco.Elver@ARM.com            DPRINTF(MemCheckerMonitor,
21010612SMarco.Elver@ARM.com                    "Forwarded write request: serial = %d, addr = %#llx, "
21110612SMarco.Elver@ARM.com                    "size = %d\n",
21210612SMarco.Elver@ARM.com                    serial, addr, size);
21310612SMarco.Elver@ARM.com        } else {
21410612SMarco.Elver@ARM.com            DPRINTF(MemCheckerMonitor,
21510612SMarco.Elver@ARM.com                    "Forwarded non read/write request: addr = %#llx\n", addr);
21610612SMarco.Elver@ARM.com        }
21710612SMarco.Elver@ARM.com    } else if (successful) {
21810612SMarco.Elver@ARM.com        DPRINTF(MemCheckerMonitor,
21911284Sandreas.hansson@arm.com                "Forwarded request marked for cache response: addr = %#llx\n",
22011284Sandreas.hansson@arm.com                addr);
22110612SMarco.Elver@ARM.com    }
22210612SMarco.Elver@ARM.com
22310612SMarco.Elver@ARM.com    return successful;
22410612SMarco.Elver@ARM.com}
22510612SMarco.Elver@ARM.com
22610612SMarco.Elver@ARM.combool
22710612SMarco.Elver@ARM.comMemCheckerMonitor::recvTimingResp(PacketPtr pkt)
22810612SMarco.Elver@ARM.com{
22910612SMarco.Elver@ARM.com    // should always see responses
23010612SMarco.Elver@ARM.com    assert(pkt->isResponse());
23110612SMarco.Elver@ARM.com
23210612SMarco.Elver@ARM.com    // Store relevant fields of packet, because packet may be modified
23310612SMarco.Elver@ARM.com    // or even deleted when sendTiming() is called.
23410612SMarco.Elver@ARM.com    bool is_read = pkt->isRead() && !pkt->req->isPrefetch();
23510612SMarco.Elver@ARM.com    bool is_write = pkt->isWrite();
23610612SMarco.Elver@ARM.com    bool is_failed_LLSC = pkt->isLLSC() && pkt->req->getExtraData() == 0;
23710612SMarco.Elver@ARM.com    unsigned size = pkt->getSize();
23810612SMarco.Elver@ARM.com    Addr addr = pkt->getAddr();
23911489Sandreas.hansson@arm.com    std::unique_ptr<uint8_t[]> pkt_data;
24010612SMarco.Elver@ARM.com    MemCheckerMonitorSenderState* received_state = NULL;
24110612SMarco.Elver@ARM.com
24210612SMarco.Elver@ARM.com    if (is_read) {
24310612SMarco.Elver@ARM.com        // On receipt of a response, only need to allocate pkt_data if this is
24410612SMarco.Elver@ARM.com        // a read. For writes, we have already given the MemChecker the data on
24510612SMarco.Elver@ARM.com        // the request, so it doesn't make sense to allocate on write.
24610612SMarco.Elver@ARM.com        pkt_data.reset(new uint8_t[size]);
24713377Sodanrc@yahoo.com.br        pkt->writeData(pkt_data.get());
24810612SMarco.Elver@ARM.com    }
24910612SMarco.Elver@ARM.com
25010612SMarco.Elver@ARM.com    if (is_read || is_write) {
25110612SMarco.Elver@ARM.com        received_state =
25210612SMarco.Elver@ARM.com            dynamic_cast<MemCheckerMonitorSenderState*>(pkt->senderState);
25310612SMarco.Elver@ARM.com
25410612SMarco.Elver@ARM.com        // Restore initial sender state
25510612SMarco.Elver@ARM.com        panic_if(received_state == NULL,
25610612SMarco.Elver@ARM.com                 "Monitor got a response without monitor sender state\n");
25710612SMarco.Elver@ARM.com
25810612SMarco.Elver@ARM.com        // Restore the state
25910612SMarco.Elver@ARM.com        pkt->senderState = received_state->predecessor;
26010612SMarco.Elver@ARM.com    }
26110612SMarco.Elver@ARM.com
26210612SMarco.Elver@ARM.com    // Attempt to send the packet
26310612SMarco.Elver@ARM.com    bool successful = slavePort.sendTimingResp(pkt);
26410612SMarco.Elver@ARM.com
26510612SMarco.Elver@ARM.com    // If packet successfully send, complete transaction in MemChecker
26610612SMarco.Elver@ARM.com    // instance, and delete sender state, otherwise restore state.
26710612SMarco.Elver@ARM.com    if (successful) {
26810612SMarco.Elver@ARM.com        if (is_read) {
26910612SMarco.Elver@ARM.com            DPRINTF(MemCheckerMonitor,
27010612SMarco.Elver@ARM.com                    "Received read response: serial = %d, addr = %#llx, "
27110612SMarco.Elver@ARM.com                    "size = %d\n",
27210612SMarco.Elver@ARM.com                    received_state->serial, addr, size);
27310612SMarco.Elver@ARM.com
27410612SMarco.Elver@ARM.com            bool result = memchecker->completeRead(received_state->serial,
27510612SMarco.Elver@ARM.com                                                   curTick(),
27610612SMarco.Elver@ARM.com                                                   addr,
27710612SMarco.Elver@ARM.com                                                   size,
27810612SMarco.Elver@ARM.com                                                   pkt_data.get());
27910612SMarco.Elver@ARM.com
28010612SMarco.Elver@ARM.com            if (!result) {
28110612SMarco.Elver@ARM.com                warn("%s: read of %#llx @ cycle %d failed:\n%s\n",
28210612SMarco.Elver@ARM.com                     name(),
28310612SMarco.Elver@ARM.com                     addr, curTick(),
28410612SMarco.Elver@ARM.com                     memchecker->getErrorMessage().c_str());
28510612SMarco.Elver@ARM.com
28610612SMarco.Elver@ARM.com                panic_if(!warnOnly, "MemChecker violation!");
28710612SMarco.Elver@ARM.com            }
28810612SMarco.Elver@ARM.com
28910612SMarco.Elver@ARM.com            delete received_state;
29010612SMarco.Elver@ARM.com        } else if (is_write) {
29110612SMarco.Elver@ARM.com            DPRINTF(MemCheckerMonitor,
29210612SMarco.Elver@ARM.com                    "Received write response: serial = %d, addr = %#llx, "
29310612SMarco.Elver@ARM.com                    "size = %d\n",
29410612SMarco.Elver@ARM.com                    received_state->serial, addr, size);
29510612SMarco.Elver@ARM.com
29610612SMarco.Elver@ARM.com            if (is_failed_LLSC) {
29710612SMarco.Elver@ARM.com                // The write was not successful, let MemChecker know.
29810612SMarco.Elver@ARM.com                memchecker->abortWrite(received_state->serial,
29910612SMarco.Elver@ARM.com                                       addr,
30010612SMarco.Elver@ARM.com                                       size);
30110612SMarco.Elver@ARM.com            } else {
30210612SMarco.Elver@ARM.com                memchecker->completeWrite(received_state->serial,
30310612SMarco.Elver@ARM.com                                          curTick(),
30410612SMarco.Elver@ARM.com                                          addr,
30510612SMarco.Elver@ARM.com                                          size);
30610612SMarco.Elver@ARM.com            }
30710612SMarco.Elver@ARM.com
30810612SMarco.Elver@ARM.com            delete received_state;
30910612SMarco.Elver@ARM.com        } else {
31010612SMarco.Elver@ARM.com            DPRINTF(MemCheckerMonitor,
31110612SMarco.Elver@ARM.com                    "Received non read/write response: addr = %#llx\n", addr);
31210612SMarco.Elver@ARM.com        }
31310612SMarco.Elver@ARM.com    } else if (is_read || is_write) {
31410612SMarco.Elver@ARM.com        // Don't delete anything and let the packet look like we
31510612SMarco.Elver@ARM.com        // did not touch it
31610612SMarco.Elver@ARM.com        pkt->senderState = received_state;
31710612SMarco.Elver@ARM.com    }
31810612SMarco.Elver@ARM.com
31910612SMarco.Elver@ARM.com    return successful;
32010612SMarco.Elver@ARM.com}
32110612SMarco.Elver@ARM.com
32210612SMarco.Elver@ARM.comvoid
32310612SMarco.Elver@ARM.comMemCheckerMonitor::recvTimingSnoopReq(PacketPtr pkt)
32410612SMarco.Elver@ARM.com{
32510612SMarco.Elver@ARM.com    slavePort.sendTimingSnoopReq(pkt);
32610612SMarco.Elver@ARM.com}
32710612SMarco.Elver@ARM.com
32810612SMarco.Elver@ARM.combool
32910612SMarco.Elver@ARM.comMemCheckerMonitor::recvTimingSnoopResp(PacketPtr pkt)
33010612SMarco.Elver@ARM.com{
33110612SMarco.Elver@ARM.com    return masterPort.sendTimingSnoopResp(pkt);
33210612SMarco.Elver@ARM.com}
33310612SMarco.Elver@ARM.com
33410612SMarco.Elver@ARM.combool
33510612SMarco.Elver@ARM.comMemCheckerMonitor::isSnooping() const
33610612SMarco.Elver@ARM.com{
33710612SMarco.Elver@ARM.com    // check if the connected master port is snooping
33810612SMarco.Elver@ARM.com    return slavePort.isSnooping();
33910612SMarco.Elver@ARM.com}
34010612SMarco.Elver@ARM.com
34110612SMarco.Elver@ARM.comAddrRangeList
34210612SMarco.Elver@ARM.comMemCheckerMonitor::getAddrRanges() const
34310612SMarco.Elver@ARM.com{
34410612SMarco.Elver@ARM.com    // get the address ranges of the connected slave port
34510612SMarco.Elver@ARM.com    return masterPort.getAddrRanges();
34610612SMarco.Elver@ARM.com}
34710612SMarco.Elver@ARM.com
34810612SMarco.Elver@ARM.comvoid
34910713Sandreas.hansson@arm.comMemCheckerMonitor::recvReqRetry()
35010612SMarco.Elver@ARM.com{
35110713Sandreas.hansson@arm.com    slavePort.sendRetryReq();
35210612SMarco.Elver@ARM.com}
35310612SMarco.Elver@ARM.com
35410612SMarco.Elver@ARM.comvoid
35510713Sandreas.hansson@arm.comMemCheckerMonitor::recvRespRetry()
35610612SMarco.Elver@ARM.com{
35710713Sandreas.hansson@arm.com    masterPort.sendRetryResp();
35810612SMarco.Elver@ARM.com}
35910612SMarco.Elver@ARM.com
36010612SMarco.Elver@ARM.comvoid
36110612SMarco.Elver@ARM.comMemCheckerMonitor::recvRangeChange()
36210612SMarco.Elver@ARM.com{
36310612SMarco.Elver@ARM.com    slavePort.sendRangeChange();
36410612SMarco.Elver@ARM.com}
365