changed sendresult -> bool,tick,void as appropriate
authorAli Saidi <saidi@eecs.umich.edu>
Tue, 31 Jan 2006 19:20:39 +0000 (14:20 -0500)
committerAli Saidi <saidi@eecs.umich.edu>
Tue, 31 Jan 2006 19:20:39 +0000 (14:20 -0500)
first crack at io devices code
made CpuRequest that derives from Request

dev/io_device.cc:
dev/io_device.hh:
    first crack at the classes for Pio and Dma devices
dev/platform.hh:
    We are going to a system pointer to get info about the memory system
mem/bus.hh:
    changed sendresult -> bool,tick,void as appropriate
mem/port.hh:
    changed sendresult -> bool,tick,void as appropriate;
    removed the sendTiming(pkt,t) call since it is not really
    implementable in a generic fashion
mem/request.hh:
    pulled items from Request into CpuRequest

--HG--
extra : convert_revision : 6213cf2b66417fa023b80884d9e623e78f5aa891

dev/io_device.cc
dev/io_device.hh
dev/platform.hh
mem/bus.hh
mem/port.hh
mem/request.hh

index 6ab876ab86a3b00882b884f6cd70746462201507..1ed2a060aa0678ea2bf8d7d7c4cfde72dd03e72a 100644 (file)
  */
 
 #include "dev/io_device.hh"
-#include "mem/bus/base_interface.hh"
-#include "mem/bus/dma_interface.hh"
 #include "sim/builder.hh"
 
+void
+PioPort::SendEvent::process()
+{
+    if (port->sendTiming(packet) == Success)
+        return;
+
+    port->transmitList.push_back(&packet);
+}
+
 PioDevice::PioDevice(const std::string &name, Platform *p)
-    : FunctionalMemory(name), platform(p), pioInterface(NULL), pioLatency(0)
-{}
+    : SimObject(name), platform(p)
+{
+    pioPort = new PioPort(this);
+}
+
+
+bool
+PioDevice::recvTiming(Packet &pkt)
+{
+    device->recvAtomic(pkt);
+    sendTiming(pkt, pkt.responseTime-pkt.requestTime);
+    return Success;
+}
 
 PioDevice::~PioDevice()
 {
-    if (pioInterface)
+    if (pioPort)
         delete pioInterface;
 }
 
-DEFINE_SIM_OBJECT_CLASS_NAME("PioDevice", PioDevice)
+void
+DmaPort::sendDma(Packet &pkt)
+{
+    device->platform->system->memoryMode()
+    {
+        case MemAtomic:
+    }
+}
 
 DmaDevice::DmaDevice(const std::string &name, Platform *p)
-    : PioDevice(name, p), dmaInterface(NULL)
-{}
+    : PioDevice(name, p)
+{
+    dmaPort = new dmaPort(this);
+}
+
+void
+DmaPort::dmaAction(Memory::Command cmd, DmaPort port, Addr addr, int size,
+                     Event *event, uint8_t *data = NULL)
+{
+
+    assert(event);
+
+    int prevSize = 0;
+    Packet basePkt;
+    Request baseReq;
+
+    basePkt.flags = 0;
+    basePkt.coherence = NULL;
+    basePkt.senderState = NULL;
+    basePkt.src = 0;
+    basePkt.dest = 0;
+    basePkt.cmd = cmd;
+    basePkt.result = Unknown;
+    basePkt.request = NULL;
+    baseReq.nicReq = true;
+    baseReq.time = curTick;
+
+    completionEvent = event;
+
+    for (ChunkGenerator gen(addr, size, sendBlockSizeQuery()); !gen.done(); gen.next()) {
+            Packet *pkt = new Packet(basePkt);
+            Request *req = new Request(baseReq);
+            pkt->addr = gen.addr();
+            pkt->size = gen.size();
+            pkt->req = req;
+            pkt->req->paddr = pkt->addr;
+            pkt->req->size = pkt->size;
+            // Increment the data pointer on a write
+            pkt->data = data ? data + prevSize : NULL ;
+            prevSize = pkt->size;
+
+            sendDma(*pkt);
+    }
+}
+
+
+void
+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;
+
+   if (state == Timing) {
+       if (sendTiming(pkt) == Failure)
+           transmitList.push_back(&packet);
+   } else if (state == Atomic) {
+       sendAtomic(pkt);
+       completionEvent->schedule(pkt.responseTime - pkt.requestTime);
+       completionEvent == NULL;
+   } else if (state == Functional) {
+       sendFunctional(pkt);
+       // Is this correct???
+       completionEvent->schedule(pkt.responseTime - pkt.requestTime);
+       completionEvent == NULL;
+   } else
+       panic("Unknown memory command state.");
+
+}
 
 DmaDevice::~DmaDevice()
 {
@@ -53,5 +146,4 @@ DmaDevice::~DmaDevice()
         delete dmaInterface;
 }
 
