Device: Make changes necessary to support a coherent page walker cache.
authorMitchell Hayenga <Mitchell.Hayenga@ARM.com>
Thu, 1 Dec 2011 08:15:22 +0000 (00:15 -0800)
committerMitchell Hayenga <Mitchell.Hayenga@ARM.com>
Thu, 1 Dec 2011 08:15:22 +0000 (00:15 -0800)
Adds the flag 'recvSnoops' which enables pagewalkers using DmaPorts,
to properly configure snoops.

--HG--
extra : rebase_source : 64207bef62c3268ddff2236ee4adae873812325f

src/arch/arm/table_walker.cc
src/dev/io_device.cc
src/dev/io_device.hh

index 62b22472ba85c2d877c72571cf031a020c51121f..b2ab010c0d9373e49ba401ac1ae7dadd3546603d 100644 (file)
@@ -99,7 +99,7 @@ TableWalker::getPort(const std::string &if_name, int idx)
         System *sys = params()->sys;
         Tick minb = params()->min_backoff;
         Tick maxb = params()->max_backoff;
-        port = new DmaPort(this, sys, minb, maxb);
+        port = new DmaPort(this, sys, minb, maxb, true);
         return port;
     }
     return NULL;
index 5e2395bf9dc83b635ddfe01480ac22d529ee90ae..5c13b50912ef7348c7bef3d1a297be7290c8c731 100644 (file)
@@ -115,11 +115,13 @@ BasicPioDevice::addressRanges(AddrRangeList &range_list)
 }
 
 
-DmaPort::DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff)
+DmaPort::DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff,
+                 bool recv_snoops)
     : Port(dev->name() + "-dmaport", dev), device(dev), sys(s),
       pendingCount(0), actionInProgress(0), drainEvent(NULL),
       backoffTime(0), minBackoffDelay(min_backoff),
-      maxBackoffDelay(max_backoff), inRetry(false), backoffEvent(this)
+      maxBackoffDelay(max_backoff), inRetry(false), recvSnoops(recv_snoops),
+      snoopRangeSent(false), backoffEvent(this)
 { }
 
 bool
@@ -141,6 +143,12 @@ DmaPort::recvTiming(PacketPtr pkt)
         pkt->reinitNacked();
         queueDma(pkt, true);
     } else if (pkt->senderState) {
+        if (recvSnoops) {
+            if (pkt->isRequest()) {
+                return true;
+            }
+        }
+
         DmaReqState *state;
         backoffTime >>= 2;
 
index 812c276d638be4daf663e8e34e3aa6006d15aeb3..36787c13efd84f4be44694af2c155d465ba6b81b 100644 (file)
@@ -130,20 +130,45 @@ class DmaPort : public Port
      * 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();
@@ -152,7 +177,8 @@ class DmaPort : public Port
     EventWrapper<DmaPort, &DmaPort::sendDma> backoffEvent;
 
   public:
-    DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff);
+    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, Request::Flags flag = 0);