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