-DEFINE_SIM_OBJECT_CLASS_NAME("DmaDevice", DmaDevice)
 
index bcfd062b964c98911d662c7d57352554f04f7e44..88dd32733b4412ecb6744e937a38fd5f9925f6e9 100644 (file)
 #ifndef __DEV_IO_DEVICE_HH__
 #define __DEV_IO_DEVICE_HH__
 
-#include "mem/functional/functional.hh"
+#include "base/chunk_generator.hh"
+#include "mem/port.hh"
+#include "sim/eventq.hh"
 
-class BaseInterface;
 class Bus;
-class HierParams;
 class Platform;
-template <class BusType> class DMAInterface;
+class PioDevice;
 
-class PioDevice : public FunctionalMemory
+class PioPort : public Port
 {
   protected:
+    PioDevice *device;
+
+    virtual bool recvTiming(Packet &pkt);
+
+    virtual Tick recvAtomic(Packet &pkt)
+    { return device->recvAtomic(pkt) };
+
+    virtual void recvFunctional(Packet &pkt)
+    { device->recvAtomic(pkt) };
+
+    virtual void recvAddressRangeQuery(std::list<Range<Addr> > &range_list,
+                                                 bool &owner)
+    { device->addressRanges(range_list, owner); }
+
+    void sendTiming(Packet &pkt, Tick time)
+    { new SendEvent(this, pkt, time); }
+
+    class SendEvent : public Event
+    {
+        PioPort *port;
+        Packet packet;
+
+        SendEvent(PioPort *p, Packet &pkt, Tick t)
+            : Event(&mainEventQueue), packet(pkt)
+        { schedule(curTick + t); }
+
+        virtual void process();
+
+        virtual const char *description()
+        { return "Future scheduled sendTiming event"; }
+
+        friend class PioPort;
+    }
+
+  public:
+    PioPort(PioDevice *dev)
+        : device(dev)
+    { }
+
+};
+
+class DmaPort : public Port
+{
+  protected:
+    PioDevice *device;
+    std::list<Packet*> transmitList;
+
+
+    virtual bool recvTiming(Packet &pkt)
+    { completionEvent->schedule(curTick+1); completionEvent = NULL; }
+    virtual Tick recvAtomic(Packet &pkt)
+    { panic("dma port shouldn't be used for pio access."); }
+    virtual void recvFunctional(Packet &pkt)
+    { panic("dma port shouldn't be used for pio access."); }
+
+    virtual void recvStatusChange(Status status)
+    { ; }
+
+    virtual Packet *recvRetry()
+    { return transmitList.pop_front();  }
+
+    virtual void recvAddressRangeQuery(std::list<Range<Addr> > &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;
+        Packet packet;
+
+        SendEvent(PioPort *p, Packet &pkt, Tick t)
+            : Event(&mainEventQueue), packet(pkt)
+        { schedule(curTick + t); }
+
+        virtual void process();
+
+        virtual const char *description()
+        { return "Future scheduled sendTiming event"; }
+
+        friend class PioPort;
+    }
+  public:
+    DmaPort(DmaDevice *dev)
+        : device(dev)
+    { }
+
+
+};
+
+
+class PioDevice : public SimObject
+{
+  protected:
+
     Platform *platform;
-    BaseInterface *pioInterface;
-    Tick pioLatency;
+
+    PioPort *pioPort;
+
+    virtual void addressRanges(std::list<Range<Addr> > &range_list,
+                                   bool &owner) = 0;
+
+    virtual read(Packet &pkt) = 0;
+
+    virtual write(Packet &pkt) = 0;
+
+    Tick recvAtomic(Packet &pkt)
+    { return pkt->cmd == Read ? this->read(pkt) : this->write(pkt); }
 
   public:
     PioDevice(const std::string &name, Platform *p);
+
     virtual ~PioDevice();
+
+    virtual Port *getPort(std::string if_name)
+    {
+        if (if_name == "pio")
+            return pioPort;
+        else
+            return NULL;
+    }
 };
 
 class DmaDevice : public PioDevice
 {
   protected:
-    DMAInterface<Bus> *dmaInterface;
+    DmaPort *dmaPort;
 
   public:
     DmaDevice(const std::string &name, Platform *p);
     virtual ~DmaDevice();
+
+    virtual Port *getPort(std::string if_name)
+    {
+        if (if_name == "pio")
+            return pioPort;
+        else if (if_name = "dma")
+            return dmaPort;
+        else
+            return NULL;
+    }
 };
 
