Make PioPort/DmaPort,DmaDevice/PioDevice compile.
authorAli Saidi <saidi@eecs.umich.edu>
Tue, 21 Mar 2006 20:45:31 +0000 (15:45 -0500)
committerAli Saidi <saidi@eecs.umich.edu>
Tue, 21 Mar 2006 20:45:31 +0000 (15:45 -0500)
Add another type to the PacketResult enum of Unknown
Seperate time into requsetTime and responseTime.

dev/io_device.cc:
dev/io_device.hh:
    Make PioPort/DmaPort,DmaDevice/PioDevice compile.
mem/packet.hh:
    Add another type to the PacketResult enum of Unknown (e.g. no state set yet)
mem/request.hh:
    Seperate time into requsetTime and responseTime.

--HG--
extra : convert_revision : c6394cb838013296caea6492275252b8cae2882f

dev/io_device.cc
dev/io_device.hh
mem/packet.hh
mem/request.hh

index b580c28057dbadb8f6db02dc8ff5a49757205482..268484e5761f6eee506cdda378bf10b8cb2ef9de 100644 (file)
 #include "dev/io_device.hh"
 #include "sim/builder.hh"
 
+
+PioPort::PioPort(PioDevice *dev)
+        : device(dev)
+{ }
+
+
+Tick
+PioPort::recvAtomic(Packet &pkt)
+{
+    return device->recvAtomic(pkt);
+}
+
+void
+PioPort::recvFunctional(Packet &pkt)
+{
+    device->recvAtomic(pkt);
+}
+
+void
+PioPort::getDeviceAddressRanges(AddrRangeList &range_list, bool &owner)
+{
+    device->addressRanges(range_list, owner);
+}
+
+
+Packet *
+PioPort::recvRetry()
+{
+    Packet* pkt = transmitList.front();
+    transmitList.pop_front();
+    return pkt;
+}
+
+
 void
 PioPort::SendEvent::process()
 {
-    if (port->sendTiming(packet) == Success)
+    if (port->Port::sendTiming(packet) == Success)
         return;
 
     port->transmitList.push_back(&packet);
@@ -46,37 +80,57 @@ PioDevice::PioDevice(const std::string &name, Platform *p)
 
 
 bool
-PioDevice::recvTiming(Packet &pkt)
+PioPort::recvTiming(Packet &pkt)
 {
     device->recvAtomic(pkt);
-    sendTiming(pkt, pkt.responseTime-pkt.requestTime);
+    sendTiming(pkt, pkt.req->responseTime-pkt.req->requestTime);
     return Success;
 }
 
 PioDevice::~PioDevice()
 {
     if (pioPort)
-        delete pioInterface;
+        delete pioPort;
 }
 
-void
-DmaPort::sendDma(Packet &pkt)
+
+DmaPort::DmaPort(DmaDevice *dev)
+        : device(dev)
+{ }
+
+bool
+DmaPort::recvTiming(Packet &pkt)
 {
-    device->platform->system->memoryMode()
-    {
-        case MemAtomic:
-    }
+    completionEvent->schedule(curTick+1);
+    completionEvent = NULL;
+    return Success;
 }
 
 DmaDevice::DmaDevice(const std::string &name, Platform *p)
     : PioDevice(name, p)
 {
-    dmaPort = new dmaPort(this);
+    dmaPort = new DmaPort(this);
 }
 
 void
-DmaPort::dmaAction(Memory::Command cmd, DmaPort port, Addr addr, int size,
-                     Event *event, uint8_t *data = NULL)
+DmaPort::SendEvent::process()
+{
+    if (port->Port::sendTiming(packet) == Success)
+        return;
+
+    port->transmitList.push_back(&packet);
+}
+
+Packet *
+DmaPort::recvRetry()
+{
+    Packet* pkt = transmitList.front();
+    transmitList.pop_front();
+    return pkt;
+}
+void
+DmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size,
+                     Event *event, uint8_t *data)
 {
 
     assert(event);
@@ -92,9 +146,9 @@ DmaPort::dmaAction(Memory::Command cmd, DmaPort port, Addr addr, int size,
     basePkt.dest = 0;
     basePkt.cmd = cmd;
     basePkt.result = Unknown;
-    basePkt.request = NULL;
+    basePkt.req = NULL;
     baseReq.nicReq = true;
-    baseReq.time = curTick;
+    baseReq.requestTime = curTick;
 
     completionEvent = event;
 
@@ -109,7 +163,7 @@ DmaPort::dmaAction(Memory::Command cmd, DmaPort port, Addr addr, int size,
             pkt->req->size = pkt->size;
             // Increment the data pointer on a write
             pkt->data = data ? data + prevSize : NULL ;
-            prevSize = pkt->size;
+            prevSize += pkt->size;
 
             sendDma(*pkt);
     }
@@ -122,29 +176,29 @@ DmaPort::sendDma(Packet &pkt)
    // some kind of selction between access methods
    // more work is going to have to be done to make
    // switching actually work
-   MemState state = device->platform->system->memState;
+  /* MemState state = device->platform->system->memState;
 
    if (state == Timing) {
        if (sendTiming(pkt) == Failure)
            transmitList.push_back(&packet);
-   } else if (state == Atomic) {
+   } else if (state == Atomic) {*/
        sendAtomic(pkt);
-       completionEvent->schedule(pkt.responseTime - pkt.requestTime);
-       completionEvent == NULL;
-   } else if (state == Functional) {
+       completionEvent->schedule(pkt.req->responseTime - pkt.req->requestTime);
+       completionEvent = NULL;
+/*   } else if (state == Functional) {
        sendFunctional(pkt);
        // Is this correct???
-       completionEvent->schedule(pkt.responseTime - pkt.requestTime);
+       completionEvent->schedule(pkt.req->responseTime - pkt.req->requestTime);
        completionEvent == NULL;
    } else
        panic("Unknown memory command state.");
-
+  */
 }
 
 DmaDevice::~DmaDevice()
 {
-    if (dmaInterface)
-        delete dmaInterface;
+    if (dmaPort)
+        delete dmaPort;
 }
 
 
index a79c3f20ac049344a33b59fbbe9ee916aef790a7..8e44a1c00f55dae118241a4e95890a35ce178886 100644 (file)
 #include "base/chunk_generator.hh"
 #include "mem/port.hh"
 #include "sim/eventq.hh"
+#include "sim/sim_object.hh"
 
-class Bus;
 class Platform;
 class PioDevice;
-
+class DmaDevice;
+
+/**
+ * The PioPort class is a programmed i/o port that all devices that are
+ * sensitive to an address range use. The port takes all the memory
+ * access types and roles them into one read() and write() call that the device
+ * must respond to. The device must also provide the addressRanges() function
+ * with which it returns the address ranges it is interested in. An extra
+ * sendTiming() function is implemented which takes an delay. In this way the
+ * device can immediatly call sendTiming(pkt, time) after processing a request
+ * and the request will be handled by the port even if the port bus the device
+ * connects to is blocked.
+ */
 class PioPort : public Port
 {
   protected:
+    /** The device that this port serves. */
     PioDevice *device;
 
+    /** The platform that device/port are in. This is used to select which mode
+     * we are currently operating in. */
+    Platfrom *platform;
+
+    /** A list of outgoing timing response packets that haven't been serviced
+     * yet. */
+    std::list<Packet*> transmitList;
+
+    /** The current status of the peer(bus) that we are connected to. */
+    Status peerStatus;
+
     virtual bool recvTiming(Packet &pkt);
 
-    virtual Tick recvAtomic(Packet &pkt)
-    { return device->recvAtomic(pkt) };
+    virtual Tick recvAtomic(Packet &pkt);
 
-    virtual void recvFunctional(Packet &pkt)
-    { device->recvAtomic(pkt) };
+    virtual void recvFunctional(Packet &pkt) ;
 
-    virtual void getDeviceAddressRanges(AddrRangeList &range_list, bool &owner)
-    { device->addressRanges(range_list, owner); }
+    virtual void recvStatusChange(Status status)
+    { peerStatus = status; }
 
-    void sendTiming(Packet &pkt, Tick time)
-    { new SendEvent(this, pkt, time); }
+    virtual void getDeviceAddressRanges(AddrRangeList &range_list, bool &owner);
 
+    /**
+     * 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
     {
         PioPort *port;
@@ -71,13 +97,19 @@ class PioPort : public Port
         { return "Future scheduled sendTiming event"; }
 
         friend class PioPort;
-    }
+    };
+
+    /** Schedule a sendTiming() event to be called in the future. */
+    void sendTiming(Packet &pkt, Tick time)
+    { new PioPort::SendEvent(this, pkt, time); }
+
+    /** This function pops the last element off the transmit list and sends it.*/
+    virtual Packet *recvRetry();
 
   public:
-    PioPort(PioDevice *dev)
-        : device(dev)
-    { }
+    PioPort(PioDevice *dev, Platform *p);
 
+  friend class PioPort::SendEvent;
 };
 
 class DmaPort : public Port
@@ -85,10 +117,10 @@ class DmaPort : public Port
   protected:
     PioDevice *device;
     std::list<Packet*> transmitList;
+    Event *completionEvent;
 
 
-    virtual bool recvTiming(Packet &pkt)
-    { completionEvent->schedule(curTick+1); completionEvent = NULL; }
+    virtual bool recvTiming(Packet &pkt);
     virtual Tick recvAtomic(Packet &pkt)
     { panic("dma port shouldn't be used for pio access."); }
     virtual void recvFunctional(Packet &pkt)
@@ -97,23 +129,14 @@ class DmaPort : public Port
     virtual void recvStatusChange(Status status)
     { ; }
 
-    virtual Packet *recvRetry()
-    { return transmitList.pop_front();  }
+    virtual Packet *recvRetry() ;
 
     virtual void getDeviceAddressRanges(AddrRangeList &range_list, bool &owner)
     { range_list.clear(); owner = true; }
 
-    void dmaAction(Memory::Command cmd, DmaPort port, Addr addr, int size,
-              Event *event, uint8_t *data = NULL);
-
-    void sendDma(Packet &pkt);
-
-    virtual Packet *recvRetry()
-    { return transmitList.pop_front();  }
-
     class SendEvent : public Event
     {
-        PioPort *port;
+        DmaPort *port;
         Packet packet;
 
         SendEvent(PioPort *p, Packet &pkt, Tick t)
@@ -125,33 +148,55 @@ class DmaPort : public Port
         virtual const char *description()
         { return "Future scheduled sendTiming event"; }
 
-        friend class PioPort;
-    }
+        friend class DmaPort;
+    };
+
+    void dmaAction(Command cmd, DmaPort port, Addr addr, int size,
+              Event *event, uint8_t *data = NULL);
+
+    void sendDma(Packet &pkt);
+
   public:
