X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmem%2Ftport.hh;h=eaf5acd5d6afeefb0a181eac9cb77b90b92ba417;hb=ea8b347dc5d375572d8d19770024ec8be5fd5017;hp=df6d481962cca3e32c25bdaa43ca86c9467dae74;hpb=4ed184eadefb16627f2807cb3dc7886bb1b920d1;p=gem5.git diff --git a/src/mem/tport.hh b/src/mem/tport.hh index df6d48196..eaf5acd5d 100644 --- a/src/mem/tport.hh +++ b/src/mem/tport.hh @@ -37,11 +37,12 @@ * Declaration of SimpleTimingPort. */ -#include "mem/port.hh" -#include "sim/eventq.hh" #include #include +#include "mem/port.hh" +#include "sim/eventq.hh" + /** * A simple port for interfacing objects that basically have only * functional memory behavior (e.g. I/O devices) to the memory system. @@ -58,68 +59,98 @@ class SimpleTimingPort : public Port { protected: + /** A deferred packet, buffered to transmit later. */ + class DeferredPacket { + public: + Tick tick; ///< The tick when the packet is ready to transmit + PacketPtr pkt; ///< Pointer to the packet to transmit + DeferredPacket(Tick t, PacketPtr p) + : tick(t), pkt(p) + {} + }; + + typedef std::list DeferredPacketList; + typedef std::list::iterator DeferredPacketIterator; + /** A list of outgoing timing response packets that haven't been * serviced yet. */ - std::list transmitList; + DeferredPacketList transmitList; + + /** This function attempts to send deferred packets. Scheduled to + * be called in the future via SendEvent. */ + void processSendEvent(); /** * This class is used to implemented sendTiming() with a delay. When - * a delay is requested a new event is created. When the event time - * expires it attempts to send the packet. If it cannot, the packet - * is pushed onto the transmit list to be sent when recvRetry() is - * called. */ - class SendEvent : public Event - { - SimpleTimingPort *port; - Packet *packet; + * a delay is requested a the event is scheduled if it isn't already. + * When the event time expires it attempts to send the packet. + * If it cannot, the packet sent when recvRetry() is called. + **/ + Event *sendEvent; - public: - SendEvent(SimpleTimingPort *p, Packet *pkt, Tick t) - : Event(&mainEventQueue), port(p), packet(pkt) - { setFlags(AutoDelete); schedule(curTick + t); } + /** If we need to drain, keep the drain event around until we're done + * here.*/ + Event *drainEvent; - virtual void process(); + /** Remember whether we're awaiting a retry from the bus. */ + bool waitingOnRetry; - virtual const char *description() - { return "Future scheduled sendTiming event"; } - }; + /** Check the list of buffered packets against the supplied + * functional request. */ + bool checkFunctional(PacketPtr funcPkt); + /** Check whether we have a packet ready to go on the transmit list. */ + bool deferredPacketReady() + { return !transmitList.empty() && transmitList.front().tick <= curTick(); } - /** Number of timing requests that are emulating the device timing before - * attempting to end up on the bus. + Tick deferredPacketReadyTime() + { return transmitList.empty() ? MaxTick : transmitList.front().tick; } + + /** + * Schedule a send even if not already waiting for a retry. If the + * requested time is before an already scheduled send event it + * will be rescheduled. + * + * @param when */ - int outTiming; + void schedSendEvent(Tick when); - /** If we need to drain, keep the drain event around until we're done - * here.*/ - Event *drainEvent; + /** Schedule a sendTiming() event to be called in the future. + * @param pkt packet to send + * @param absolute time (in ticks) to send packet + */ + void schedSendTiming(PacketPtr pkt, Tick when); - /** Schedule a sendTiming() event to be called in the future. */ - void sendTimingLater(Packet *pkt, Tick time) - { outTiming++; new SendEvent(this, pkt, time); } + /** Attempt to send the packet at the head of the deferred packet + * list. Caller must guarantee that the deferred packet list is + * non-empty and that the head packet is scheduled for curTick() (or + * earlier). + */ + void sendDeferredPacket(); /** This function is notification that the device should attempt to send a * packet again. */ virtual void recvRetry(); /** Implemented using recvAtomic(). */ - void recvFunctional(Packet *pkt); + void recvFunctional(PacketPtr pkt); /** Implemented using recvAtomic(). */ - bool recvTiming(Packet *pkt); + bool recvTiming(PacketPtr pkt); /** - * Simple ports generally don't care about any status - * changes... can always override this in cases where that's not - * true. */ - virtual void recvStatusChange(Status status) { } + * Simple ports are generally used as slave ports (i.e. the + * respond to requests) and thus do not expect to receive any + * range changes (as the neighbouring port has a master role and + * do not have any address ranges. A subclass can override the + * default behaviuor if needed. + */ + virtual void recvRangeChange() { } public: - - SimpleTimingPort(std::string pname) - : Port(pname), outTiming(0), drainEvent(NULL) - {} + SimpleTimingPort(std::string pname, MemObject *_owner); + ~SimpleTimingPort(); /** Hook for draining timing accesses from the system. The * associated SimObject's drain() functions should be implemented