+
+
+
 #endif // __DEV_IO_DEVICE_HH__
index ee9c72617e0f3a9a933cfc722541c846ff61e2e3..ff37ee71ae660299c8e114f73951a950cd48b53c 100644 (file)
@@ -41,6 +41,7 @@ class PciConfigAll;
 class IntrControl;
 class SimConsole;
 class Uart;
+class System;
 
 class Platform : public SimObject
 {
@@ -54,6 +55,9 @@ class Platform : public SimObject
     /** Pointer to the UART, set by the uart */
     Uart *uart;
 
+    /** Pointer to the system for info about the memory system. */
+    System *system;
+
   public:
     Platform(const std::string &name, IntrControl *intctrl, PciConfigAll *pci);
     virtual ~Platform();
index 80d4d9dfd9fb6a4e3266b59ec109663c5fb18bc6..8dea42e286b1f6969d0ced928c12c49f49b6666d 100644 (file)
@@ -45,15 +45,15 @@ class Bus : public MemObject
 {
     /** Function called by the port when the bus is recieving a Timing
         transaction.*/
-    SendResult recvTiming(Packet &pkt, int id);
+    bool recvTiming(Packet &pkt, int id);
 
     /** Function called by the port when the bus is recieving a Atomic
         transaction.*/
-    SendResult recvAtomic(Packet &pkt, int id);
+    Tick recvAtomic(Packet &pkt, int id);
 
     /** Function called by the port when the bus is recieving a Functional
         transaction.*/
-    SendResult recvFunctional(Packet &pkt, int id);
+    void recvFunctional(Packet &pkt, int id);
 
     /** Function called by the port when the bus is recieving a status change.*/
     void recvStatusChange(Port::Status status, int id);
@@ -79,17 +79,17 @@ class Bus : public MemObject
 
         /** When reciving a timing request from the peer port (at id),
             pass it to the bus. */
-        virtual SendResult recvTiming(Packet &pkt)
+        virtual bool recvTiming(Packet &pkt)
         { return bus->recvTiming(pkt, id); }
 
         /** When reciving a Atomic requestfrom the peer port (at id),
             pass it to the bus. */
-        virtual SendResult recvAtomic(Packet &pkt)
+        virtual Tick recvAtomic(Packet &pkt)
         { return bus->recvAtomic(pkt, id); }
 
         /** When reciving a Functional requestfrom the peer port (at id),
             pass it to the bus. */
-        virtual SendResult recvFunctional(Packet &pkt)
+        virtual void recvFunctional(Packet &pkt)
         { return bus->recvFunctional(pkt, id); }
 
         /** When reciving a status changefrom the peer port (at id),
index 03f4abac0284ece9f62927400f805fc7bc4cecfb..81150b2a30834e8e7e1307109218be16d3d10e5e 100644 (file)
@@ -87,25 +87,13 @@ class Port
   protected:
 
     /** Called to recive a timing call from the peer port. */
-    virtual SendResult recvTiming(Packet &pkt) = 0;
-
-    /** Virtual function that can be used to handle scheduling an event
-        to send the recvTiming at a given time.  This is for direct
-        connection without a interconnect.  The bus will override
-        this in it's port class because the bus does the timing.
-        This is used to insert timing when an interconnect doesn't
-        have it's own event queue.
-    */
-    virtual SendResult recvTiming(Packet &pkt, Tick t)
-    {
-        // schedule event to call recvTiming(pkt) @ tick t
-    }
+    virtual bool recvTiming(Packet &pkt) = 0;
 
     /** Called to recive a atomic call from the peer port. */
-    virtual SendResult recvAtomic(Packet &pkt) = 0;
+    virtual Tick recvAtomic(Packet &pkt) = 0;
 
     /** Called to recive a functional call from the peer port. */
-    virtual SendResult recvFunctional(Packet &pkt) = 0;
+    virtual void recvFunctional(Packet &pkt) = 0;
 
     /** Called to recieve a status change from the peer port. */
     virtual void recvStatusChange(Status status) = 0;
@@ -146,21 +134,13 @@ class Port
         case a cache has a higher priority request come in while waiting for
         the bus to arbitrate.
     */
-    SendResult sendTiming(Packet &pkt) { return peer->recvTiming(pkt); }
-
-    /** This function is identical to the sendTiming function, accept it
-        provides a time when the recvTiming should be called.  The
-        peer->recvTimimng will schedule the event, if it's device handles the
-        timing (bus) it will be overloaded by the bus type port to handle it
-        properly.
-    */
-    SendResult sendTiming(Packet &pkt, Tick t) { return peer->recvTiming(pkt, t); }
+    bool sendTiming(Packet &pkt) { return peer->recvTiming(pkt); }
 
     /** Function called by the associated device to send an atomic access,
         an access in which the data is moved and the state is updated in one
         cycle, without interleaving with other memory accesses.
     */
-    SendResult sendAtomic(Packet &pkt)
+    Tick sendAtomic(Packet &pkt)
         { return peer->recvAtomic(pkt); }
 
     /** Function called by the associated device to send a functional access,
@@ -168,7 +148,7 @@ class Port
         memory system, without affecting the current state of any block
         or moving the block.
     */
-    SendResult sendFunctional(Packet &pkt)
+    void sendFunctional(Packet &pkt)
         { return peer->recvFunctional(pkt); }
 
     /** Called by the associated device to send a status change to the device
index 331f76698dde63d1f8b4c658bc03bebca867adba..31f5b19216c380ae4c922f6d79702d3a3f1cc3d5 100644 (file)
 class Request
 {
 
-    /** The virtual address of the request. */
-    Addr vaddr;
     /** The physical address of the request. */
     Addr paddr;
 
-    /** whether this req came from the CPU or not */
-    bool nic_req;
-
-     /** The address space ID. */
-    int asid;
-    /** The related execution context. */
-    ExecContext *xc;
+    /** whether this req came from the CPU or not  **DO we need this??***/
+    bool nicReq;
 
     /** The size of the request. */
     int size;
 
+    /** The time this request was started. Used to calculate latencies. */
+    Tick time;
+
+    /** Destination address if this is a block copy. */
+    Addr copyDest;
+};
+
+class CpuRequest : public Request
+{
+    /** The virtual address of the request. */
+    Addr vaddr;
+
+    /** The address space ID. */
+    int asid;
+
     /** The return value of store conditional. */
-    uint64_t result;
+    uint64_t scResult;
 
     /** The cpu number for statistics. */
-    int cpu_num;
+    int cpuNum;
+
     /** The requesting  thread id. */
-    int  thread_num;
-    /** The time this request was started. Used to calculate latencies. */
-    Tick time;
+    int  threadNum;
 
     /** program counter of initiating access; for tracing/debugging */
     Addr pc;
-}
+};
 
 #endif // __MEM_REQUEST_HH__