tport.cc revision 3352:8e940d22b2a8
112396SRiken.Gohil@arm.com/* 212396SRiken.Gohil@arm.com * Copyright (c) 2006 The Regents of The University of Michigan 312396SRiken.Gohil@arm.com * All rights reserved. 412396SRiken.Gohil@arm.com * 512396SRiken.Gohil@arm.com * Redistribution and use in source and binary forms, with or without 612396SRiken.Gohil@arm.com * modification, are permitted provided that the following conditions are 712396SRiken.Gohil@arm.com * met: redistributions of source code must retain the above copyright 812396SRiken.Gohil@arm.com * notice, this list of conditions and the following disclaimer; 912396SRiken.Gohil@arm.com * redistributions in binary form must reproduce the above copyright 1012396SRiken.Gohil@arm.com * notice, this list of conditions and the following disclaimer in the 1112396SRiken.Gohil@arm.com * documentation and/or other materials provided with the distribution; 1212396SRiken.Gohil@arm.com * neither the name of the copyright holders nor the names of its 1312396SRiken.Gohil@arm.com * contributors may be used to endorse or promote products derived from 1412396SRiken.Gohil@arm.com * this software without specific prior written permission. 1512396SRiken.Gohil@arm.com * 1612396SRiken.Gohil@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712396SRiken.Gohil@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812396SRiken.Gohil@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912396SRiken.Gohil@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012396SRiken.Gohil@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112396SRiken.Gohil@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212396SRiken.Gohil@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312396SRiken.Gohil@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412396SRiken.Gohil@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512396SRiken.Gohil@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612396SRiken.Gohil@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712396SRiken.Gohil@arm.com * 2812396SRiken.Gohil@arm.com * Authors: Ali Saidi 2912396SRiken.Gohil@arm.com */ 3012396SRiken.Gohil@arm.com 3112396SRiken.Gohil@arm.com#include "mem/tport.hh" 3212396SRiken.Gohil@arm.com 3312396SRiken.Gohil@arm.comvoid 3412396SRiken.Gohil@arm.comSimpleTimingPort::recvFunctional(PacketPtr pkt) 3512396SRiken.Gohil@arm.com{ 3612396SRiken.Gohil@arm.com std::list<PacketPtr>::iterator i = transmitList.begin(); 3712396SRiken.Gohil@arm.com std::list<PacketPtr>::iterator end = transmitList.end(); 3812396SRiken.Gohil@arm.com bool cont = true; 3912396SRiken.Gohil@arm.com 4012396SRiken.Gohil@arm.com while (i != end) { 4112396SRiken.Gohil@arm.com PacketPtr target = *i; 4212396SRiken.Gohil@arm.com // If the target contains data, and it overlaps the 4312396SRiken.Gohil@arm.com // probed request, need to update data 4412396SRiken.Gohil@arm.com if (target->intersect(pkt)) 4512396SRiken.Gohil@arm.com fixPacket(pkt, target); 4612396SRiken.Gohil@arm.com 4712396SRiken.Gohil@arm.com } 4812396SRiken.Gohil@arm.com 4912396SRiken.Gohil@arm.com //Then just do an atomic access and throw away the returned latency 5012396SRiken.Gohil@arm.com if (pkt->result != Packet::Success) 5112396SRiken.Gohil@arm.com recvAtomic(pkt); 5212396SRiken.Gohil@arm.com} 5312396SRiken.Gohil@arm.com 5412396SRiken.Gohil@arm.combool 5512396SRiken.Gohil@arm.comSimpleTimingPort::recvTiming(PacketPtr pkt) 5612396SRiken.Gohil@arm.com{ 5712396SRiken.Gohil@arm.com // If the device is only a slave, it should only be sending 5812396SRiken.Gohil@arm.com // responses, which should never get nacked. There used to be 5912396SRiken.Gohil@arm.com // code to hanldle nacks here, but I'm pretty sure it didn't work 6012396SRiken.Gohil@arm.com // correctly with the drain code, so that would need to be fixed 6112396SRiken.Gohil@arm.com // if we ever added it back. 6212396SRiken.Gohil@arm.com assert(pkt->result != Packet::Nacked); 6312396SRiken.Gohil@arm.com Tick latency = recvAtomic(pkt); 6412396SRiken.Gohil@arm.com // turn packet around to go back to requester if response expected 6512396SRiken.Gohil@arm.com if (pkt->needsResponse()) { 6612396SRiken.Gohil@arm.com pkt->makeTimingResponse(); 6712396SRiken.Gohil@arm.com sendTimingLater(pkt, latency); 6812396SRiken.Gohil@arm.com } 6912396SRiken.Gohil@arm.com else { 7012396SRiken.Gohil@arm.com if (pkt->cmd != Packet::UpgradeReq) 7112396SRiken.Gohil@arm.com { 7212396SRiken.Gohil@arm.com delete pkt->req; 7312396SRiken.Gohil@arm.com delete pkt; 7412396SRiken.Gohil@arm.com } 7512396SRiken.Gohil@arm.com } 7612396SRiken.Gohil@arm.com return true; 7712396SRiken.Gohil@arm.com} 7812396SRiken.Gohil@arm.com 7912396SRiken.Gohil@arm.comvoid 8012396SRiken.Gohil@arm.comSimpleTimingPort::recvRetry() 8112396SRiken.Gohil@arm.com{ 8212396SRiken.Gohil@arm.com assert(outTiming > 0); 8312396SRiken.Gohil@arm.com assert(!transmitList.empty()); 8412396SRiken.Gohil@arm.com if (sendTiming(transmitList.front())) { 8512396SRiken.Gohil@arm.com transmitList.pop_front(); 8612396SRiken.Gohil@arm.com outTiming--; 8712396SRiken.Gohil@arm.com DPRINTF(Bus, "No Longer waiting on retry\n"); 8812396SRiken.Gohil@arm.com if (!transmitList.empty()) 8912396SRiken.Gohil@arm.com sendTimingLater(transmitList.front(), 1); 9012396SRiken.Gohil@arm.com } 9112396SRiken.Gohil@arm.com 9212396SRiken.Gohil@arm.com if (transmitList.empty() && drainEvent) { 9312396SRiken.Gohil@arm.com drainEvent->process(); 9412396SRiken.Gohil@arm.com drainEvent = NULL; 9512396SRiken.Gohil@arm.com } 9612396SRiken.Gohil@arm.com} 9712396SRiken.Gohil@arm.com 9812396SRiken.Gohil@arm.comvoid 9912396SRiken.Gohil@arm.comSimpleTimingPort::SendEvent::process() 10012396SRiken.Gohil@arm.com{ 10112396SRiken.Gohil@arm.com assert(port->outTiming > 0); 10212396SRiken.Gohil@arm.com if (!port->transmitList.empty() && port->transmitList.front() != packet) { 10312396SRiken.Gohil@arm.com //We are not the head of the list 10412396SRiken.Gohil@arm.com port->transmitList.push_back(packet); 10512396SRiken.Gohil@arm.com } else if (port->sendTiming(packet)) { 10612396SRiken.Gohil@arm.com // send successful 10712396SRiken.Gohil@arm.com if (port->transmitList.size()) { 10812396SRiken.Gohil@arm.com port->transmitList.pop_front(); 10912396SRiken.Gohil@arm.com port->outTiming--; 11012396SRiken.Gohil@arm.com if (!port->transmitList.empty()) 11112396SRiken.Gohil@arm.com port->sendTimingLater(port->transmitList.front(), 1); 11212396SRiken.Gohil@arm.com } 11312396SRiken.Gohil@arm.com if (port->transmitList.empty() && port->drainEvent) { 11412396SRiken.Gohil@arm.com port->drainEvent->process(); 11512396SRiken.Gohil@arm.com port->drainEvent = NULL; 11612396SRiken.Gohil@arm.com } 11712396SRiken.Gohil@arm.com } else { 11812396SRiken.Gohil@arm.com // send unsuccessful (due to flow control). Will get retry 11912396SRiken.Gohil@arm.com // callback later; save for then if not already 12012396SRiken.Gohil@arm.com DPRINTF(Bus, "Waiting on retry\n"); 12112396SRiken.Gohil@arm.com if (!(port->transmitList.front() == packet)) 12212396SRiken.Gohil@arm.com port->transmitList.push_back(packet); 12312396SRiken.Gohil@arm.com } 12412396SRiken.Gohil@arm.com} 12512396SRiken.Gohil@arm.com 12612396SRiken.Gohil@arm.com 12712396SRiken.Gohil@arm.comunsigned int 12812396SRiken.Gohil@arm.comSimpleTimingPort::drain(Event *de) 12912396SRiken.Gohil@arm.com{ 13012396SRiken.Gohil@arm.com if (outTiming == 0 && transmitList.size() == 0) 13112396SRiken.Gohil@arm.com return 0; 13212396SRiken.Gohil@arm.com drainEvent = de; 13312396SRiken.Gohil@arm.com return 1; 13412396SRiken.Gohil@arm.com} 13512396SRiken.Gohil@arm.com