summaryrefslogtreecommitdiff
path: root/dev
diff options
context:
space:
mode:
authorAli Saidi <saidi@eecs.umich.edu>2006-01-31 14:20:39 -0500
committerAli Saidi <saidi@eecs.umich.edu>2006-01-31 14:20:39 -0500
commit4875b3346709d72e0be99fb6ccede65550b91f94 (patch)
treebd71ec62c7a5a74e40ca226a2ac5b4f26c71f81d /dev
parenta1033448ead67ea2819d67609c0390aefc865b0f (diff)
downloadgem5-4875b3346709d72e0be99fb6ccede65550b91f94.tar.xz
changed sendresult -> bool,tick,void as appropriate
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
Diffstat (limited to 'dev')
-rw-r--r--dev/io_device.cc110
-rw-r--r--dev/io_device.hh150
-rw-r--r--dev/platform.hh4
3 files changed, 247 insertions, 17 deletions
diff --git a/dev/io_device.cc b/dev/io_device.cc
index 6ab876ab8..1ed2a060a 100644
--- a/dev/io_device.cc
+++ b/dev/io_device.cc
@@ -27,25 +27,118 @@
*/
#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)
diff --git a/dev/io_device.hh b/dev/io_device.hh
index bcfd062b9..88dd32733 100644
--- a/dev/io_device.hh
+++ b/dev/io_device.hh
@@ -29,34 +29,168 @@
#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__
diff --git a/dev/platform.hh b/dev/platform.hh
index ee9c72617..ff37ee71a 100644
--- a/dev/platform.hh
+++ b/dev/platform.hh
@@ -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();