-    DmaPort(DmaDevice *dev)
-        : device(dev)
-    { }
+    DmaPort(DmaDevice *dev);
 
+  friend class DmaPort::SendEvent;
 
 };
 
+/**
+ * This device is the base class which all devices senstive to an address range
+ * inherit from. There are three pure virtual functions which all devices must
+ * implement addressRanges(), read(), and write(). The magic do choose which
+ * mode we are in, etc is handled by the PioPort so the device doesn't have to
+ * bother.
+ */
 
 class PioDevice : public SimObject
 {
   protected:
 
+    /** The platform we are in. This is used to decide what type of memory
+     * transaction we should perform. */
     Platform *platform;
 
+    /** The pioPort that handles the requests for us and provides us requests
+     * that it sees. */
     PioPort *pioPort;
 
     virtual void addressRanges(AddrRangeList &range_list, bool &owner) = 0;
 
-    virtual read(Packet &pkt) = 0;
+    /** As far as the devices are concerned they only accept atomic transactions
+     * which are converted to either a write or a read. */
+    Tick recvAtomic(Packet &pkt)
+    { return pkt.cmd == Read ? this->read(pkt) : this->write(pkt); }
 
-    virtual write(Packet &pkt) = 0;
+    /** Pure virtual function that the device must implement. Called when a read
+     * command is recieved by the port. */
+    virtual bool read(Packet &pkt) = 0;
 
-    Tick recvAtomic(Packet &pkt)
-    { return pkt->cmd == Read ? this->read(pkt) : this->write(pkt); }
+    /** Pure virtual function that the device must implement. Called when a
+     * write command is recieved by the port. */
+    virtual bool write(Packet &pkt) = 0;
 
   public:
     PioDevice(const std::string &name, Platform *p);
@@ -165,6 +210,8 @@ class PioDevice : public SimObject
         else
             return NULL;
     }
