bridge.cc revision 10713:eddb533708cb
111308Santhony.gutierrez@amd.com/*
211308Santhony.gutierrez@amd.com * Copyright (c) 2011-2013 ARM Limited
311308Santhony.gutierrez@amd.com * All rights reserved
411308Santhony.gutierrez@amd.com *
511308Santhony.gutierrez@amd.com * The license below extends only to copyright in the software and shall
611308Santhony.gutierrez@amd.com * not be construed as granting a license to any other intellectual
711308Santhony.gutierrez@amd.com * property including but not limited to intellectual property relating
811308Santhony.gutierrez@amd.com * to a hardware implementation of the functionality of the software
911308Santhony.gutierrez@amd.com * licensed hereunder.  You may use the software subject to the license
1011308Santhony.gutierrez@amd.com * terms below provided that you ensure that this notice is replicated
1111308Santhony.gutierrez@amd.com * unmodified and in its entirety in all distributions of the software,
1211308Santhony.gutierrez@amd.com * modified or unmodified, in source code or in binary form.
1311308Santhony.gutierrez@amd.com *
1411308Santhony.gutierrez@amd.com * Copyright (c) 2006 The Regents of The University of Michigan
1511308Santhony.gutierrez@amd.com * All rights reserved.
1611308Santhony.gutierrez@amd.com *
1711308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without
1811308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are
1911308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright
2011308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer;
2111308Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright
2211308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the
2311308Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution;
2411308Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its
2511308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from
2611308Santhony.gutierrez@amd.com * this software without specific prior written permission.
2711308Santhony.gutierrez@amd.com *
2811308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2911308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3011308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3111308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3211308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3311308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3411308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3511308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3611308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3711308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3811308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3911308Santhony.gutierrez@amd.com *
4011308Santhony.gutierrez@amd.com * Authors: Ali Saidi
4111308Santhony.gutierrez@amd.com *          Steve Reinhardt
4211308Santhony.gutierrez@amd.com *          Andreas Hansson
4311670Sandreas.hansson@arm.com */
4411670Sandreas.hansson@arm.com
4511308Santhony.gutierrez@amd.com/**
4611308Santhony.gutierrez@amd.com * @file
4711308Santhony.gutierrez@amd.com * Implementation of a memory-mapped bridge that connects a master
4811308Santhony.gutierrez@amd.com * and a slave through a request and response queue.
4911308Santhony.gutierrez@amd.com */
5011308Santhony.gutierrez@amd.com
5111308Santhony.gutierrez@amd.com#include "base/trace.hh"
5211308Santhony.gutierrez@amd.com#include "debug/Bridge.hh"
5311308Santhony.gutierrez@amd.com#include "mem/bridge.hh"
5411308Santhony.gutierrez@amd.com#include "params/Bridge.hh"
5511308Santhony.gutierrez@amd.com
5611308Santhony.gutierrez@amd.comBridge::BridgeSlavePort::BridgeSlavePort(const std::string& _name,
5711308Santhony.gutierrez@amd.com                                         Bridge& _bridge,
5811308Santhony.gutierrez@amd.com                                         BridgeMasterPort& _masterPort,
5911308Santhony.gutierrez@amd.com                                         Cycles _delay, int _resp_limit,
6011308Santhony.gutierrez@amd.com                                         std::vector<AddrRange> _ranges)
6111308Santhony.gutierrez@amd.com    : SlavePort(_name, &_bridge), bridge(_bridge), masterPort(_masterPort),
6211308Santhony.gutierrez@amd.com      delay(_delay), ranges(_ranges.begin(), _ranges.end()),
6311308Santhony.gutierrez@amd.com      outstandingResponses(0), retryReq(false),
6411308Santhony.gutierrez@amd.com      respQueueLimit(_resp_limit), sendEvent(*this)
6511308Santhony.gutierrez@amd.com{
6611308Santhony.gutierrez@amd.com}
6711308Santhony.gutierrez@amd.com
6811308Santhony.gutierrez@amd.comBridge::BridgeMasterPort::BridgeMasterPort(const std::string& _name,
6911308Santhony.gutierrez@amd.com                                           Bridge& _bridge,
7011308Santhony.gutierrez@amd.com                                           BridgeSlavePort& _slavePort,
7111308Santhony.gutierrez@amd.com                                           Cycles _delay, int _req_limit)
7211308Santhony.gutierrez@amd.com    : MasterPort(_name, &_bridge), bridge(_bridge), slavePort(_slavePort),
7311308Santhony.gutierrez@amd.com      delay(_delay), reqQueueLimit(_req_limit), sendEvent(*this)
7411308Santhony.gutierrez@amd.com{
7511308Santhony.gutierrez@amd.com}
7611308Santhony.gutierrez@amd.com
7711308Santhony.gutierrez@amd.comBridge::Bridge(Params *p)
7811308Santhony.gutierrez@amd.com    : MemObject(p),
7911308Santhony.gutierrez@amd.com      slavePort(p->name + ".slave", *this, masterPort,
8011308Santhony.gutierrez@amd.com                ticksToCycles(p->delay), p->resp_size, p->ranges),
8111308Santhony.gutierrez@amd.com      masterPort(p->name + ".master", *this, slavePort,
8211308Santhony.gutierrez@amd.com                 ticksToCycles(p->delay), p->req_size)
8311308Santhony.gutierrez@amd.com{
8411308Santhony.gutierrez@amd.com}
8511308Santhony.gutierrez@amd.com
8611308Santhony.gutierrez@amd.comBaseMasterPort&
8711308Santhony.gutierrez@amd.comBridge::getMasterPort(const std::string &if_name, PortID idx)
8811308Santhony.gutierrez@amd.com{
8911308Santhony.gutierrez@amd.com    if (if_name == "master")
9011308Santhony.gutierrez@amd.com        return masterPort;
9111308Santhony.gutierrez@amd.com    else
9211308Santhony.gutierrez@amd.com        // pass it along to our super class
9311308Santhony.gutierrez@amd.com        return MemObject::getMasterPort(if_name, idx);
9411308Santhony.gutierrez@amd.com}
9511308Santhony.gutierrez@amd.com
9611308Santhony.gutierrez@amd.comBaseSlavePort&
9711308Santhony.gutierrez@amd.comBridge::getSlavePort(const std::string &if_name, PortID idx)
9811308Santhony.gutierrez@amd.com{
9911308Santhony.gutierrez@amd.com    if (if_name == "slave")
10011308Santhony.gutierrez@amd.com        return slavePort;
10111308Santhony.gutierrez@amd.com    else
10211308Santhony.gutierrez@amd.com        // pass it along to our super class
10311308Santhony.gutierrez@amd.com        return MemObject::getSlavePort(if_name, idx);
10411308Santhony.gutierrez@amd.com}
10511308Santhony.gutierrez@amd.com
10611308Santhony.gutierrez@amd.comvoid
10711308Santhony.gutierrez@amd.comBridge::init()
10811308Santhony.gutierrez@amd.com{
10911308Santhony.gutierrez@amd.com    // make sure both sides are connected and have the same block size
11011308Santhony.gutierrez@amd.com    if (!slavePort.isConnected() || !masterPort.isConnected())
11111308Santhony.gutierrez@amd.com        fatal("Both ports of a bridge must be connected.\n");
11211308Santhony.gutierrez@amd.com
11311308Santhony.gutierrez@amd.com    // notify the master side  of our address ranges
11411308Santhony.gutierrez@amd.com    slavePort.sendRangeChange();
11511308Santhony.gutierrez@amd.com}
11611308Santhony.gutierrez@amd.com
11711308Santhony.gutierrez@amd.combool
11811308Santhony.gutierrez@amd.comBridge::BridgeSlavePort::respQueueFull() const
11911308Santhony.gutierrez@amd.com{
12011308Santhony.gutierrez@amd.com    return outstandingResponses == respQueueLimit;
12111308Santhony.gutierrez@amd.com}
12211308Santhony.gutierrez@amd.com
12311308Santhony.gutierrez@amd.combool
12411308Santhony.gutierrez@amd.comBridge::BridgeMasterPort::reqQueueFull() const
12511308Santhony.gutierrez@amd.com{
12611308Santhony.gutierrez@amd.com    return transmitList.size() == reqQueueLimit;
12711308Santhony.gutierrez@amd.com}
12811308Santhony.gutierrez@amd.com
12911308Santhony.gutierrez@amd.combool
13011308Santhony.gutierrez@amd.comBridge::BridgeMasterPort::recvTimingResp(PacketPtr pkt)
13111308Santhony.gutierrez@amd.com{
13211308Santhony.gutierrez@amd.com    // all checks are done when the request is accepted on the slave
13311308Santhony.gutierrez@amd.com    // side, so we are guaranteed to have space for the response
13411308Santhony.gutierrez@amd.com    DPRINTF(Bridge, "recvTimingResp: %s addr 0x%x\n",
13511308Santhony.gutierrez@amd.com            pkt->cmdString(), pkt->getAddr());
13611308Santhony.gutierrez@amd.com
13711308Santhony.gutierrez@amd.com    DPRINTF(Bridge, "Request queue size: %d\n", transmitList.size());
13811308Santhony.gutierrez@amd.com
13911308Santhony.gutierrez@amd.com    // @todo: We need to pay for this and not just zero it out
14011308Santhony.gutierrez@amd.com    pkt->headerDelay = pkt->payloadDelay = 0;
14111308Santhony.gutierrez@amd.com
14211308Santhony.gutierrez@amd.com    slavePort.schedTimingResp(pkt, bridge.clockEdge(delay));
14311308Santhony.gutierrez@amd.com
14411308Santhony.gutierrez@amd.com    return true;
14511308Santhony.gutierrez@amd.com}
14611308Santhony.gutierrez@amd.com
14711308Santhony.gutierrez@amd.combool
14811308Santhony.gutierrez@amd.comBridge::BridgeSlavePort::recvTimingReq(PacketPtr pkt)
14911308Santhony.gutierrez@amd.com{
15011308Santhony.gutierrez@amd.com    DPRINTF(Bridge, "recvTimingReq: %s addr 0x%x\n",
15111308Santhony.gutierrez@amd.com            pkt->cmdString(), pkt->getAddr());
15211308Santhony.gutierrez@amd.com
15311308Santhony.gutierrez@amd.com    // we should not see a timing request if we are already in a retry
15411308Santhony.gutierrez@amd.com    assert(!retryReq);
15511308Santhony.gutierrez@amd.com
15611308Santhony.gutierrez@amd.com    DPRINTF(Bridge, "Response queue size: %d outresp: %d\n",
15711308Santhony.gutierrez@amd.com            transmitList.size(), outstandingResponses);
15811308Santhony.gutierrez@amd.com
15911308Santhony.gutierrez@amd.com    // if the request queue is full then there is no hope
16011308Santhony.gutierrez@amd.com    if (masterPort.reqQueueFull()) {
16111308Santhony.gutierrez@amd.com        DPRINTF(Bridge, "Request queue full\n");
16211308Santhony.gutierrez@amd.com        retryReq = true;
16311308Santhony.gutierrez@amd.com    } else {
16411308Santhony.gutierrez@amd.com        // look at the response queue if we expect to see a response
16511308Santhony.gutierrez@amd.com        bool expects_response = pkt->needsResponse() &&
16611308Santhony.gutierrez@amd.com            !pkt->memInhibitAsserted();
16711308Santhony.gutierrez@amd.com        if (expects_response) {
16811308Santhony.gutierrez@amd.com            if (respQueueFull()) {
16911308Santhony.gutierrez@amd.com                DPRINTF(Bridge, "Response queue full\n");
17011308Santhony.gutierrez@amd.com                retryReq = true;
17111308Santhony.gutierrez@amd.com            } else {
17211308Santhony.gutierrez@amd.com                // ok to send the request with space for the response
17311308Santhony.gutierrez@amd.com                DPRINTF(Bridge, "Reserving space for response\n");
17411308Santhony.gutierrez@amd.com                assert(outstandingResponses != respQueueLimit);
17511308Santhony.gutierrez@amd.com                ++outstandingResponses;
17611308Santhony.gutierrez@amd.com
17711308Santhony.gutierrez@amd.com                // no need to set retryReq to false as this is already the
17811308Santhony.gutierrez@amd.com                // case
17911308Santhony.gutierrez@amd.com            }
18011308Santhony.gutierrez@amd.com        }
18111308Santhony.gutierrez@amd.com
18211308Santhony.gutierrez@amd.com        if (!retryReq) {
18311308Santhony.gutierrez@amd.com            // @todo: We need to pay for this and not just zero it out
18411308Santhony.gutierrez@amd.com            pkt->headerDelay = pkt->payloadDelay = 0;
18511308Santhony.gutierrez@amd.com
18611308Santhony.gutierrez@amd.com            masterPort.schedTimingReq(pkt, bridge.clockEdge(delay));
18711308Santhony.gutierrez@amd.com        }
18811308Santhony.gutierrez@amd.com    }
18911308Santhony.gutierrez@amd.com
19011308Santhony.gutierrez@amd.com    // remember that we are now stalling a packet and that we have to
19111308Santhony.gutierrez@amd.com    // tell the sending master to retry once space becomes available,
19211308Santhony.gutierrez@amd.com    // we make no distinction whether the stalling is due to the
19311308Santhony.gutierrez@amd.com    // request queue or response queue being full
19411308Santhony.gutierrez@amd.com    return !retryReq;
19511308Santhony.gutierrez@amd.com}
19611308Santhony.gutierrez@amd.com
19711308Santhony.gutierrez@amd.comvoid
19811308Santhony.gutierrez@amd.comBridge::BridgeSlavePort::retryStalledReq()
19911308Santhony.gutierrez@amd.com{
20011308Santhony.gutierrez@amd.com    if (retryReq) {
20111308Santhony.gutierrez@amd.com        DPRINTF(Bridge, "Request waiting for retry, now retrying\n");
20211308Santhony.gutierrez@amd.com        retryReq = false;
20311308Santhony.gutierrez@amd.com        sendRetryReq();
20411308Santhony.gutierrez@amd.com    }
20511308Santhony.gutierrez@amd.com}
20611308Santhony.gutierrez@amd.com
20711308Santhony.gutierrez@amd.comvoid
20811308Santhony.gutierrez@amd.comBridge::BridgeMasterPort::schedTimingReq(PacketPtr pkt, Tick when)
20911308Santhony.gutierrez@amd.com{
21011308Santhony.gutierrez@amd.com    // If we're about to put this packet at the head of the queue, we
21111308Santhony.gutierrez@amd.com    // need to schedule an event to do the transmit.  Otherwise there
21211308Santhony.gutierrez@amd.com    // should already be an event scheduled for sending the head
21311308Santhony.gutierrez@amd.com    // packet.
21411308Santhony.gutierrez@amd.com    if (transmitList.empty()) {
21511308Santhony.gutierrez@amd.com        bridge.schedule(sendEvent, when);
21611308Santhony.gutierrez@amd.com    }
21711308Santhony.gutierrez@amd.com
21811308Santhony.gutierrez@amd.com    assert(transmitList.size() != reqQueueLimit);
21911308Santhony.gutierrez@amd.com
22011308Santhony.gutierrez@amd.com    transmitList.push_back(DeferredPacket(pkt, when));
22111308Santhony.gutierrez@amd.com}
22211308Santhony.gutierrez@amd.com
22311308Santhony.gutierrez@amd.com
22411308Santhony.gutierrez@amd.comvoid
22511308Santhony.gutierrez@amd.comBridge::BridgeSlavePort::schedTimingResp(PacketPtr pkt, Tick when)
22611308Santhony.gutierrez@amd.com{
22711308Santhony.gutierrez@amd.com    // If we're about to put this packet at the head of the queue, we
22811308Santhony.gutierrez@amd.com    // need to schedule an event to do the transmit.  Otherwise there
22911308Santhony.gutierrez@amd.com    // should already be an event scheduled for sending the head
23011308Santhony.gutierrez@amd.com    // packet.
23111308Santhony.gutierrez@amd.com    if (transmitList.empty()) {
23211308Santhony.gutierrez@amd.com        bridge.schedule(sendEvent, when);
23311308Santhony.gutierrez@amd.com    }
23411308Santhony.gutierrez@amd.com
23511308Santhony.gutierrez@amd.com    transmitList.push_back(DeferredPacket(pkt, when));
23611308Santhony.gutierrez@amd.com}
23711308Santhony.gutierrez@amd.com
23811308Santhony.gutierrez@amd.comvoid
23911308Santhony.gutierrez@amd.comBridge::BridgeMasterPort::trySendTiming()
24011308Santhony.gutierrez@amd.com{
24111308Santhony.gutierrez@amd.com    assert(!transmitList.empty());
24211308Santhony.gutierrez@amd.com
24311308Santhony.gutierrez@amd.com    DeferredPacket req = transmitList.front();
24411308Santhony.gutierrez@amd.com
24511308Santhony.gutierrez@amd.com    assert(req.tick <= curTick());
24611308Santhony.gutierrez@amd.com
24711308Santhony.gutierrez@amd.com    PacketPtr pkt = req.pkt;
24811308Santhony.gutierrez@amd.com
24911308Santhony.gutierrez@amd.com    DPRINTF(Bridge, "trySend request addr 0x%x, queue size %d\n",
25011308Santhony.gutierrez@amd.com            pkt->getAddr(), transmitList.size());
25111308Santhony.gutierrez@amd.com
25211308Santhony.gutierrez@amd.com    if (sendTimingReq(pkt)) {
25311308Santhony.gutierrez@amd.com        // send successful
25411308Santhony.gutierrez@amd.com        transmitList.pop_front();
25511308Santhony.gutierrez@amd.com        DPRINTF(Bridge, "trySend request successful\n");
25611308Santhony.gutierrez@amd.com
25711308Santhony.gutierrez@amd.com        // If there are more packets to send, schedule event to try again.
25811308Santhony.gutierrez@amd.com        if (!transmitList.empty()) {
25911308Santhony.gutierrez@amd.com            DeferredPacket next_req = transmitList.front();
26011308Santhony.gutierrez@amd.com            DPRINTF(Bridge, "Scheduling next send\n");
26111308Santhony.gutierrez@amd.com            bridge.schedule(sendEvent, std::max(next_req.tick,
26211308Santhony.gutierrez@amd.com                                                bridge.clockEdge()));
26311308Santhony.gutierrez@amd.com        }
26411308Santhony.gutierrez@amd.com
26511308Santhony.gutierrez@amd.com        // if we have stalled a request due to a full request queue,
26611308Santhony.gutierrez@amd.com        // then send a retry at this point, also note that if the
26711308Santhony.gutierrez@amd.com        // request we stalled was waiting for the response queue
26811308Santhony.gutierrez@amd.com        // rather than the request queue we might stall it again
26911308Santhony.gutierrez@amd.com        slavePort.retryStalledReq();
27011308Santhony.gutierrez@amd.com    }
27111308Santhony.gutierrez@amd.com
27211308Santhony.gutierrez@amd.com    // if the send failed, then we try again once we receive a retry,
27311308Santhony.gutierrez@amd.com    // and therefore there is no need to take any action
27411308Santhony.gutierrez@amd.com}
27511308Santhony.gutierrez@amd.com
27611308Santhony.gutierrez@amd.comvoid
27711308Santhony.gutierrez@amd.comBridge::BridgeSlavePort::trySendTiming()
27811308Santhony.gutierrez@amd.com{
27911308Santhony.gutierrez@amd.com    assert(!transmitList.empty());
28011308Santhony.gutierrez@amd.com
28111308Santhony.gutierrez@amd.com    DeferredPacket resp = transmitList.front();
28211308Santhony.gutierrez@amd.com
28311308Santhony.gutierrez@amd.com    assert(resp.tick <= curTick());
28411308Santhony.gutierrez@amd.com
28511308Santhony.gutierrez@amd.com    PacketPtr pkt = resp.pkt;
28611308Santhony.gutierrez@amd.com
28711308Santhony.gutierrez@amd.com    DPRINTF(Bridge, "trySend response addr 0x%x, outstanding %d\n",
28811308Santhony.gutierrez@amd.com            pkt->getAddr(), outstandingResponses);
28911308Santhony.gutierrez@amd.com
29011308Santhony.gutierrez@amd.com    if (sendTimingResp(pkt)) {
29111308Santhony.gutierrez@amd.com        // send successful
29211308Santhony.gutierrez@amd.com        transmitList.pop_front();
29311308Santhony.gutierrez@amd.com        DPRINTF(Bridge, "trySend response successful\n");
29411308Santhony.gutierrez@amd.com
29511308Santhony.gutierrez@amd.com        assert(outstandingResponses != 0);
29611308Santhony.gutierrez@amd.com        --outstandingResponses;
29711308Santhony.gutierrez@amd.com
29811308Santhony.gutierrez@amd.com        // If there are more packets to send, schedule event to try again.
29911308Santhony.gutierrez@amd.com        if (!transmitList.empty()) {
30011308Santhony.gutierrez@amd.com            DeferredPacket next_resp = transmitList.front();
30111308Santhony.gutierrez@amd.com            DPRINTF(Bridge, "Scheduling next send\n");
30211308Santhony.gutierrez@amd.com            bridge.schedule(sendEvent, std::max(next_resp.tick,
30311308Santhony.gutierrez@amd.com                                                bridge.clockEdge()));
30411308Santhony.gutierrez@amd.com        }
30511308Santhony.gutierrez@amd.com
30611308Santhony.gutierrez@amd.com        // if there is space in the request queue and we were stalling
30711308Santhony.gutierrez@amd.com        // a request, it will definitely be possible to accept it now
30811308Santhony.gutierrez@amd.com        // since there is guaranteed space in the response queue
30911308Santhony.gutierrez@amd.com        if (!masterPort.reqQueueFull() && retryReq) {
31011308Santhony.gutierrez@amd.com            DPRINTF(Bridge, "Request waiting for retry, now retrying\n");
31111308Santhony.gutierrez@amd.com            retryReq = false;
31211308Santhony.gutierrez@amd.com            sendRetryReq();
31311308Santhony.gutierrez@amd.com        }
31411308Santhony.gutierrez@amd.com    }
31511308Santhony.gutierrez@amd.com
31611308Santhony.gutierrez@amd.com    // if the send failed, then we try again once we receive a retry,
31711308Santhony.gutierrez@amd.com    // and therefore there is no need to take any action
31811308Santhony.gutierrez@amd.com}
31911308Santhony.gutierrez@amd.com
32011308Santhony.gutierrez@amd.comvoid
32111308Santhony.gutierrez@amd.comBridge::BridgeMasterPort::recvReqRetry()
32211308Santhony.gutierrez@amd.com{
32311308Santhony.gutierrez@amd.com    trySendTiming();
32411308Santhony.gutierrez@amd.com}
32511308Santhony.gutierrez@amd.com
32611308Santhony.gutierrez@amd.comvoid
32711308Santhony.gutierrez@amd.comBridge::BridgeSlavePort::recvRespRetry()
32811308Santhony.gutierrez@amd.com{
32911308Santhony.gutierrez@amd.com    trySendTiming();
33011308Santhony.gutierrez@amd.com}
33111308Santhony.gutierrez@amd.com
33211308Santhony.gutierrez@amd.comTick
33311308Santhony.gutierrez@amd.comBridge::BridgeSlavePort::recvAtomic(PacketPtr pkt)
33411308Santhony.gutierrez@amd.com{
33511308Santhony.gutierrez@amd.com    return delay * bridge.clockPeriod() + masterPort.sendAtomic(pkt);
33611308Santhony.gutierrez@amd.com}
33711308Santhony.gutierrez@amd.com
33811308Santhony.gutierrez@amd.comvoid
33911308Santhony.gutierrez@amd.comBridge::BridgeSlavePort::recvFunctional(PacketPtr pkt)
34011308Santhony.gutierrez@amd.com{
34111308Santhony.gutierrez@amd.com    pkt->pushLabel(name());
34211308Santhony.gutierrez@amd.com
34311308Santhony.gutierrez@amd.com    // check the response queue
34411308Santhony.gutierrez@amd.com    for (auto i = transmitList.begin();  i != transmitList.end(); ++i) {
34511308Santhony.gutierrez@amd.com        if (pkt->checkFunctional((*i).pkt)) {
34611308Santhony.gutierrez@amd.com            pkt->makeResponse();
34711308Santhony.gutierrez@amd.com            return;
34811308Santhony.gutierrez@amd.com        }
34911308Santhony.gutierrez@amd.com    }
35011308Santhony.gutierrez@amd.com
35111308Santhony.gutierrez@amd.com    // also check the master port's request queue
35211308Santhony.gutierrez@amd.com    if (masterPort.checkFunctional(pkt)) {
35311308Santhony.gutierrez@amd.com        return;
35411308Santhony.gutierrez@amd.com    }
35511308Santhony.gutierrez@amd.com
35611308Santhony.gutierrez@amd.com    pkt->popLabel();
35711308Santhony.gutierrez@amd.com
35811308Santhony.gutierrez@amd.com    // fall through if pkt still not satisfied
35911308Santhony.gutierrez@amd.com    masterPort.sendFunctional(pkt);
36011308Santhony.gutierrez@amd.com}
36111308Santhony.gutierrez@amd.com
36211308Santhony.gutierrez@amd.combool
36311308Santhony.gutierrez@amd.comBridge::BridgeMasterPort::checkFunctional(PacketPtr pkt)
36411308Santhony.gutierrez@amd.com{
36511308Santhony.gutierrez@amd.com    bool found = false;
36611308Santhony.gutierrez@amd.com    auto i = transmitList.begin();
36711308Santhony.gutierrez@amd.com
36811308Santhony.gutierrez@amd.com    while(i != transmitList.end() && !found) {
36911308Santhony.gutierrez@amd.com        if (pkt->checkFunctional((*i).pkt)) {
37011308Santhony.gutierrez@amd.com            pkt->makeResponse();
37111308Santhony.gutierrez@amd.com            found = true;
37211308Santhony.gutierrez@amd.com        }
37311308Santhony.gutierrez@amd.com        ++i;
37411308Santhony.gutierrez@amd.com    }
37511308Santhony.gutierrez@amd.com
37611308Santhony.gutierrez@amd.com    return found;
37711308Santhony.gutierrez@amd.com}
37811308Santhony.gutierrez@amd.com
37911308Santhony.gutierrez@amd.comAddrRangeList
38011308Santhony.gutierrez@amd.comBridge::BridgeSlavePort::getAddrRanges() const
38111308Santhony.gutierrez@amd.com{
38211308Santhony.gutierrez@amd.com    return ranges;
38311308Santhony.gutierrez@amd.com}
38411308Santhony.gutierrez@amd.com
38511308Santhony.gutierrez@amd.comBridge *
38611308Santhony.gutierrez@amd.comBridgeParams::create()
38711308Santhony.gutierrez@amd.com{
38811308Santhony.gutierrez@amd.com    return new Bridge(this);
38911308Santhony.gutierrez@amd.com}
39011308Santhony.gutierrez@amd.com