packet_queue.hh revision 7823
110717Sandreas.hansson@arm.com/*
28839Sandreas.hansson@arm.com * Copyright (c) 2006 The Regents of The University of Michigan
38839Sandreas.hansson@arm.com * All rights reserved.
48839Sandreas.hansson@arm.com *
58839Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68839Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78839Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88839Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98839Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108839Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118839Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128839Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
135335Shines@cs.fsu.edu * contributors may be used to endorse or promote products derived from
147897Shestness@cs.utexas.edu * this software without specific prior written permission.
154486Sbinkertn@umich.edu *
164486Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
174486Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
184486Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
194486Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
204486Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
214486Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
224486Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
234486Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
244486Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254486Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
264486Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274486Sbinkertn@umich.edu *
284486Sbinkertn@umich.edu * Authors: Ali Saidi
294486Sbinkertn@umich.edu */
304486Sbinkertn@umich.edu
314486Sbinkertn@umich.edu#ifndef __MEM_TPORT_HH__
324486Sbinkertn@umich.edu#define __MEM_TPORT_HH__
334486Sbinkertn@umich.edu
344486Sbinkertn@umich.edu/**
354486Sbinkertn@umich.edu * @file
364486Sbinkertn@umich.edu *
374486Sbinkertn@umich.edu * Declaration of SimpleTimingPort.
384486Sbinkertn@umich.edu */
394486Sbinkertn@umich.edu
404486Sbinkertn@umich.edu#include "mem/port.hh"
417897Shestness@cs.utexas.edu#include "sim/eventq.hh"
428839Sandreas.hansson@arm.com#include <list>
434486Sbinkertn@umich.edu#include <string>
446654Snate@binkert.org
456654Snate@binkert.org/**
466654Snate@binkert.org * A simple port for interfacing objects that basically have only
473102SN/A * functional memory behavior (e.g. I/O devices) to the memory system.
483102SN/A * Both timing and functional accesses are implemented in terms of
496654Snate@binkert.org * atomic accesses.  A derived port class thus only needs to provide
5010720Sandreas.hansson@arm.com * recvAtomic() to support all memory access modes.
514776Sgblack@eecs.umich.edu *
5210663SAli.Saidi@ARM.com * The tricky part is handling recvTiming(), where the response must
536654Snate@binkert.org * be scheduled separately via a later call to sendTiming().  This
549793Sakash.bagdia@arm.com * feature is handled by scheduling an internal event that calls
552667SN/A * sendTiming() after a delay, and optionally rescheduling the
564776Sgblack@eecs.umich.edu * response if it is nacked.
574776Sgblack@eecs.umich.edu */
586654Snate@binkert.orgclass SimpleTimingPort : public Port
596023Snate@binkert.org{
608745Sgblack@eecs.umich.edu  protected:
619384SAndreas.Sandberg@arm.com    /** A deferred packet, buffered to transmit later. */
629384SAndreas.Sandberg@arm.com    class DeferredPacket {
636654Snate@binkert.org      public:
646022Sgblack@eecs.umich.edu        Tick tick;      ///< The tick when the packet is ready to transmit
658745Sgblack@eecs.umich.edu        PacketPtr pkt;  ///< Pointer to the packet to transmit
669384SAndreas.Sandberg@arm.com        DeferredPacket(Tick t, PacketPtr p)
679384SAndreas.Sandberg@arm.com            : tick(t), pkt(p)
686654Snate@binkert.org        {}
696022Sgblack@eecs.umich.edu    };
708745Sgblack@eecs.umich.edu
719384SAndreas.Sandberg@arm.com    typedef std::list<DeferredPacket> DeferredPacketList;
729384SAndreas.Sandberg@arm.com    typedef std::list<DeferredPacket>::iterator DeferredPacketIterator;
736654Snate@binkert.org
746022Sgblack@eecs.umich.edu    /** A list of outgoing timing response packets that haven't been
758745Sgblack@eecs.umich.edu     * serviced yet. */
769384SAndreas.Sandberg@arm.com    DeferredPacketList transmitList;
779384SAndreas.Sandberg@arm.com
786654Snate@binkert.org    /** This function attempts to send deferred packets.  Scheduled to
7910037SARM gem5 Developers     * be called in the future via SendEvent. */
808745Sgblack@eecs.umich.edu    void processSendEvent();
819384SAndreas.Sandberg@arm.com
829384SAndreas.Sandberg@arm.com    /**
836691Stjones1@inf.ed.ac.uk     * This class is used to implemented sendTiming() with a delay. When
846691Stjones1@inf.ed.ac.uk     * a delay is requested a the event is scheduled if it isn't already.
858745Sgblack@eecs.umich.edu     * When the event time expires it attempts to send the packet.
869384SAndreas.Sandberg@arm.com     * If it cannot, the packet sent when recvRetry() is called.
879384SAndreas.Sandberg@arm.com     **/
884486Sbinkertn@umich.edu    Event *sendEvent;
895529Snate@binkert.org
901366SN/A    /** If we need to drain, keep the drain event around until we're done
911310SN/A     * here.*/
929338SAndreas.Sandberg@arm.com    Event *drainEvent;
939254SAndreas.Sandberg@arm.com
949254SAndreas.Sandberg@arm.com    /** Remember whether we're awaiting a retry from the bus. */
959254SAndreas.Sandberg@arm.com    bool waitingOnRetry;
969254SAndreas.Sandberg@arm.com
979254SAndreas.Sandberg@arm.com    /** Check the list of buffered packets against the supplied
989254SAndreas.Sandberg@arm.com     * functional request. */
999430SAndreas.Sandberg@ARM.com    bool checkFunctional(PacketPtr funcPkt);
1009446SAndreas.Sandberg@ARM.com
1019650Stimothy.jones@arm.com    /** Check whether we have a packet ready to go on the transmit list. */
1029749Sandreas@sandberg.pp.se    bool deferredPacketReady()
1039749Sandreas@sandberg.pp.se    { return !transmitList.empty() && transmitList.front().tick <= curTick(); }
10411415SGeoffrey.Blake@arm.com
1059254SAndreas.Sandberg@arm.com    Tick deferredPacketReadyTime()
1069254SAndreas.Sandberg@arm.com    { return transmitList.empty() ? MaxTick : transmitList.front().tick; }
1079518SAndreas.Sandberg@ARM.com
1089518SAndreas.Sandberg@ARM.com    void
1099518SAndreas.Sandberg@ARM.com    schedSendEvent(Tick when)
1109518SAndreas.Sandberg@ARM.com    {
1119518SAndreas.Sandberg@ARM.com        if (waitingOnRetry) {
1129518SAndreas.Sandberg@ARM.com            assert(!sendEvent->scheduled());
1139518SAndreas.Sandberg@ARM.com            return;
1149518SAndreas.Sandberg@ARM.com        }
1159518SAndreas.Sandberg@ARM.com
1169518SAndreas.Sandberg@ARM.com        if (!sendEvent->scheduled()) {
1179518SAndreas.Sandberg@ARM.com            schedule(sendEvent, when);
1189518SAndreas.Sandberg@ARM.com        } else if (sendEvent->when() > when) {
1199518SAndreas.Sandberg@ARM.com            reschedule(sendEvent, when);
1209518SAndreas.Sandberg@ARM.com        }
1219518SAndreas.Sandberg@ARM.com    }
1229518SAndreas.Sandberg@ARM.com
1239518SAndreas.Sandberg@ARM.com
1249518SAndreas.Sandberg@ARM.com    /** Schedule a sendTiming() event to be called in the future.
1259518SAndreas.Sandberg@ARM.com     * @param pkt packet to send
1269254SAndreas.Sandberg@arm.com     * @param absolute time (in ticks) to send packet
1279254SAndreas.Sandberg@arm.com     */
1289254SAndreas.Sandberg@arm.com    void schedSendTiming(PacketPtr pkt, Tick when);
1299254SAndreas.Sandberg@arm.com
1302901SN/A    /** Attempt to send the packet at the head of the deferred packet
1315712Shsul@eecs.umich.edu     * list.  Caller must guarantee that the deferred packet list is
13210190Sakash.bagdia@arm.com     * non-empty and that the head packet is scheduled for curTick() (or
1335529Snate@binkert.org     * earlier).
1345529Snate@binkert.org     */
1355529Snate@binkert.org    void sendDeferredPacket();
1369161Sandreas.hansson@arm.com
1375529Snate@binkert.org    /** This function is notification that the device should attempt to send a
1385821Ssaidi@eecs.umich.edu     * packet again. */
1393170SN/A    virtual void recvRetry();
1405780Ssteve.reinhardt@amd.com
1415780Ssteve.reinhardt@amd.com    /** Implemented using recvAtomic(). */
1425780Ssteve.reinhardt@amd.com    void recvFunctional(PacketPtr pkt);
1435780Ssteve.reinhardt@amd.com
1445780Ssteve.reinhardt@amd.com    /** Implemented using recvAtomic(). */
1458784Sgblack@eecs.umich.edu    bool recvTiming(PacketPtr pkt);
1468784Sgblack@eecs.umich.edu
1478784Sgblack@eecs.umich.edu    /**
1488793Sgblack@eecs.umich.edu     * Simple ports generally don't care about any status
1491310SN/A     * changes... can always override this in cases where that's not
1506654Snate@binkert.org     * true. */
1516022Sgblack@eecs.umich.edu    virtual void recvStatusChange(Status status) { }
1526022Sgblack@eecs.umich.edu
15311150Smitch.hayenga@arm.com
15411150Smitch.hayenga@arm.com  public:
1559384SAndreas.Sandberg@arm.com    SimpleTimingPort(std::string pname, MemObject *_owner);
1566654Snate@binkert.org    ~SimpleTimingPort();
1576023Snate@binkert.org
1586023Snate@binkert.org    /** Hook for draining timing accesses from the system.  The
15911150Smitch.hayenga@arm.com     * associated SimObject's drain() functions should be implemented
16011150Smitch.hayenga@arm.com     * something like this when this class is used:
1619384SAndreas.Sandberg@arm.com     \code
1626654Snate@binkert.org          PioDevice::drain(Event *de)
1636022Sgblack@eecs.umich.edu          {
1646022Sgblack@eecs.umich.edu              unsigned int count;
16511150Smitch.hayenga@arm.com              count = SimpleTimingPort->drain(de);
1669384SAndreas.Sandberg@arm.com              if (count)
1676654Snate@binkert.org                  changeState(Draining);
1686022Sgblack@eecs.umich.edu              else
1696022Sgblack@eecs.umich.edu                  changeState(Drained);
17011150Smitch.hayenga@arm.com              return count;
17111150Smitch.hayenga@arm.com          }
1729384SAndreas.Sandberg@arm.com     \endcode
1736654Snate@binkert.org    */
1746116Snate@binkert.org    unsigned int drain(Event *de);
1756116Snate@binkert.org};
17610037SARM gem5 Developers
17710037SARM gem5 Developers#endif // __MEM_TPORT_HH__
17811150Smitch.hayenga@arm.com