tport.hh revision 8856
12914Ssaidi@eecs.umich.edu/*
28856Sandreas.hansson@arm.com * Copyright (c) 2012 ARM Limited
38856Sandreas.hansson@arm.com * All rights reserved.
48856Sandreas.hansson@arm.com *
58856Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
68856Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
78856Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
88856Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
98856Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
108856Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
118856Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
128856Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
138856Sandreas.hansson@arm.com *
142914Ssaidi@eecs.umich.edu * Copyright (c) 2006 The Regents of The University of Michigan
152914Ssaidi@eecs.umich.edu * All rights reserved.
162914Ssaidi@eecs.umich.edu *
172914Ssaidi@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
182914Ssaidi@eecs.umich.edu * modification, are permitted provided that the following conditions are
192914Ssaidi@eecs.umich.edu * met: redistributions of source code must retain the above copyright
202914Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
212914Ssaidi@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
222914Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
232914Ssaidi@eecs.umich.edu * documentation and/or other materials provided with the distribution;
242914Ssaidi@eecs.umich.edu * neither the name of the copyright holders nor the names of its
252914Ssaidi@eecs.umich.edu * contributors may be used to endorse or promote products derived from
262914Ssaidi@eecs.umich.edu * this software without specific prior written permission.
272914Ssaidi@eecs.umich.edu *
282914Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292914Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302914Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312914Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322914Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332914Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342914Ssaidi@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352914Ssaidi@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362914Ssaidi@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372914Ssaidi@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382914Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392914Ssaidi@eecs.umich.edu *
402914Ssaidi@eecs.umich.edu * Authors: Ali Saidi
418856Sandreas.hansson@arm.com *          Andreas Hansson
422914Ssaidi@eecs.umich.edu */
432914Ssaidi@eecs.umich.edu
443091Sstever@eecs.umich.edu#ifndef __MEM_TPORT_HH__
453091Sstever@eecs.umich.edu#define __MEM_TPORT_HH__
463091Sstever@eecs.umich.edu
472914Ssaidi@eecs.umich.edu/**
482914Ssaidi@eecs.umich.edu * @file
493091Sstever@eecs.umich.edu *
503091Sstever@eecs.umich.edu * Declaration of SimpleTimingPort.
512914Ssaidi@eecs.umich.edu */
522914Ssaidi@eecs.umich.edu
538229Snate@binkert.org#include <list>
548229Snate@binkert.org#include <string>
558229Snate@binkert.org
562914Ssaidi@eecs.umich.edu#include "mem/port.hh"
572914Ssaidi@eecs.umich.edu#include "sim/eventq.hh"
582914Ssaidi@eecs.umich.edu
593091Sstever@eecs.umich.edu/**
603091Sstever@eecs.umich.edu * A simple port for interfacing objects that basically have only
613091Sstever@eecs.umich.edu * functional memory behavior (e.g. I/O devices) to the memory system.
623091Sstever@eecs.umich.edu * Both timing and functional accesses are implemented in terms of
633091Sstever@eecs.umich.edu * atomic accesses.  A derived port class thus only needs to provide
643091Sstever@eecs.umich.edu * recvAtomic() to support all memory access modes.
653091Sstever@eecs.umich.edu *
663091Sstever@eecs.umich.edu * The tricky part is handling recvTiming(), where the response must
673091Sstever@eecs.umich.edu * be scheduled separately via a later call to sendTiming().  This
683091Sstever@eecs.umich.edu * feature is handled by scheduling an internal event that calls
693091Sstever@eecs.umich.edu * sendTiming() after a delay, and optionally rescheduling the
703091Sstever@eecs.umich.edu * response if it is nacked.
713091Sstever@eecs.umich.edu */
722914Ssaidi@eecs.umich.educlass SimpleTimingPort : public Port
732914Ssaidi@eecs.umich.edu{
742914Ssaidi@eecs.umich.edu  protected:
754490Sstever@eecs.umich.edu    /** A deferred packet, buffered to transmit later. */
764490Sstever@eecs.umich.edu    class DeferredPacket {
774490Sstever@eecs.umich.edu      public:
784490Sstever@eecs.umich.edu        Tick tick;      ///< The tick when the packet is ready to transmit
794490Sstever@eecs.umich.edu        PacketPtr pkt;  ///< Pointer to the packet to transmit
804490Sstever@eecs.umich.edu        DeferredPacket(Tick t, PacketPtr p)
814490Sstever@eecs.umich.edu            : tick(t), pkt(p)
824490Sstever@eecs.umich.edu        {}
834490Sstever@eecs.umich.edu    };
844490Sstever@eecs.umich.edu
854490Sstever@eecs.umich.edu    typedef std::list<DeferredPacket> DeferredPacketList;
864490Sstever@eecs.umich.edu    typedef std::list<DeferredPacket>::iterator DeferredPacketIterator;
874490Sstever@eecs.umich.edu
883090Sstever@eecs.umich.edu    /** A list of outgoing timing response packets that haven't been
893090Sstever@eecs.umich.edu     * serviced yet. */
904490Sstever@eecs.umich.edu    DeferredPacketList transmitList;
914490Sstever@eecs.umich.edu
928856Sandreas.hansson@arm.com    /** Label to use for print request packets label stack. */
938856Sandreas.hansson@arm.com    const std::string label;
948856Sandreas.hansson@arm.com
954490Sstever@eecs.umich.edu    /** This function attempts to send deferred packets.  Scheduled to
964490Sstever@eecs.umich.edu     * be called in the future via SendEvent. */
974490Sstever@eecs.umich.edu    void processSendEvent();
983091Sstever@eecs.umich.edu
992914Ssaidi@eecs.umich.edu    /**
1003090Sstever@eecs.umich.edu     * This class is used to implemented sendTiming() with a delay. When
1013403Ssaidi@eecs.umich.edu     * a delay is requested a the event is scheduled if it isn't already.
1023403Ssaidi@eecs.umich.edu     * When the event time expires it attempts to send the packet.
1033403Ssaidi@eecs.umich.edu     * If it cannot, the packet sent when recvRetry() is called.
1043403Ssaidi@eecs.umich.edu     **/
1058856Sandreas.hansson@arm.com    EventWrapper<SimpleTimingPort,
1068856Sandreas.hansson@arm.com                 &SimpleTimingPort::processSendEvent> sendEvent;
1072914Ssaidi@eecs.umich.edu
1082914Ssaidi@eecs.umich.edu    /** If we need to drain, keep the drain event around until we're done
1092914Ssaidi@eecs.umich.edu     * here.*/
1102914Ssaidi@eecs.umich.edu    Event *drainEvent;
1112914Ssaidi@eecs.umich.edu
1124492Sstever@eecs.umich.edu    /** Remember whether we're awaiting a retry from the bus. */
1134492Sstever@eecs.umich.edu    bool waitingOnRetry;
1144492Sstever@eecs.umich.edu
1154492Sstever@eecs.umich.edu    /** Check whether we have a packet ready to go on the transmit list. */
1164492Sstever@eecs.umich.edu    bool deferredPacketReady()
1177823Ssteve.reinhardt@amd.com    { return !transmitList.empty() && transmitList.front().tick <= curTick(); }
1184492Sstever@eecs.umich.edu
1194871Sstever@eecs.umich.edu    Tick deferredPacketReadyTime()
1204666Sstever@eecs.umich.edu    { return transmitList.empty() ? MaxTick : transmitList.front().tick; }
1214666Sstever@eecs.umich.edu
1228708Sandreas.hansson@arm.com    /**
1238708Sandreas.hansson@arm.com     * Schedule a send even if not already waiting for a retry. If the
1248708Sandreas.hansson@arm.com     * requested time is before an already scheduled send event it
1258708Sandreas.hansson@arm.com     * will be rescheduled.
1268708Sandreas.hansson@arm.com     *
1278708Sandreas.hansson@arm.com     * @param when
1288708Sandreas.hansson@arm.com     */
1298708Sandreas.hansson@arm.com    void schedSendEvent(Tick when);
1304666Sstever@eecs.umich.edu
1313403Ssaidi@eecs.umich.edu    /** Schedule a sendTiming() event to be called in the future.
1323403Ssaidi@eecs.umich.edu     * @param pkt packet to send
1334492Sstever@eecs.umich.edu     * @param absolute time (in ticks) to send packet
1343403Ssaidi@eecs.umich.edu     */
1354492Sstever@eecs.umich.edu    void schedSendTiming(PacketPtr pkt, Tick when);
1364492Sstever@eecs.umich.edu
1374492Sstever@eecs.umich.edu    /** Attempt to send the packet at the head of the deferred packet
1384492Sstever@eecs.umich.edu     * list.  Caller must guarantee that the deferred packet list is
1397823Ssteve.reinhardt@amd.com     * non-empty and that the head packet is scheduled for curTick() (or
1404492Sstever@eecs.umich.edu     * earlier).
1414492Sstever@eecs.umich.edu     */
1428856Sandreas.hansson@arm.com    virtual void sendDeferredPacket();
1438856Sandreas.hansson@arm.com
1448856Sandreas.hansson@arm.com    /**
1458856Sandreas.hansson@arm.com     * Attempt to send the packet at the front of the transmit list,
1468856Sandreas.hansson@arm.com     * and set waitingOnRetry accordingly. The packet is temporarily
1478856Sandreas.hansson@arm.com     * taken off the list, but put back at the front if not
1488856Sandreas.hansson@arm.com     * successfully sent.
1498856Sandreas.hansson@arm.com     */
1508856Sandreas.hansson@arm.com    void trySendTiming();
1518856Sandreas.hansson@arm.com
1528856Sandreas.hansson@arm.com    /**
1538856Sandreas.hansson@arm.com     * Based on the transmit list, or the provided time, schedule a
1548856Sandreas.hansson@arm.com     * send event if there are packets to send. If we are idle and
1558856Sandreas.hansson@arm.com     * asked to drain then do so.
1568856Sandreas.hansson@arm.com     *
1578856Sandreas.hansson@arm.com     * @param time an alternative time for the next send event
1588856Sandreas.hansson@arm.com     */
1598856Sandreas.hansson@arm.com    void scheduleSend(Tick time = MaxTick);
1602914Ssaidi@eecs.umich.edu
1612914Ssaidi@eecs.umich.edu    /** This function is notification that the device should attempt to send a
1622914Ssaidi@eecs.umich.edu     * packet again. */
1632914Ssaidi@eecs.umich.edu    virtual void recvRetry();
1642914Ssaidi@eecs.umich.edu
1653091Sstever@eecs.umich.edu    /** Implemented using recvAtomic(). */
1663349Sbinkertn@umich.edu    void recvFunctional(PacketPtr pkt);
1673091Sstever@eecs.umich.edu
1683091Sstever@eecs.umich.edu    /** Implemented using recvAtomic(). */
1693349Sbinkertn@umich.edu    bool recvTiming(PacketPtr pkt);
1703091Sstever@eecs.umich.edu
1713091Sstever@eecs.umich.edu    /**
1728711Sandreas.hansson@arm.com     * Simple ports are generally used as slave ports (i.e. the
1738711Sandreas.hansson@arm.com     * respond to requests) and thus do not expect to receive any
1748711Sandreas.hansson@arm.com     * range changes (as the neighbouring port has a master role and
1758711Sandreas.hansson@arm.com     * do not have any address ranges. A subclass can override the
1768711Sandreas.hansson@arm.com     * default behaviuor if needed.
1778711Sandreas.hansson@arm.com     */
1788711Sandreas.hansson@arm.com    virtual void recvRangeChange() { }
1793091Sstever@eecs.umich.edu
1803091Sstever@eecs.umich.edu
1812914Ssaidi@eecs.umich.edu  public:
1828856Sandreas.hansson@arm.com    SimpleTimingPort(const std::string &_name, MemObject *_owner,
1838856Sandreas.hansson@arm.com                     const std::string _label = "SimpleTimingPort");
1845740Snate@binkert.org    ~SimpleTimingPort();
1854490Sstever@eecs.umich.edu
1868856Sandreas.hansson@arm.com    /** Check the list of buffered packets against the supplied
1878856Sandreas.hansson@arm.com     * functional request. */
1888856Sandreas.hansson@arm.com    bool checkFunctional(PacketPtr pkt);
1898856Sandreas.hansson@arm.com
1903091Sstever@eecs.umich.edu    /** Hook for draining timing accesses from the system.  The
1913091Sstever@eecs.umich.edu     * associated SimObject's drain() functions should be implemented
1923091Sstever@eecs.umich.edu     * something like this when this class is used:
1933091Sstever@eecs.umich.edu     \code
1943091Sstever@eecs.umich.edu          PioDevice::drain(Event *de)
1953091Sstever@eecs.umich.edu          {
1963091Sstever@eecs.umich.edu              unsigned int count;
1973091Sstever@eecs.umich.edu              count = SimpleTimingPort->drain(de);
1983091Sstever@eecs.umich.edu              if (count)
1993091Sstever@eecs.umich.edu                  changeState(Draining);
2003091Sstever@eecs.umich.edu              else
2013091Sstever@eecs.umich.edu                  changeState(Drained);
2023091Sstever@eecs.umich.edu              return count;
2033091Sstever@eecs.umich.edu          }
2043091Sstever@eecs.umich.edu     \endcode
2053091Sstever@eecs.umich.edu    */
2062914Ssaidi@eecs.umich.edu    unsigned int drain(Event *de);
2072914Ssaidi@eecs.umich.edu};
2082914Ssaidi@eecs.umich.edu
2092914Ssaidi@eecs.umich.edu#endif // __MEM_TPORT_HH__
210