bridge.cc revision 9090
12568SN/A/* 28922Swilliam.wang@arm.com * Copyright (c) 2011-2012 ARM Limited 38713Sandreas.hansson@arm.com * All rights reserved 48713Sandreas.hansson@arm.com * 58713Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 68713Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 78713Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 88713Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 98713Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 108713Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 118713Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 128713Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 138713Sandreas.hansson@arm.com * 142568SN/A * Copyright (c) 2006 The Regents of The University of Michigan 152568SN/A * All rights reserved. 162568SN/A * 172568SN/A * Redistribution and use in source and binary forms, with or without 182568SN/A * modification, are permitted provided that the following conditions are 192568SN/A * met: redistributions of source code must retain the above copyright 202568SN/A * notice, this list of conditions and the following disclaimer; 212568SN/A * redistributions in binary form must reproduce the above copyright 222568SN/A * notice, this list of conditions and the following disclaimer in the 232568SN/A * documentation and/or other materials provided with the distribution; 242568SN/A * neither the name of the copyright holders nor the names of its 252568SN/A * contributors may be used to endorse or promote products derived from 262568SN/A * this software without specific prior written permission. 272568SN/A * 282568SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292568SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302568SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312568SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322568SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332568SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342568SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352568SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362568SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372568SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382568SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392665Ssaidi@eecs.umich.edu * 402665Ssaidi@eecs.umich.edu * Authors: Ali Saidi 412665Ssaidi@eecs.umich.edu * Steve Reinhardt 428713Sandreas.hansson@arm.com * Andreas Hansson 432568SN/A */ 442568SN/A 452568SN/A/** 462982Sstever@eecs.umich.edu * @file 478713Sandreas.hansson@arm.com * Implementation of a memory-mapped bus bridge that connects a master 488713Sandreas.hansson@arm.com * and a slave through a request and response queue. 492568SN/A */ 502568SN/A 512568SN/A#include "base/trace.hh" 528232Snate@binkert.org#include "debug/BusBridge.hh" 532568SN/A#include "mem/bridge.hh" 544762Snate@binkert.org#include "params/Bridge.hh" 552568SN/A 568713Sandreas.hansson@arm.comBridge::BridgeSlavePort::BridgeSlavePort(const std::string &_name, 578713Sandreas.hansson@arm.com Bridge* _bridge, 588851Sandreas.hansson@arm.com BridgeMasterPort& _masterPort, 598713Sandreas.hansson@arm.com int _delay, int _nack_delay, 608713Sandreas.hansson@arm.com int _resp_limit, 618713Sandreas.hansson@arm.com std::vector<Range<Addr> > _ranges) 628922Swilliam.wang@arm.com : SlavePort(_name, _bridge), bridge(_bridge), masterPort(_masterPort), 638713Sandreas.hansson@arm.com delay(_delay), nackDelay(_nack_delay), 648713Sandreas.hansson@arm.com ranges(_ranges.begin(), _ranges.end()), 658713Sandreas.hansson@arm.com outstandingResponses(0), inRetry(false), 668851Sandreas.hansson@arm.com respQueueLimit(_resp_limit), sendEvent(*this) 678713Sandreas.hansson@arm.com{ 688713Sandreas.hansson@arm.com} 698713Sandreas.hansson@arm.com 708713Sandreas.hansson@arm.comBridge::BridgeMasterPort::BridgeMasterPort(const std::string &_name, 718713Sandreas.hansson@arm.com Bridge* _bridge, 728851Sandreas.hansson@arm.com BridgeSlavePort& _slavePort, 738713Sandreas.hansson@arm.com int _delay, int _req_limit) 748922Swilliam.wang@arm.com : MasterPort(_name, _bridge), bridge(_bridge), slavePort(_slavePort), 758851Sandreas.hansson@arm.com delay(_delay), inRetry(false), reqQueueLimit(_req_limit), 768851Sandreas.hansson@arm.com sendEvent(*this) 772643Sstever@eecs.umich.edu{ 782643Sstever@eecs.umich.edu} 792643Sstever@eecs.umich.edu 804435Ssaidi@eecs.umich.eduBridge::Bridge(Params *p) 815034Smilesck@eecs.umich.edu : MemObject(p), 828851Sandreas.hansson@arm.com slavePort(p->name + "-slave", this, masterPort, p->delay, 838713Sandreas.hansson@arm.com p->nack_delay, p->resp_size, p->ranges), 848851Sandreas.hansson@arm.com masterPort(p->name + "-master", this, slavePort, p->delay, p->req_size), 854435Ssaidi@eecs.umich.edu ackWrites(p->write_ack), _params(p) 862643Sstever@eecs.umich.edu{ 874432Ssaidi@eecs.umich.edu if (ackWrites) 884432Ssaidi@eecs.umich.edu panic("No support for acknowledging writes\n"); 892643Sstever@eecs.umich.edu} 902643Sstever@eecs.umich.edu 918922Swilliam.wang@arm.comMasterPort& 928922Swilliam.wang@arm.comBridge::getMasterPort(const std::string &if_name, int idx) 938922Swilliam.wang@arm.com{ 948922Swilliam.wang@arm.com if (if_name == "master") 958922Swilliam.wang@arm.com return masterPort; 968922Swilliam.wang@arm.com else 978922Swilliam.wang@arm.com // pass it along to our super class 988922Swilliam.wang@arm.com return MemObject::getMasterPort(if_name, idx); 998922Swilliam.wang@arm.com} 1008922Swilliam.wang@arm.com 1018922Swilliam.wang@arm.comSlavePort& 1028922Swilliam.wang@arm.comBridge::getSlavePort(const std::string &if_name, int idx) 1032643Sstever@eecs.umich.edu{ 1048713Sandreas.hansson@arm.com if (if_name == "slave") 1058922Swilliam.wang@arm.com return slavePort; 1068922Swilliam.wang@arm.com else 1078922Swilliam.wang@arm.com // pass it along to our super class 1088922Swilliam.wang@arm.com return MemObject::getSlavePort(if_name, idx); 1092643Sstever@eecs.umich.edu} 1102643Sstever@eecs.umich.edu 1112568SN/Avoid 1122568SN/ABridge::init() 1132568SN/A{ 1148713Sandreas.hansson@arm.com // make sure both sides are connected and have the same block size 1158713Sandreas.hansson@arm.com if (!slavePort.isConnected() || !masterPort.isConnected()) 1164432Ssaidi@eecs.umich.edu fatal("Both ports of bus bridge are not connected to a bus.\n"); 1174432Ssaidi@eecs.umich.edu 1188713Sandreas.hansson@arm.com if (slavePort.peerBlockSize() != masterPort.peerBlockSize()) 1198713Sandreas.hansson@arm.com fatal("Slave port size %d, master port size %d \n " \ 1206764SBrad.Beckmann@amd.com "Busses don't have the same block size... Not supported.\n", 1218713Sandreas.hansson@arm.com slavePort.peerBlockSize(), masterPort.peerBlockSize()); 1228713Sandreas.hansson@arm.com 1238713Sandreas.hansson@arm.com // notify the master side of our address ranges 1248713Sandreas.hansson@arm.com slavePort.sendRangeChange(); 1252568SN/A} 1262568SN/A 1274433Ssaidi@eecs.umich.edubool 1288713Sandreas.hansson@arm.comBridge::BridgeSlavePort::respQueueFull() 1294433Ssaidi@eecs.umich.edu{ 1308713Sandreas.hansson@arm.com return outstandingResponses == respQueueLimit; 1314435Ssaidi@eecs.umich.edu} 1324435Ssaidi@eecs.umich.edu 1334435Ssaidi@eecs.umich.edubool 1348713Sandreas.hansson@arm.comBridge::BridgeMasterPort::reqQueueFull() 1354435Ssaidi@eecs.umich.edu{ 1368713Sandreas.hansson@arm.com return requestQueue.size() == reqQueueLimit; 1374433Ssaidi@eecs.umich.edu} 1382568SN/A 1392568SN/Abool 1408975Sandreas.hansson@arm.comBridge::BridgeMasterPort::recvTimingResp(PacketPtr pkt) 1412568SN/A{ 1428713Sandreas.hansson@arm.com // all checks are done when the request is accepted on the slave 1438713Sandreas.hansson@arm.com // side, so we are guaranteed to have space for the response 1448949Sandreas.hansson@arm.com DPRINTF(BusBridge, "recvTiming: response %s addr 0x%x\n", 1458949Sandreas.hansson@arm.com pkt->cmdString(), pkt->getAddr()); 1462643Sstever@eecs.umich.edu 1478713Sandreas.hansson@arm.com DPRINTF(BusBridge, "Request queue size: %d\n", requestQueue.size()); 1484450Ssaidi@eecs.umich.edu 1498851Sandreas.hansson@arm.com slavePort.queueForSendTiming(pkt); 1508713Sandreas.hansson@arm.com 1518713Sandreas.hansson@arm.com return true; 1528713Sandreas.hansson@arm.com} 1538713Sandreas.hansson@arm.com 1548713Sandreas.hansson@arm.combool 1558975Sandreas.hansson@arm.comBridge::BridgeSlavePort::recvTimingReq(PacketPtr pkt) 1568713Sandreas.hansson@arm.com{ 1578949Sandreas.hansson@arm.com DPRINTF(BusBridge, "recvTiming: request %s addr 0x%x\n", 1588949Sandreas.hansson@arm.com pkt->cmdString(), pkt->getAddr()); 1598713Sandreas.hansson@arm.com 1608713Sandreas.hansson@arm.com DPRINTF(BusBridge, "Response queue size: %d outresp: %d\n", 1618713Sandreas.hansson@arm.com responseQueue.size(), outstandingResponses); 1628713Sandreas.hansson@arm.com 1638851Sandreas.hansson@arm.com if (masterPort.reqQueueFull()) { 1648713Sandreas.hansson@arm.com DPRINTF(BusBridge, "Request queue full, nacking\n"); 1654433Ssaidi@eecs.umich.edu nackRequest(pkt); 1664433Ssaidi@eecs.umich.edu return true; 1673662Srdreslin@umich.edu } 1684433Ssaidi@eecs.umich.edu 1695562Snate@binkert.org if (pkt->needsResponse()) { 1704435Ssaidi@eecs.umich.edu if (respQueueFull()) { 1718713Sandreas.hansson@arm.com DPRINTF(BusBridge, 1728713Sandreas.hansson@arm.com "Response queue full, no space for response, nacking\n"); 1738713Sandreas.hansson@arm.com DPRINTF(BusBridge, 1748713Sandreas.hansson@arm.com "queue size: %d outstanding resp: %d\n", 1758713Sandreas.hansson@arm.com responseQueue.size(), outstandingResponses); 1764433Ssaidi@eecs.umich.edu nackRequest(pkt); 1774433Ssaidi@eecs.umich.edu return true; 1784433Ssaidi@eecs.umich.edu } else { 1794433Ssaidi@eecs.umich.edu DPRINTF(BusBridge, "Request Needs response, reserving space\n"); 1808713Sandreas.hansson@arm.com assert(outstandingResponses != respQueueLimit); 1814433Ssaidi@eecs.umich.edu ++outstandingResponses; 1824433Ssaidi@eecs.umich.edu } 1835562Snate@binkert.org } 1844433Ssaidi@eecs.umich.edu 1858851Sandreas.hansson@arm.com masterPort.queueForSendTiming(pkt); 1864433Ssaidi@eecs.umich.edu 1874433Ssaidi@eecs.umich.edu return true; 1882657Ssaidi@eecs.umich.edu} 1892657Ssaidi@eecs.umich.edu 1904433Ssaidi@eecs.umich.eduvoid 1918713Sandreas.hansson@arm.comBridge::BridgeSlavePort::nackRequest(PacketPtr pkt) 1924433Ssaidi@eecs.umich.edu{ 1934433Ssaidi@eecs.umich.edu // Nack the packet 1944986Ssaidi@eecs.umich.edu pkt->makeTimingResponse(); 1954870Sstever@eecs.umich.edu pkt->setNacked(); 1962657Ssaidi@eecs.umich.edu 1978713Sandreas.hansson@arm.com // The Nack packets are stored in the response queue just like any 1988713Sandreas.hansson@arm.com // other response, but they do not occupy any space as this is 1998713Sandreas.hansson@arm.com // tracked by the outstandingResponses, this guarantees space for 2008713Sandreas.hansson@arm.com // the Nack packets, but implicitly means we have an (unrealistic) 2018713Sandreas.hansson@arm.com // unbounded Nack queue. 2028713Sandreas.hansson@arm.com 2038713Sandreas.hansson@arm.com // put it on the list to send 2047823Ssteve.reinhardt@amd.com Tick readyTime = curTick() + nackDelay; 2059029Sandreas.hansson@arm.com DeferredResponse resp(pkt, readyTime, true); 2064435Ssaidi@eecs.umich.edu 2074435Ssaidi@eecs.umich.edu // nothing on the list, add it and we're done 2088713Sandreas.hansson@arm.com if (responseQueue.empty()) { 2094435Ssaidi@eecs.umich.edu assert(!sendEvent.scheduled()); 2108708Sandreas.hansson@arm.com bridge->schedule(sendEvent, readyTime); 2119029Sandreas.hansson@arm.com responseQueue.push_back(resp); 2124435Ssaidi@eecs.umich.edu return; 2134433Ssaidi@eecs.umich.edu } 2144435Ssaidi@eecs.umich.edu 2154435Ssaidi@eecs.umich.edu assert(sendEvent.scheduled() || inRetry); 2164435Ssaidi@eecs.umich.edu 2174435Ssaidi@eecs.umich.edu // does it go at the end? 2189029Sandreas.hansson@arm.com if (readyTime >= responseQueue.back().ready) { 2199029Sandreas.hansson@arm.com responseQueue.push_back(resp); 2204435Ssaidi@eecs.umich.edu return; 2214435Ssaidi@eecs.umich.edu } 2224435Ssaidi@eecs.umich.edu 2234435Ssaidi@eecs.umich.edu // ok, somewhere in the middle, fun 2249029Sandreas.hansson@arm.com std::list<DeferredResponse>::iterator i = responseQueue.begin(); 2259029Sandreas.hansson@arm.com std::list<DeferredResponse>::iterator end = responseQueue.end(); 2269029Sandreas.hansson@arm.com std::list<DeferredResponse>::iterator begin = responseQueue.begin(); 2274435Ssaidi@eecs.umich.edu bool done = false; 2284435Ssaidi@eecs.umich.edu 2294435Ssaidi@eecs.umich.edu while (i != end && !done) { 2309029Sandreas.hansson@arm.com if (readyTime < (*i).ready) { 2314435Ssaidi@eecs.umich.edu if (i == begin) 2328708Sandreas.hansson@arm.com bridge->reschedule(sendEvent, readyTime); 2339029Sandreas.hansson@arm.com responseQueue.insert(i, resp); 2344435Ssaidi@eecs.umich.edu done = true; 2354435Ssaidi@eecs.umich.edu } 2364435Ssaidi@eecs.umich.edu i++; 2374435Ssaidi@eecs.umich.edu } 2384435Ssaidi@eecs.umich.edu assert(done); 2394433Ssaidi@eecs.umich.edu} 2404433Ssaidi@eecs.umich.edu 2414433Ssaidi@eecs.umich.eduvoid 2428713Sandreas.hansson@arm.comBridge::BridgeMasterPort::queueForSendTiming(PacketPtr pkt) 2432657Ssaidi@eecs.umich.edu{ 2447823Ssteve.reinhardt@amd.com Tick readyTime = curTick() + delay; 2459029Sandreas.hansson@arm.com 2469029Sandreas.hansson@arm.com // If we expect to see a response, we need to restore the source 2479029Sandreas.hansson@arm.com // and destination field that is potentially changed by a second 2489029Sandreas.hansson@arm.com // bus 2499029Sandreas.hansson@arm.com if (!pkt->memInhibitAsserted() && pkt->needsResponse()) { 2509029Sandreas.hansson@arm.com // Update the sender state so we can deal with the response 2519029Sandreas.hansson@arm.com // appropriately 2529029Sandreas.hansson@arm.com RequestState *req_state = new RequestState(pkt); 2539029Sandreas.hansson@arm.com pkt->senderState = req_state; 2549029Sandreas.hansson@arm.com } 2552643Sstever@eecs.umich.edu 2562643Sstever@eecs.umich.edu // If we're about to put this packet at the head of the queue, we 2572643Sstever@eecs.umich.edu // need to schedule an event to do the transmit. Otherwise there 2582643Sstever@eecs.umich.edu // should already be an event scheduled for sending the head 2592643Sstever@eecs.umich.edu // packet. 2608713Sandreas.hansson@arm.com if (requestQueue.empty()) { 2618708Sandreas.hansson@arm.com bridge->schedule(sendEvent, readyTime); 2622568SN/A } 2638713Sandreas.hansson@arm.com 2648713Sandreas.hansson@arm.com assert(requestQueue.size() != reqQueueLimit); 2658713Sandreas.hansson@arm.com 2669029Sandreas.hansson@arm.com requestQueue.push_back(DeferredRequest(pkt, readyTime)); 2678713Sandreas.hansson@arm.com} 2688713Sandreas.hansson@arm.com 2698713Sandreas.hansson@arm.com 2708713Sandreas.hansson@arm.comvoid 2718713Sandreas.hansson@arm.comBridge::BridgeSlavePort::queueForSendTiming(PacketPtr pkt) 2728713Sandreas.hansson@arm.com{ 2738713Sandreas.hansson@arm.com // This is a response for a request we forwarded earlier. The 2749029Sandreas.hansson@arm.com // corresponding request state should be stored in the packet's 2758713Sandreas.hansson@arm.com // senderState field. 2769029Sandreas.hansson@arm.com RequestState *req_state = dynamic_cast<RequestState*>(pkt->senderState); 2779029Sandreas.hansson@arm.com assert(req_state != NULL); 2788713Sandreas.hansson@arm.com // set up new packet dest & senderState based on values saved 2798713Sandreas.hansson@arm.com // from original request 2809029Sandreas.hansson@arm.com req_state->fixResponse(pkt); 2818713Sandreas.hansson@arm.com 2828949Sandreas.hansson@arm.com // the bridge assumes that at least one bus has set the 2838949Sandreas.hansson@arm.com // destination field of the packet 2848949Sandreas.hansson@arm.com assert(pkt->isDestValid()); 2858713Sandreas.hansson@arm.com DPRINTF(BusBridge, "response, new dest %d\n", pkt->getDest()); 2869029Sandreas.hansson@arm.com delete req_state; 2878713Sandreas.hansson@arm.com 2888713Sandreas.hansson@arm.com Tick readyTime = curTick() + delay; 2898713Sandreas.hansson@arm.com 2908713Sandreas.hansson@arm.com // If we're about to put this packet at the head of the queue, we 2918713Sandreas.hansson@arm.com // need to schedule an event to do the transmit. Otherwise there 2928713Sandreas.hansson@arm.com // should already be an event scheduled for sending the head 2938713Sandreas.hansson@arm.com // packet. 2948713Sandreas.hansson@arm.com if (responseQueue.empty()) { 2958713Sandreas.hansson@arm.com bridge->schedule(sendEvent, readyTime); 2968713Sandreas.hansson@arm.com } 2979029Sandreas.hansson@arm.com responseQueue.push_back(DeferredResponse(pkt, readyTime)); 2982568SN/A} 2992568SN/A 3002568SN/Avoid 3018713Sandreas.hansson@arm.comBridge::BridgeMasterPort::trySend() 3022568SN/A{ 3038713Sandreas.hansson@arm.com assert(!requestQueue.empty()); 3042568SN/A 3059029Sandreas.hansson@arm.com DeferredRequest req = requestQueue.front(); 3062643Sstever@eecs.umich.edu 3079029Sandreas.hansson@arm.com assert(req.ready <= curTick()); 3082643Sstever@eecs.umich.edu 3099029Sandreas.hansson@arm.com PacketPtr pkt = req.pkt; 3102643Sstever@eecs.umich.edu 3119029Sandreas.hansson@arm.com DPRINTF(BusBridge, "trySend request: addr 0x%x\n", pkt->getAddr()); 3124432Ssaidi@eecs.umich.edu 3138975Sandreas.hansson@arm.com if (sendTimingReq(pkt)) { 3142643Sstever@eecs.umich.edu // send successful 3158713Sandreas.hansson@arm.com requestQueue.pop_front(); 3162657Ssaidi@eecs.umich.edu 3172657Ssaidi@eecs.umich.edu // If there are more packets to send, schedule event to try again. 3188713Sandreas.hansson@arm.com if (!requestQueue.empty()) { 3199029Sandreas.hansson@arm.com req = requestQueue.front(); 3204433Ssaidi@eecs.umich.edu DPRINTF(BusBridge, "Scheduling next send\n"); 3219029Sandreas.hansson@arm.com bridge->schedule(sendEvent, 3229029Sandreas.hansson@arm.com std::max(req.ready, curTick() + 1)); 3232657Ssaidi@eecs.umich.edu } 3242643Sstever@eecs.umich.edu } else { 3254435Ssaidi@eecs.umich.edu inRetry = true; 3262643Sstever@eecs.umich.edu } 3274986Ssaidi@eecs.umich.edu 3288713Sandreas.hansson@arm.com DPRINTF(BusBridge, "trySend: request queue size: %d\n", 3298713Sandreas.hansson@arm.com requestQueue.size()); 3302568SN/A} 3312568SN/A 3328713Sandreas.hansson@arm.comvoid 3338713Sandreas.hansson@arm.comBridge::BridgeSlavePort::trySend() 3348713Sandreas.hansson@arm.com{ 3358713Sandreas.hansson@arm.com assert(!responseQueue.empty()); 3368713Sandreas.hansson@arm.com 3379029Sandreas.hansson@arm.com DeferredResponse resp = responseQueue.front(); 3388713Sandreas.hansson@arm.com 3399029Sandreas.hansson@arm.com assert(resp.ready <= curTick()); 3408713Sandreas.hansson@arm.com 3419029Sandreas.hansson@arm.com PacketPtr pkt = resp.pkt; 3428713Sandreas.hansson@arm.com 3439029Sandreas.hansson@arm.com DPRINTF(BusBridge, "trySend response: dest %d addr 0x%x\n", 3449029Sandreas.hansson@arm.com pkt->getDest(), pkt->getAddr()); 3458713Sandreas.hansson@arm.com 3469029Sandreas.hansson@arm.com bool was_nacked_here = resp.nackedHere; 3478713Sandreas.hansson@arm.com 3488975Sandreas.hansson@arm.com if (sendTimingResp(pkt)) { 3498713Sandreas.hansson@arm.com DPRINTF(BusBridge, " successful\n"); 3508713Sandreas.hansson@arm.com // send successful 3518713Sandreas.hansson@arm.com responseQueue.pop_front(); 3528713Sandreas.hansson@arm.com 3538713Sandreas.hansson@arm.com if (!was_nacked_here) { 3548713Sandreas.hansson@arm.com assert(outstandingResponses != 0); 3558713Sandreas.hansson@arm.com --outstandingResponses; 3568713Sandreas.hansson@arm.com } 3578713Sandreas.hansson@arm.com 3588713Sandreas.hansson@arm.com // If there are more packets to send, schedule event to try again. 3598713Sandreas.hansson@arm.com if (!responseQueue.empty()) { 3609029Sandreas.hansson@arm.com resp = responseQueue.front(); 3618713Sandreas.hansson@arm.com DPRINTF(BusBridge, "Scheduling next send\n"); 3629029Sandreas.hansson@arm.com bridge->schedule(sendEvent, 3639029Sandreas.hansson@arm.com std::max(resp.ready, curTick() + 1)); 3648713Sandreas.hansson@arm.com } 3658713Sandreas.hansson@arm.com } else { 3668713Sandreas.hansson@arm.com DPRINTF(BusBridge, " unsuccessful\n"); 3678713Sandreas.hansson@arm.com inRetry = true; 3688713Sandreas.hansson@arm.com } 3698713Sandreas.hansson@arm.com 3708713Sandreas.hansson@arm.com DPRINTF(BusBridge, "trySend: queue size: %d outstanding resp: %d\n", 3718713Sandreas.hansson@arm.com responseQueue.size(), outstandingResponses); 3728713Sandreas.hansson@arm.com} 3732568SN/A 3742657Ssaidi@eecs.umich.eduvoid 3758713Sandreas.hansson@arm.comBridge::BridgeMasterPort::recvRetry() 3762568SN/A{ 3774435Ssaidi@eecs.umich.edu inRetry = false; 3789029Sandreas.hansson@arm.com Tick nextReady = requestQueue.front().ready; 3797823Ssteve.reinhardt@amd.com if (nextReady <= curTick()) 3804435Ssaidi@eecs.umich.edu trySend(); 3814435Ssaidi@eecs.umich.edu else 3828708Sandreas.hansson@arm.com bridge->schedule(sendEvent, nextReady); 3832568SN/A} 3842568SN/A 3858713Sandreas.hansson@arm.comvoid 3868713Sandreas.hansson@arm.comBridge::BridgeSlavePort::recvRetry() 3872568SN/A{ 3888713Sandreas.hansson@arm.com inRetry = false; 3899029Sandreas.hansson@arm.com Tick nextReady = responseQueue.front().ready; 3908713Sandreas.hansson@arm.com if (nextReady <= curTick()) 3918713Sandreas.hansson@arm.com trySend(); 3928713Sandreas.hansson@arm.com else 3938713Sandreas.hansson@arm.com bridge->schedule(sendEvent, nextReady); 3942568SN/A} 3952568SN/A 3968713Sandreas.hansson@arm.comTick 3978713Sandreas.hansson@arm.comBridge::BridgeSlavePort::recvAtomic(PacketPtr pkt) 3988713Sandreas.hansson@arm.com{ 3998851Sandreas.hansson@arm.com return delay + masterPort.sendAtomic(pkt); 4008713Sandreas.hansson@arm.com} 4018713Sandreas.hansson@arm.com 4022568SN/Avoid 4038713Sandreas.hansson@arm.comBridge::BridgeSlavePort::recvFunctional(PacketPtr pkt) 4042568SN/A{ 4059029Sandreas.hansson@arm.com std::list<DeferredResponse>::iterator i; 4062568SN/A 4075314Sstever@gmail.com pkt->pushLabel(name()); 4085314Sstever@gmail.com 4098713Sandreas.hansson@arm.com // check the response queue 4108713Sandreas.hansson@arm.com for (i = responseQueue.begin(); i != responseQueue.end(); ++i) { 4119029Sandreas.hansson@arm.com if (pkt->checkFunctional((*i).pkt)) { 4127668Ssteve.reinhardt@amd.com pkt->makeResponse(); 4134626Sstever@eecs.umich.edu return; 4147668Ssteve.reinhardt@amd.com } 4152568SN/A } 4162568SN/A 4178713Sandreas.hansson@arm.com // also check the master port's request queue 4188851Sandreas.hansson@arm.com if (masterPort.checkFunctional(pkt)) { 4198713Sandreas.hansson@arm.com return; 4208713Sandreas.hansson@arm.com } 4218713Sandreas.hansson@arm.com 4225314Sstever@gmail.com pkt->popLabel(); 4235314Sstever@gmail.com 4244626Sstever@eecs.umich.edu // fall through if pkt still not satisfied 4258851Sandreas.hansson@arm.com masterPort.sendFunctional(pkt); 4268713Sandreas.hansson@arm.com} 4278713Sandreas.hansson@arm.com 4288713Sandreas.hansson@arm.combool 4298713Sandreas.hansson@arm.comBridge::BridgeMasterPort::checkFunctional(PacketPtr pkt) 4308713Sandreas.hansson@arm.com{ 4318713Sandreas.hansson@arm.com bool found = false; 4329029Sandreas.hansson@arm.com std::list<DeferredRequest>::iterator i = requestQueue.begin(); 4338713Sandreas.hansson@arm.com 4348713Sandreas.hansson@arm.com while(i != requestQueue.end() && !found) { 4359029Sandreas.hansson@arm.com if (pkt->checkFunctional((*i).pkt)) { 4368713Sandreas.hansson@arm.com pkt->makeResponse(); 4378713Sandreas.hansson@arm.com found = true; 4388713Sandreas.hansson@arm.com } 4398713Sandreas.hansson@arm.com ++i; 4408713Sandreas.hansson@arm.com } 4418713Sandreas.hansson@arm.com 4428713Sandreas.hansson@arm.com return found; 4432568SN/A} 4442568SN/A 4458711Sandreas.hansson@arm.comAddrRangeList 4469090Sandreas.hansson@arm.comBridge::BridgeSlavePort::getAddrRanges() const 4472568SN/A{ 4488711Sandreas.hansson@arm.com return ranges; 4492568SN/A} 4502568SN/A 4514762Snate@binkert.orgBridge * 4524762Snate@binkert.orgBridgeParams::create() 4532568SN/A{ 4544762Snate@binkert.org return new Bridge(this); 4552568SN/A} 456