From 4875b3346709d72e0be99fb6ccede65550b91f94 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 31 Jan 2006 14:20:39 -0500 Subject: 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 --- dev/io_device.cc | 110 ++++++++++++++++++++++++++++++++++++---- dev/io_device.hh | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- dev/platform.hh | 4 ++ 3 files changed, 247 insertions(+), 17 deletions(-) (limited to 'dev') 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 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_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 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_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_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 *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(); -- cgit v1.2.3