+    friend class PioPort;
+
 };
 
 class DmaDevice : public PioDevice
@@ -180,14 +227,14 @@ class DmaDevice : public PioDevice
     {
         if (if_name == "pio")
             return pioPort;
-        else if (if_name = "dma")
+        else if (if_name == "dma")
             return dmaPort;
         else
             return NULL;
     }
-};
-
 
+    friend class DmaPort;
+};
 
 
 #endif // __DEV_IO_DEVICE_HH__
index 260fc60f715c4f93f5547e3fbab05f141b30f0d6..57702dc97b2e4caa705de1380b7c457c20b6540e 100644 (file)
@@ -54,7 +54,8 @@ enum Command
 enum PacketResult
 {
     Success,
-    BadAddress
+    BadAddress,
+    Unknown
 };
 
 class SenderState{};
index 5e227574150a7eaeef20cacfc50d4e0060946474..1c65057a0b8befbc51354fd597561c656cc6364f 100644 (file)
@@ -73,7 +73,11 @@ class Request
     int size;
 
     /** The time this request was started. Used to calculate latencies. */
-    Tick time;
+    Tick requestTime;
+
+    /** The time this request was responded to in the memory hierachy. Used by
+     * deviced to inform ports how long a request should be delayed. */
+    Tick responseTime;
 
     /** Destination address if this is a block copy. */
     Addr copyDest;