packet_queue.cc revision 3403
17893SN/A/*
27893SN/A * Copyright (c) 2006 The Regents of The University of Michigan
37893SN/A * All rights reserved.
49988Snilay@cs.wisc.edu *
58825Snilay@cs.wisc.edu * Redistribution and use in source and binary forms, with or without
69988Snilay@cs.wisc.edu * modification, are permitted provided that the following conditions are
77893SN/A * met: redistributions of source code must retain the above copyright
87893SN/A * notice, this list of conditions and the following disclaimer;
97893SN/A * redistributions in binary form must reproduce the above copyright
107893SN/A * notice, this list of conditions and the following disclaimer in the
117893SN/A * documentation and/or other materials provided with the distribution;
127893SN/A * neither the name of the copyright holders nor the names of its
1310315Snilay@cs.wisc.edu * contributors may be used to endorse or promote products derived from
148825Snilay@cs.wisc.edu * this software without specific prior written permission.
159885Sstever@gmail.com *
169885Sstever@gmail.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711570SCurtis.Dunham@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
189988Snilay@cs.wisc.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911374Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
208825Snilay@cs.wisc.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
218825Snilay@cs.wisc.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2210315Snilay@cs.wisc.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311960Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
248825Snilay@cs.wisc.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2510242Ssteve.reinhardt@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
269449SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
279449SAli.Saidi@ARM.com *
288464SN/A * Authors: Ali Saidi
2910798Ssteve.reinhardt@amd.com */
3011374Ssteve.reinhardt@amd.com
318721SN/A#include "mem/tport.hh"
3211570SCurtis.Dunham@arm.com
3311570SCurtis.Dunham@arm.comvoid
3411570SCurtis.Dunham@arm.comSimpleTimingPort::recvFunctional(PacketPtr pkt)
3511570SCurtis.Dunham@arm.com{
368825Snilay@cs.wisc.edu    std::list<std::pair<Tick,PacketPtr> >::iterator i = transmitList.begin();
378825Snilay@cs.wisc.edu    std::list<std::pair<Tick,PacketPtr> >::iterator end = transmitList.end();
3811570SCurtis.Dunham@arm.com    bool done = false;
3911570SCurtis.Dunham@arm.com
407935SN/A    while (i != end && !done) {
417935SN/A        PacketPtr target = i->second;
427935SN/A        // If the target contains data, and it overlaps the
437935SN/A        // probed request, need to update data
447935SN/A        if (target->intersect(pkt))
457935SN/A            done = fixPacket(pkt, target);
467935SN/A
478983Snate@binkert.org    }
487893SN/A
499885Sstever@gmail.com    //Then just do an atomic access and throw away the returned latency
509885Sstever@gmail.com    if (pkt->result != Packet::Success)
519885Sstever@gmail.com        recvAtomic(pkt);
5210315Snilay@cs.wisc.edu}
539988Snilay@cs.wisc.edu
5410315Snilay@cs.wisc.edubool
559885Sstever@gmail.comSimpleTimingPort::recvTiming(PacketPtr pkt)
569885Sstever@gmail.com{
577893SN/A    // If the device is only a slave, it should only be sending
587893SN/A    // responses, which should never get nacked.  There used to be
599885Sstever@gmail.com    // code to hanldle nacks here, but I'm pretty sure it didn't work
607893SN/A    // correctly with the drain code, so that would need to be fixed
617893SN/A    // if we ever added it back.
628241SN/A    assert(pkt->result != Packet::Nacked);
638241SN/A    Tick latency = recvAtomic(pkt);
647893SN/A    // turn packet around to go back to requester if response expected
657893SN/A    if (pkt->needsResponse()) {
667893SN/A        pkt->makeTimingResponse();
677893SN/A        sendTiming(pkt, latency);
689481Snilay@cs.wisc.edu    }
6911960Sgabeblack@google.com    else {
707893SN/A        if (pkt->cmd != Packet::UpgradeReq)
719885Sstever@gmail.com        {
727893SN/A            delete pkt->req;
737893SN/A            delete pkt;
747893SN/A        }
757893SN/A    }
767893SN/A    return true;
777893SN/A}
787893SN/A
797893SN/Avoid
807893SN/ASimpleTimingPort::recvRetry()
8111570SCurtis.Dunham@arm.com{
827893SN/A    assert(!transmitList.empty());
837893SN/A    if (Port::sendTiming(transmitList.front().second)) {
848825Snilay@cs.wisc.edu        transmitList.pop_front();
857893SN/A        DPRINTF(Bus, "No Longer waiting on retry\n");
867893SN/A        if (!transmitList.empty()) {
879988Snilay@cs.wisc.edu            Tick time = transmitList.front().first;
889988Snilay@cs.wisc.edu            sendEvent.schedule(time <= curTick ? curTick+1 : time);
8910451Snilay@cs.wisc.edu        }
907893SN/A    }
917893SN/A
927893SN/A    if (transmitList.empty() && drainEvent) {
937893SN/A        drainEvent->process();
947893SN/A        drainEvent = NULL;
957893SN/A    }
967893SN/A}
977893SN/A
987893SN/Avoid
997893SN/ASimpleTimingPort::sendTiming(PacketPtr pkt, Tick time)
1007893SN/A{
1018825Snilay@cs.wisc.edu    if (transmitList.empty()) {
1029449SAli.Saidi@ARM.com        assert(!sendEvent.scheduled());
1037893SN/A        sendEvent.schedule(curTick+time);
1047893SN/A    }
1057893SN/A    transmitList.push_back(std::pair<Tick,PacketPtr>(time+curTick,pkt));
1067893SN/A}
1077893SN/A
1087893SN/Avoid
1097893SN/ASimpleTimingPort::SendEvent::process()
1108728SN/A{
1117893SN/A    assert(port->transmitList.size());
1129924Ssteve.reinhardt@amd.com    assert(port->transmitList.front().first <= curTick);
1137893SN/A    if (port->Port::sendTiming(port->transmitList.front().second)) {
1147893SN/A        //send successful, remove packet
1157893SN/A        port->transmitList.pop_front();
1167893SN/A        if (!port->transmitList.empty()) {
1177893SN/A            Tick time = port->transmitList.front().first;
11811570SCurtis.Dunham@arm.com            schedule(time <= curTick ? curTick+1 : time);
11911570SCurtis.Dunham@arm.com        }
12011570SCurtis.Dunham@arm.com        if (port->transmitList.empty() && port->drainEvent) {
12111570SCurtis.Dunham@arm.com            port->drainEvent->process();
1228825Snilay@cs.wisc.edu            port->drainEvent = NULL;
1237893SN/A        }
1247893SN/A        return;
1257893SN/A    }
1267893SN/A    // send unsuccessful (due to flow control).  Will get retry
1277893SN/A    // callback later; save for then if not already
1287893SN/A    DPRINTF(Bus, "Waiting on retry\n");
1299885Sstever@gmail.com}
1307893SN/A
1317893SN/A
1327893SN/Aunsigned int
1337893SN/ASimpleTimingPort::drain(Event *de)
1347893SN/A{
1357893SN/A    if (transmitList.size() == 0)
1367893SN/A        return 0;
1377893SN/A    drainEvent = de;
1387893SN/A    return 1;
13910242Ssteve.reinhardt@amd.com}
1407893SN/A