/** Amount to delay completion of dma by */
Tick delay;
+
DmaReqState(Event *ce, Port *p, Addr tb, Tick _delay)
: completionEvent(ce), outPort(p), totBytes(tb), numBytes(0),
delay(_delay)
{}
};
- DmaDevice *device;
+ MemObject *device;
std::list<PacketPtr> transmitList;
/** The system that device/port are in. This is used to select which mode
* recived, decreases as responses are recived. */
Tick backoffTime;
+ /** Minimum time that device should back off for after failed sendTiming */
+ Tick minBackoffDelay;
+
+ /** Maximum time that device should back off for after failed sendTiming */
+ Tick maxBackoffDelay;
+
/** If the port is currently waiting for a retry before it can send whatever
* it is that it's sending. */
bool inRetry;
+ /** Port accesses a cache which requires snooping */
+ bool recvSnoops;
+
+ /** Records snoop response so we only reply once to a status change */
+ bool snoopRangeSent;
+
virtual bool recvTiming(PacketPtr pkt);
virtual Tick recvAtomic(PacketPtr pkt)
- { panic("dma port shouldn't be used for pio access."); M5_DUMMY_RETURN }
+ {
+ if (recvSnoops) return 0;
+
+ panic("dma port shouldn't be used for pio access."); M5_DUMMY_RETURN
+ }
virtual void recvFunctional(PacketPtr pkt)
- { panic("dma port shouldn't be used for pio access."); }
+ {
+ if (recvSnoops) return;
+
+ panic("dma port shouldn't be used for pio access.");
+ }
virtual void recvStatusChange(Status status)
- { ; }
+ {
+ if (recvSnoops) {
+ if (status == RangeChange) {
+ if (!snoopRangeSent) {
+ snoopRangeSent = true;
+ sendStatusChange(Port::RangeChange);
+ }
+ return;
+ }
+ panic("Unexpected recvStatusChange\n");
+ }
+ }
virtual void recvRetry() ;
virtual void getDeviceAddressRanges(AddrRangeList &resp,
bool &snoop)
- { resp.clear(); snoop = false; }
+ { resp.clear(); snoop = recvSnoops; }
void queueDma(PacketPtr pkt, bool front = false);
void sendDma();
EventWrapper<DmaPort, &DmaPort::sendDma> backoffEvent;
public:
- DmaPort(DmaDevice *dev, System *s);
+ DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff,
+ bool recv_snoops = false);
void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
- uint8_t *data, Tick delay);
+ uint8_t *data, Tick delay, Request::Flags flag = 0);
bool dmaPending() { return pendingCount > 0; }
- int cacheBlockSize() { return peerBlockSize(); }
+ unsigned cacheBlockSize() const { return peerBlockSize(); }
unsigned int drain(Event *de);
};
virtual unsigned int drain(Event *de);
- virtual Port *getPort(const std::string &if_name, int idx = -1)
- {
- if (if_name == "pio") {
- if (pioPort != NULL)
- fatal("%s: pio port already connected to %s",
- name(), pioPort->getPeer()->name());
- pioPort = new PioPort(this, sys);
- return pioPort;
- } else
- return NULL;
- }
+ virtual Port *getPort(const std::string &if_name, int idx = -1);
+
friend class PioPort;
};
{
protected:
DmaPort *dmaPort;
- Tick minBackoffDelay;
- Tick maxBackoffDelay;
public:
typedef DmaDeviceParams Params;
virtual unsigned int drain(Event *de);
- int cacheBlockSize() { return dmaPort->cacheBlockSize(); }
+ unsigned cacheBlockSize() const { return dmaPort->cacheBlockSize(); }
- virtual Port *getPort(const std::string &if_name, int idx = -1)
- {
- if (if_name == "pio") {
- if (pioPort != NULL)
- fatal("%s: pio port already connected to %s",
- name(), pioPort->getPeer()->name());
- pioPort = new PioPort(this, sys);
- return pioPort;
- } else if (if_name == "dma") {
- if (dmaPort != NULL)
- fatal("%s: dma port already connected to %s",
- name(), pioPort->getPeer()->name());
- dmaPort = new DmaPort(this, sys);
- return dmaPort;
- } else
- return NULL;
- }
+ virtual Port *getPort(const std::string &if_name, int idx = -1);
friend class DmaPort;
};