summaryrefslogtreecommitdiff
path: root/dev/io_device.hh
diff options
context:
space:
mode:
Diffstat (limited to 'dev/io_device.hh')
-rw-r--r--dev/io_device.hh147
1 files changed, 139 insertions, 8 deletions
diff --git a/dev/io_device.hh b/dev/io_device.hh
index bcfd062b9..a79c3f20a 100644
--- a/dev/io_device.hh
+++ b/dev/io_device.hh
@@ -29,34 +29,165 @@
#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 getDeviceAddressRanges(AddrRangeList &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 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;
+ 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(AddrRangeList &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__