packet_queue.hh revision 10322
113540Sandrea.mondelli@ucf.edu/* 21376Sbinkertn@umich.edu * Copyright (c) 2012 ARM Limited 31376Sbinkertn@umich.edu * All rights reserved. 41376Sbinkertn@umich.edu * 51376Sbinkertn@umich.edu * The license below extends only to copyright in the software and shall 61376Sbinkertn@umich.edu * not be construed as granting a license to any other intellectual 71376Sbinkertn@umich.edu * property including but not limited to intellectual property relating 81376Sbinkertn@umich.edu * to a hardware implementation of the functionality of the software 91376Sbinkertn@umich.edu * licensed hereunder. You may use the software subject to the license 101376Sbinkertn@umich.edu * terms below provided that you ensure that this notice is replicated 111376Sbinkertn@umich.edu * unmodified and in its entirety in all distributions of the software, 121376Sbinkertn@umich.edu * modified or unmodified, in source code or in binary form. 131376Sbinkertn@umich.edu * 141376Sbinkertn@umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 151376Sbinkertn@umich.edu * All rights reserved. 161376Sbinkertn@umich.edu * 171376Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without 181376Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are 191376Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright 201376Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer; 211376Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright 221376Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the 231376Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution; 241376Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its 251376Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from 261376Sbinkertn@umich.edu * this software without specific prior written permission. 271376Sbinkertn@umich.edu * 281376Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 291376Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 301376Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 311385Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 321376Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 331816Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 341376Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 351816Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 361376Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 371385Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 381385Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 391385Sbinkertn@umich.edu * 401385Sbinkertn@umich.edu * Authors: Ali Saidi 411385Sbinkertn@umich.edu * Andreas Hansson 421385Sbinkertn@umich.edu */ 431385Sbinkertn@umich.edu 441816Sbinkertn@umich.edu#ifndef __MEM_PACKET_QUEUE_HH__ 451816Sbinkertn@umich.edu#define __MEM_PACKET_QUEUE_HH__ 461816Sbinkertn@umich.edu 471816Sbinkertn@umich.edu/** 481816Sbinkertn@umich.edu * @file 491816Sbinkertn@umich.edu * Declaration of a simple PacketQueue that is associated with 501816Sbinkertn@umich.edu * a port on which it attempts to send packets according to the time 511816Sbinkertn@umich.edu * stamp given to them at insertion. The packet queue is responsible 521816Sbinkertn@umich.edu * for the flow control of the port, but relies on the module 531816Sbinkertn@umich.edu * notifying the queue when a transfer ends. 541816Sbinkertn@umich.edu */ 551816Sbinkertn@umich.edu 561816Sbinkertn@umich.edu#include <list> 571816Sbinkertn@umich.edu 581816Sbinkertn@umich.edu#include "mem/port.hh" 591816Sbinkertn@umich.edu#include "sim/drain.hh" 601816Sbinkertn@umich.edu#include "sim/eventq_impl.hh" 611816Sbinkertn@umich.edu 621816Sbinkertn@umich.edu/** 631816Sbinkertn@umich.edu * A packet queue is a class that holds deferred packets and later 641816Sbinkertn@umich.edu * sends them using the associated slave port or master port. 651816Sbinkertn@umich.edu */ 661816Sbinkertn@umich.educlass PacketQueue : public Drainable 671816Sbinkertn@umich.edu{ 681816Sbinkertn@umich.edu private: 691816Sbinkertn@umich.edu /** A deferred packet, buffered to transmit later. */ 701816Sbinkertn@umich.edu class DeferredPacket { 711816Sbinkertn@umich.edu public: 721816Sbinkertn@umich.edu Tick tick; ///< The tick when the packet is ready to transmit 731816Sbinkertn@umich.edu PacketPtr pkt; ///< Pointer to the packet to transmit 741816Sbinkertn@umich.edu bool sendAsSnoop; ///< Should it be sent as a snoop or not 751816Sbinkertn@umich.edu DeferredPacket(Tick t, PacketPtr p, bool send_as_snoop) 761385Sbinkertn@umich.edu : tick(t), pkt(p), sendAsSnoop(send_as_snoop) 771376Sbinkertn@umich.edu {} 781376Sbinkertn@umich.edu }; 791376Sbinkertn@umich.edu 801602Sbinkertn@umich.edu typedef std::list<DeferredPacket> DeferredPacketList; 811376Sbinkertn@umich.edu 821956Ssaidi@eecs.umich.edu /** A list of outgoing timing response packets that haven't been 831956Ssaidi@eecs.umich.edu * serviced yet. */ 841376Sbinkertn@umich.edu DeferredPacketList transmitList; 851376Sbinkertn@umich.edu 861376Sbinkertn@umich.edu /** The manager which is used for the event queue */ 871916Sbinkertn@umich.edu EventManager& em; 881376Sbinkertn@umich.edu 891376Sbinkertn@umich.edu /** This function attempts to send deferred packets. Scheduled to 901602Sbinkertn@umich.edu * be called in the future via SendEvent. */ 911916Sbinkertn@umich.edu void processSendEvent(); 921376Sbinkertn@umich.edu 931376Sbinkertn@umich.edu /** 941376Sbinkertn@umich.edu * Event used to call processSendEvent. 951376Sbinkertn@umich.edu **/ 961376Sbinkertn@umich.edu EventWrapper<PacketQueue, &PacketQueue::processSendEvent> sendEvent; 971376Sbinkertn@umich.edu 981376Sbinkertn@umich.edu /** If we need to drain, keep the drain manager around until we're done 991376Sbinkertn@umich.edu * here.*/ 1001376Sbinkertn@umich.edu DrainManager *drainManager; 1011948Sbinkertn@umich.edu 1021376Sbinkertn@umich.edu protected: 1031376Sbinkertn@umich.edu 1041376Sbinkertn@umich.edu /** Label to use for print request packets label stack. */ 1051916Sbinkertn@umich.edu const std::string label; 1061376Sbinkertn@umich.edu 1071376Sbinkertn@umich.edu /** Remember whether we're awaiting a retry from the bus. */ 1081376Sbinkertn@umich.edu bool waitingOnRetry; 1091376Sbinkertn@umich.edu 1101376Sbinkertn@umich.edu /** Check whether we have a packet ready to go on the transmit list. */ 1111376Sbinkertn@umich.edu bool deferredPacketReady() const 1121376Sbinkertn@umich.edu { return !transmitList.empty() && transmitList.front().tick <= curTick(); } 1131916Sbinkertn@umich.edu 1141881Sbinkertn@umich.edu Tick deferredPacketReadyTime() const 1151881Sbinkertn@umich.edu { return transmitList.empty() ? MaxTick : transmitList.front().tick; } 1161881Sbinkertn@umich.edu 1171916Sbinkertn@umich.edu /** 1181948Sbinkertn@umich.edu * Attempt to send the packet at the head of the transmit 1191881Sbinkertn@umich.edu * list. Caller must guarantee that the list is non-empty and that 1201381Sbinkertn@umich.edu * the head packet is scheduled for curTick() (or earlier). Note 1211881Sbinkertn@umich.edu * that a subclass of the PacketQueue can override this method and 1221881Sbinkertn@umich.edu * thus change the behaviour (as done by the cache). 1231381Sbinkertn@umich.edu */ 1241376Sbinkertn@umich.edu virtual void sendDeferredPacket(); 1251916Sbinkertn@umich.edu 1261916Sbinkertn@umich.edu /** 1271381Sbinkertn@umich.edu * Attempt to send the packet at the front of the transmit list, 1281376Sbinkertn@umich.edu * and set waitingOnRetry accordingly. The packet is temporarily 1291381Sbinkertn@umich.edu * taken off the list, but put back at the front if not 1301376Sbinkertn@umich.edu * successfully sent. 1311381Sbinkertn@umich.edu */ 1321376Sbinkertn@umich.edu void trySendTiming(); 1331376Sbinkertn@umich.edu 1341602Sbinkertn@umich.edu /** 1351602Sbinkertn@umich.edu * 1361381Sbinkertn@umich.edu */ 1371376Sbinkertn@umich.edu virtual bool sendTiming(PacketPtr pkt, bool send_as_snoop) = 0; 1381948Sbinkertn@umich.edu 1391948Sbinkertn@umich.edu /** 1401381Sbinkertn@umich.edu * Based on the transmit list, or the provided time, schedule a 1411381Sbinkertn@umich.edu * send event if there are packets to send. If we are idle and 1421916Sbinkertn@umich.edu * asked to drain then do so. 1431916Sbinkertn@umich.edu * 1441916Sbinkertn@umich.edu * @param time an alternative time for the next send event 1451916Sbinkertn@umich.edu */ 1461381Sbinkertn@umich.edu void scheduleSend(Tick time = MaxTick); 1471376Sbinkertn@umich.edu 1481376Sbinkertn@umich.edu /** 1491881Sbinkertn@umich.edu * Simple ports are generally used as slave ports (i.e. the 1501881Sbinkertn@umich.edu * respond to requests) and thus do not expect to receive any 1511381Sbinkertn@umich.edu * range changes (as the neighbouring port has a master role and 1521376Sbinkertn@umich.edu * do not have any address ranges. A subclass can override the 1531376Sbinkertn@umich.edu * default behaviuor if needed. 1541376Sbinkertn@umich.edu */ 1551881Sbinkertn@umich.edu virtual void recvRangeChange() { } 1561881Sbinkertn@umich.edu 1571881Sbinkertn@umich.edu /** 1581881Sbinkertn@umich.edu * Create a packet queue, linked to an event manager, and a label 1591881Sbinkertn@umich.edu * that will be used for functional print request packets. 1601948Sbinkertn@umich.edu * 1611385Sbinkertn@umich.edu * @param _em Event manager used for scheduling this queue 1621385Sbinkertn@umich.edu * @param _label Label to push on the label stack for print request packets 1631916Sbinkertn@umich.edu */ 1641916Sbinkertn@umich.edu PacketQueue(EventManager& _em, const std::string& _label); 1651881Sbinkertn@umich.edu 1661376Sbinkertn@umich.edu /** 1671881Sbinkertn@umich.edu * Virtual desctructor since the class may be used as a base class. 1681881Sbinkertn@umich.edu */ 1691376Sbinkertn@umich.edu virtual ~PacketQueue(); 1701881Sbinkertn@umich.edu 1711881Sbinkertn@umich.edu public: 1721881Sbinkertn@umich.edu 1731881Sbinkertn@umich.edu /** 1741881Sbinkertn@umich.edu * Provide a name to simplify debugging. 1751881Sbinkertn@umich.edu * 1761376Sbinkertn@umich.edu * @return A complete name, appended to module and port 1771881Sbinkertn@umich.edu */ 1781881Sbinkertn@umich.edu virtual const std::string name() const = 0; 1791376Sbinkertn@umich.edu 1801376Sbinkertn@umich.edu /** Check the list of buffered packets against the supplied 1811881Sbinkertn@umich.edu * functional request. */ 1821881Sbinkertn@umich.edu bool checkFunctional(PacketPtr pkt); 1831881Sbinkertn@umich.edu 1841881Sbinkertn@umich.edu /** 1851881Sbinkertn@umich.edu * Schedule a send even if not already waiting for a retry. If the 1861881Sbinkertn@umich.edu * requested time is before an already scheduled send event it 1871881Sbinkertn@umich.edu * will be rescheduled. 1881376Sbinkertn@umich.edu * 1891376Sbinkertn@umich.edu * @param when 1901376Sbinkertn@umich.edu */ 1911881Sbinkertn@umich.edu void schedSendEvent(Tick when); 1921881Sbinkertn@umich.edu 1931376Sbinkertn@umich.edu /** 1941881Sbinkertn@umich.edu * Add a packet to the transmit list, and ensure that a 1951881Sbinkertn@umich.edu * processSendEvent is called in the future. 1961376Sbinkertn@umich.edu * 1971376Sbinkertn@umich.edu * @param pkt Packet to send 1981376Sbinkertn@umich.edu * @param when Absolute time (in ticks) to send packet 1991881Sbinkertn@umich.edu * @param send_as_snoop Send the packet as a snoop or not 2001881Sbinkertn@umich.edu */ 2011881Sbinkertn@umich.edu void schedSendTiming(PacketPtr pkt, Tick when, bool send_as_snoop = false); 2021881Sbinkertn@umich.edu 2031376Sbinkertn@umich.edu /** 2041881Sbinkertn@umich.edu * Used by a port to notify the queue that a retry was received 2051881Sbinkertn@umich.edu * and that the queue can proceed and retry sending the packet 2061376Sbinkertn@umich.edu * that caused the wait. 2071376Sbinkertn@umich.edu */ 2081881Sbinkertn@umich.edu void retry(); 2091881Sbinkertn@umich.edu 2101881Sbinkertn@umich.edu unsigned int drain(DrainManager *dm); 2111881Sbinkertn@umich.edu}; 2121376Sbinkertn@umich.edu 2131376Sbinkertn@umich.educlass MasterPacketQueue : public PacketQueue 2141376Sbinkertn@umich.edu{ 2151881Sbinkertn@umich.edu 2161376Sbinkertn@umich.edu protected: 2171881Sbinkertn@umich.edu 2181881Sbinkertn@umich.edu MasterPort& masterPort; 2191881Sbinkertn@umich.edu 2201376Sbinkertn@umich.edu public: 2211881Sbinkertn@umich.edu 2221881Sbinkertn@umich.edu /** 2231881Sbinkertn@umich.edu * Create a master packet queue, linked to an event manager, a 2241881Sbinkertn@umich.edu * master port, and a label that will be used for functional print 2251881Sbinkertn@umich.edu * request packets. 2261816Sbinkertn@umich.edu * 2271881Sbinkertn@umich.edu * @param _em Event manager used for scheduling this queue 2281881Sbinkertn@umich.edu * @param _masterPort Master port used to send the packets 2291881Sbinkertn@umich.edu * @param _label Label to push on the label stack for print request packets 2301881Sbinkertn@umich.edu */ 2311881Sbinkertn@umich.edu MasterPacketQueue(EventManager& _em, MasterPort& _masterPort, 2321816Sbinkertn@umich.edu const std::string _label = "MasterPacketQueue"); 2331881Sbinkertn@umich.edu 2341881Sbinkertn@umich.edu virtual ~MasterPacketQueue() { } 2351881Sbinkertn@umich.edu 2361881Sbinkertn@umich.edu const std::string name() const 2371881Sbinkertn@umich.edu { return masterPort.name() + "-" + label; } 2381376Sbinkertn@umich.edu 2391881Sbinkertn@umich.edu bool sendTiming(PacketPtr pkt, bool send_as_snoop); 2401881Sbinkertn@umich.edu}; 2411881Sbinkertn@umich.edu 2421881Sbinkertn@umich.educlass SlavePacketQueue : public PacketQueue 2431881Sbinkertn@umich.edu{ 2441881Sbinkertn@umich.edu 2451881Sbinkertn@umich.edu protected: 2461376Sbinkertn@umich.edu 2471881Sbinkertn@umich.edu SlavePort& slavePort; 2481881Sbinkertn@umich.edu 2491881Sbinkertn@umich.edu public: 2501881Sbinkertn@umich.edu 2511881Sbinkertn@umich.edu /** 2521881Sbinkertn@umich.edu * Create a slave packet queue, linked to an event manager, a 2531916Sbinkertn@umich.edu * slave port, and a label that will be used for functional print 2541916Sbinkertn@umich.edu * request packets. 2551916Sbinkertn@umich.edu * 2561881Sbinkertn@umich.edu * @param _em Event manager used for scheduling this queue 2571881Sbinkertn@umich.edu * @param _slavePort Slave port used to send the packets 2581881Sbinkertn@umich.edu * @param _label Label to push on the label stack for print request packets 2591881Sbinkertn@umich.edu */ 2601881Sbinkertn@umich.edu SlavePacketQueue(EventManager& _em, SlavePort& _slavePort, 2611385Sbinkertn@umich.edu const std::string _label = "SlavePacketQueue"); 2621376Sbinkertn@umich.edu 2631376Sbinkertn@umich.edu virtual ~SlavePacketQueue() { } 2641376Sbinkertn@umich.edu 2651881Sbinkertn@umich.edu const std::string name() const 2661881Sbinkertn@umich.edu { return slavePort.name() + "-" + label; } 2671376Sbinkertn@umich.edu 2681916Sbinkertn@umich.edu bool sendTiming(PacketPtr pkt, bool send_as_snoop); 2691881Sbinkertn@umich.edu 2701881Sbinkertn@umich.edu}; 2711916Sbinkertn@umich.edu 2721916Sbinkertn@umich.edu#endif // __MEM_PACKET_QUEUE_HH__ 2731916Sbinkertn@umich.edu